RabbitMQ routingKey for Java【入门教程 4】

routingKey :消息路由

绑定关系
        在之前的例子中也使用了类似的方式:

channel.queueBind(queueName, EXCHANGE_NAME, "");

        绑定是交换器和队列之间的一种关系,用户微博,微信的例子可以简单的理解为关注,就是队列(某屌丝)对交换器(女神)非常感兴趣,关注了她,以后女神发的每条微博,屌丝都能看到。

        绑定可以使用routingkey这个参数,是为了避免所有的消息都使用同一个路由线索带来的麻烦。为了区分路由规则,我们创建创建一个唯一的路由线索。


channel.queueBind(queueName, EXCHANGE_NAME, "black");

        绑定关系中使用的路由关键字【routingkey】是否有效取决于交换器的类型。如果交换器是分发【fanout】类型,就会忽略路由关键字【routingkey】的作用。如果交换器的分发为【direct】 关键字routingkey才会起作用

 

直连类型交换器
        上一章的例子是通过分发【fanout】类型的交换器【logs】广播日志信息,现在我们将日志分debug、info、warn、error这几种基本的级别,实际在生产环境中,避免磁盘空间浪费,应用只会将error级别的日志打印出来。而分发【fanout】类型的交换器会将所有基本的日志都发送出来,如果我们想只接收某一级别的日志信息,就需要使用直连【direct】类型的交换器了, 下面的图中,队列1通过ERROR这个routingkey绑定到E交换器,队列2通过WARN和INFO绑定到E交换器,E交换器的类型是直连【direct】的,如果生产者【P】发出ERROR的日志,只会有队列1会收到,如果生产者【P】发出INFO和WARN的日志,只有队列2会收到,如果生产者【P】发出DEBUG级别的日志,队列1和队列2都会忽略它。(理解这个图  我们的代码就容易理解)

 

 

我们还是以消息为例:先看看我们代码所走的流程图

 上图可以看出 smsConsumer只接受sms信息 而emailConsumer接受sms和email信息,那么怎么决定接受什么类型的信息呢?

所以这里routingKey起到关键性作用

直接上代码 项目结构:

生产者:

package wxtest.rabbitMq.routing;

import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import wxtest.rabbitMq.ConnectionUtil;

import java.io.IOException;
import java.util.concurrent.TimeoutException;

public class msgProduce {

    private static String EXCHAGE_NAME = "exchange_direct";//设置一个交换机
    private static String ROUTINGKEY_SMS = "routingkey_sms";//设置一个路由
    private static String ROUTINGKEY_email = "routingkey_emai";//设置一个路由

    public static void main(String[] args) throws IOException, TimeoutException {
        Connection connection = ConnectionUtil.getConnection();
        Channel channel = connection.createChannel();
        channel.exchangeDeclare(EXCHAGE_NAME, "direct");//fanout属于主题订阅方式 设置路由无效  direct和路由配合使用

        //分发消息
        for (int i = 0; i < 10; i++) {
            String message = "我是交换机的消息 " + i;
            //basicPublish发布的第一个参数属于交换机  第二个参数属于按照routingKey方式发放 分别向email和sms发放信息
            //一部分消息作为email发送 一部分消息作为sms发送 我们可以看看消费者的消费情况
            if (i % 2 == 0) {
                channel.basicPublish(EXCHAGE_NAME, ROUTINGKEY_email, null, message.getBytes());
            } else {
                channel.basicPublish(EXCHAGE_NAME, ROUTINGKEY_SMS, null, message.getBytes());
            }
            System.out.println(" [x] Sent '" + message + "'");
        }
        channel.close();
        connection.close();
    }
}

emailConsumer消费者: 注意观察路由情况

package wxtest.rabbitMq.routing;

import com.rabbitmq.client.*;
import wxtest.rabbitMq.ConnectionUtil;

import java.io.IOException;
import java.util.concurrent.TimeoutException;

public class emailConsumer {
    private static String exchage_name = "exchange_direct";//设置一个交换机
    private static String ROUTINGKEY_SMS = "routingkey_sms";//设置一个路由
    private static String ROUTINGKEY_email = "routingkey_emai";//设置一个路由


    public static void main(String[] args) throws IOException, TimeoutException {
        Connection connection = ConnectionUtil.getConnection();
        Channel channel = connection.createChannel();
        channel.exchangeDeclare(exchage_name, "direct");//绑定交换机
        String queueName = channel.queueDeclare().getQueue();
        channel.queueBind(queueName, exchage_name, ROUTINGKEY_SMS);//绑定交换机所对应的队列  设置路由
        channel.queueBind(queueName, exchage_name, ROUTINGKEY_email);//绑定交换机所对应的队列 设置路由
        System.out.println(" emailConsumer Waiting for messages. To exit press CTRL+C");
        DefaultConsumer 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(" emailConsumer [x] Received '" + msg + "'");
                channel.basicAck(envelope.getDeliveryTag(), false);
            }
        };
        channel.basicConsume(queueName, true, consumer);
    }
}

smsConsumer消费者: 注意观察路由情况

package wxtest.rabbitMq.routing;

import com.rabbitmq.client.*;
import wxtest.rabbitMq.ConnectionUtil;

import java.io.IOException;
import java.util.concurrent.TimeoutException;

public class smsComsumer {
    private static String exchage_name = "exchange_direct";//设置一个交换机
    private static String ROUTINGKEY_SMS = "routingkey_sms";//设置一个交换机

    public static void main(String[] args) throws IOException, TimeoutException {
        Connection connection = ConnectionUtil.getConnection();
        Channel channel = connection.createChannel();
        channel.exchangeDeclare(exchage_name, "direct");//绑定交换机
        String queueName = channel.queueDeclare().getQueue();
        channel.queueBind(queueName, exchage_name, ROUTINGKEY_SMS);//绑定交换机所对应的队列 只接受sms信息
        System.out.println(" smsComsumer Waiting for messages. To exit press CTRL+C");
        DefaultConsumer 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(" smsComsumer [x] Received '" + msg + "'");
                channel.basicAck(envelope.getDeliveryTag(), false);
            }
        };
        channel.basicConsume(queueName, true, consumer);
    }
}

输出结果如下:

 

上述代码将交换机 路由的设置都已经在代码中得以体现 ,仔细敲一遍  感受更深刻哦!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值