RabbitMQ學習系列(五):routing路由模式和Topic主題模式

(一)routing路由模式

在前面一篇博客中講到了exchange的類型,其中direct類型的exchange就是用於routing路由模式。direct類型的交換機是指:交換機和隊列綁定時會設置路由鍵(routingkey),當消息從生產者發送給交換機時也會發送一個路由鍵。只有當這兩個路由鍵相同時,交換機纔會把消息發送給隊列。

如上圖所示,當生產者發送消息的路由鍵爲error時,兩個隊列均可以收到消息;當生產者發送消息的路由鍵爲info或warning時,只有第二個隊列可收到消息。

(二)路由模式實踐

2.1 工具類

工具類和之前都一樣,不做介紹了

public class ConnectionUtil {
    public static Connection getConnection() throws IOException, TimeoutException {
        //定義一個連接工廠
        ConnectionFactory factory=new ConnectionFactory();
        //設置服務地址
        factory.setHost("127.0.0.1");
        //設置AMQP端口
        factory.setPort(5672);
        //設置VHOSTS
        factory.setVirtualHost("/vhosts_sdxb");
        //設置用戶名
        factory.setUsername("user_sdxb");
        factory.setPassword("123456");
        return factory.newConnection();
    }
}

2.2 生產者

與前面幾種模式不同的地方已經通過註解標出,其中交換機類型選擇成direct,並且按需要設置路由鍵

public class Sent {
    private static final String EXCHANGENAME="routing_exchange";
    public static void main(String[] args) throws IOException, TimeoutException {
        Connection connection = ConnectionUtil.getConnection();
        Channel channel = connection.createChannel();
        //交換機類型選擇direct
        channel.exchangeDeclare(EXCHANGENAME,"direct");
        String msg="hello world";
        //設置路由鍵(routingkey)
        String routingkey="error";
        channel.basicPublish(EXCHANGENAME,routingkey,null,msg.getBytes());
        channel.close();
        connection.close();
    }
}

2.3 消費者一

在隊列綁定時設置隊列的路由鍵

public class Receive1 {
    private static final String QUEUENAME="routing_queue1";
    private static final String EXCHANGENAME="routing_exchange";
    public static void main(String[] args) throws IOException, TimeoutException {
        Connection connection = ConnectionUtil.getConnection();
        final Channel channel = connection.createChannel();
        channel.queueDeclare(QUEUENAME, false, false, false, null);
        //在隊列綁定時設置路由鍵
        channel.queueBind(QUEUENAME, EXCHANGENAME, "error");
        Consumer consumer = new DefaultConsumer(channel) {
            @Override
            public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
                String msg = new String(body, "utf-8");
                System.out.println("receive:" + msg);
            }
        };
        //監聽隊列
        channel.basicConsume(QUEUENAME, true, consumer);
    }
}

2.4 消費者二

在第二個消費者的隊列中設置多個路由鍵

public class Receive2 {
    private static final String QUEUENAME="routing_queue2";
    private static final String EXCHANGENAME="routing_exchange";
    public static void main(String[] args) throws IOException, TimeoutException {
        Connection connection = ConnectionUtil.getConnection();
        final Channel channel = connection.createChannel();
        channel.queueDeclare(QUEUENAME, false, false, false, null);
        //在隊列綁定時設置多個路由鍵
        channel.queueBind(QUEUENAME, EXCHANGENAME, "error");
        channel.queueBind(QUEUENAME, EXCHANGENAME, "info");
        channel.queueBind(QUEUENAME, EXCHANGENAME, "warning");
        Consumer consumer = new DefaultConsumer(channel) {
            @Override
            public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
                String msg = new String(body, "utf-8");
                System.out.println("receive:" + msg);
            }
        };
        //監聽隊列
        channel.basicConsume(QUEUENAME, true, consumer);
    }
}

2.5運行結果

當路由鍵爲error時,兩個消費者均輸出消息。當路由鍵爲info或warning時,只有第二個消費者輸出消息。

(三)Topic主題模式

Topic主題模式和routing路由模式類似,只不過這裏的交換機使用的是topic類型,topic類型的交換機和direct的不同就在於topic可以匹配通配符。*代表匹配一個元素,#代表匹配一個或多個元素

以上圖爲例,Q1隊列的路由鍵爲*.orange.*,Q2隊列的路由鍵爲*.*.rabbitlazy.#,當消息的路由鍵爲quick.orange.rabbit時,兩個隊列均能收到,當消息的路由鍵爲lazy.orange.male.rabbit時,只有Q2隊列能收到。

(四)主題模式實踐

在routing路由模式的代碼基礎上修改

4.1 生產者

//交換機類型選擇direct
channel.exchangeDeclare(EXCHANGENAME,"topic");
//設置路由鍵(routingkey)
String routingkey="lazy.brown.fox";

4.2 消費者一

channel.queueBind(QUEUENAME, EXCHANGENAME, "*.orange.*");

4.3 消費者二

channel.queueBind(QUEUENAME, EXCHANGENAME, "*.*.rabbit");
channel.queueBind(QUEUENAME, EXCHANGENAME, "lazy.#");

修改以上幾處地方就實現了上述topic模型

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章