RabbitMQ --- 路由Routing

结合上一篇文章接着往下写。

路由 routing

日志系统,将error的日志信息发送到一个队列,进行保存到logs文件中。将error info warning的日志信息发送到另一个队列,进行控制台打印操作。这里可是通过 绑定秘钥 路由秘钥参数来配置。

再上一个技术发布订阅,添加一点限制,是消费者只能订阅一部分消息。

例如,我们只能将关键错误消息定向到日志文件,同时仍然能够在控制台上打印所有日志消息

绑定可以采用routingKey参数,为了避免与basic_Publish 参数混淆,将其称之为绑定秘钥
channel.queueBind(queueName, exchangeName, "severityError");
绑定秘钥的含义取决于交换机的类型,上一篇中使用的fanout类型交换机忽略了绑定秘钥。

直接交换机 direct

Exchange fanout(扇出交换机),它没有给我们太大灵活性,它只能进行无意识的广播。
Exchange direct(直接交换机),直接交换背后的路由算法很简单,消息进入队列,其绑定秘钥和路由秘钥完全匹配(匹配不上的消息被丢弃)

多个绑定

使用相同的绑定秘钥绑定多个队列是完全合法的。

在这里插入图片描述

贴代码

生产者代码
public class Routingsend {
    final static String EXCHANGE_NAME = "direct_logs";
    static ConnectionUtil connUtil = new ConnectionUtil();
    public static void main(String[] args) throws Exception {
        Connection conn = connUtil.getConn();
        Channel channel = conn.createChannel();
        //声明交换机 指定direct直连类型
        channel.exchangeDeclare(EXCHANGE_NAME, "direct");
        String message = "Exchange type direct, test routing";
        //定义路由秘钥 error
        String severity = "error";
        //发布到交换机
        channel.basicPublish(EXCHANGE_NAME, severity, null, message.getBytes());
        System.out.println("绑定秘钥:"+severity+", 消息:"+message);
		//定义路由秘钥 info
        String severity2 = "info";
        //发布到交换机
        channel.basicPublish(EXCHANGE_NAME, severity2, null, message.getBytes());
        System.out.println("绑定秘钥:"+severity2+", 消息:"+message);
		//定义路由秘钥 warning
        String severity3 = "warning";
        //发布到交换机
        channel.basicPublish(EXCHANGE_NAME, severity3, null, message.getBytes());
        System.out.println("绑定秘钥:"+severity3+", 消息:"+message);
        // 关闭通道和连接
        channel.close();
        conn.close();

    }

}

消费者1 代码,用来将error的日志信息发送到一个队列,进行保存到logs文件中
public class RoutingReceiver1 {
    final static String EXCHANG_NAME = "direct_logs";
    static ConnectionUtil connUtil = new ConnectionUtil();
    public static void main(String[] args)  throws Exception {
        Connection conn = connUtil.getConn();
        Channel channel = conn.createChannel();
        //声明交换机 指定direct直连类型
        channel.exchangeDeclare(EXCHANG_NAME, "direct");
        //获取临时队列名称
        String queneName = channel.queueDeclare().getQueue();
        //绑定队列 error为绑定秘钥,其绑定秘钥和路由秘钥完全匹
        channel.queueBind(queneName, EXCHANG_NAME, "error");
        DeliverCallback deliverCallback = (consumerTag, delivery) -> {
            String message = new String(delivery.getBody(), "UTF-8");
            System.out.println("路由秘钥:"+delivery.getEnvelope().getRoutingKey()+",接受消息: '" + message + "'");
        };
        channel.basicConsume(queneName, true, deliverCallback, consumerTag -> {});
    }
}

消费者2 代码,将error info warning的日志信息发送到另一个队列,进行控制台打印操作
public class RoutingReceiver2 {
    final static String EXCHANG_NAME = "direct_logs";
    static ConnectionUtil connUtil = new ConnectionUtil();
    public static void main(String[] args)  throws Exception {
        Connection conn = connUtil.getConn();
        Channel channel = conn.createChannel();
        //声明交换机 指定direct直连类型
        channel.exchangeDeclare(EXCHANG_NAME, "direct");
        //获取临时队列名称
        String queneName = channel.queueDeclare().getQueue();
        //绑定队列 绑定多个
        channel.queueBind(queneName, EXCHANG_NAME, "info");
        //使用相同的绑定秘钥绑定多个队列是完全合法的,上面也用这个绑定秘钥
        channel.queueBind(queneName, EXCHANG_NAME, "error");
        channel.queueBind(queneName, EXCHANG_NAME, "warning");
        DeliverCallback deliverCallback = (consumerTag, delivery) -> {
            String message = new String(delivery.getBody(), "UTF-8");
            System.out.println("路由秘钥:"+delivery.getEnvelope().getRoutingKey()+",接受消息: '" + message + "'");
        };
        channel.basicConsume(queneName, true, deliverCallback, consumerTag -> {});
    }
}

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