RabbitMQ-topic

Topic

在之前的一篇教程中,我们改进了日志系统。我们使用direct直接广播,而不是使用fanout,从而获得了选择性接收日志的可能性。

虽然使用direct exchange改进了我们的系统,但它任然有局限性–它不能基于多个标准进行路由。

Topic exchange

消息发送到topic exchange不能是一个随意的routing-key。它必须是一个由.分割单纯列表。

例如stock.usd.nysenyse.vmwquick.orange.rabbit等。routing-key可以有尽可能多,但是最多255字节。

绑定键必须采用相同的形式。topic exchangedirect exchange类似-使用特定routig key发送的消息会被传递到匹配binding key的队列里面。但是,对于routing key有两个特殊情况

  • * (star)可以替代一个单词
  • #(hash) 可以代替0个或多个单词

Topic exchange

Topic exchange是非常厉害的并且可以表现和其他exchange一样的

当一个队列是用#绑定,那么就会接受到所有信息,不管routing-key是什么,就像fanout

当绑定中不使用*#等特殊字符,topic exchange就会像direct exchange

Sender.java

public class Send {
    private final static String EXCHANGE_NAME = "test_exchange_topic";
    public static void main(String[] args) throws IOException, TimeoutException {
        // 创建连接
        Connection connection = ConnectionUtils.getConnection();
        Channel channel = connection.createChannel();

        //声明exchange
        channel.exchangeDeclare(EXCHANGE_NAME, BuiltinExchangeType.TOPIC);

        // 消息内容
        String msg = "hello world!";
        channel.basicPublish(EXCHANGE_NAME,"routekey1.1",null,msg.getBytes());
        channel.close();
        connection.close();

    }

}

Rece1.java

public class Rece1 {
    private final static String EXCHANGE_NAME = "test_exchange_topic";

    public static void main(String[] args) throws IOException, TimeoutException {
        Connection connection = ConnectionUtils.getConnection();
        Channel channel = connection.createChannel();

        //
        String queueName = channel.queueDeclare().getQueue();
//        // 声明队列
//        channel.queueDeclare(queueName,false,false,false,null);


        //绑定队列到交换机上
        channel.queueBind(queueName,EXCHANGE_NAME,"routekey.*");

        //同一时刻服务器只发送一条消息
        channel.basicQos(1);

        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("rece1 :" + msg);
                try {
                    TimeUnit.SECONDS.sleep(2);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }finally {
                    System.out.println("rece1 done");
                    channel.basicAck(envelope.getDeliveryTag(),false);
                }
            }
        };
        channel.basicConsume(queueName,false,consumer);
    }
}

Rece2.java

public class Rece2 {
    private final static String QUEUE_NAME = "test_queue_topic_work_2";
    private final static String EXCHANGE_NAME = "test_exchange_topic";

    public static void main(String[] args) throws IOException, TimeoutException {
        Connection connection = ConnectionUtils.getConnection();
        Channel channel = connection.createChannel();

        // 声明队列
        channel.queueDeclare(QUEUE_NAME,false,false,false,null);

        //绑定队列到交换机上
        channel.queueBind(QUEUE_NAME,EXCHANGE_NAME,"*.*");

        //同一时刻服务器只发送一条消息
        channel.basicQos(1);

        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("rece1 :" + msg);
                try {
                    TimeUnit.SECONDS.sleep(2);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }finally {
                    System.out.println("rece1 done");
                    channel.basicAck(envelope.getDeliveryTag(),false);
                }
            }
        };
        channel.basicConsume(QUEUE_NAME,false,consumer);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值