rabbitmq中routingkey的作用说明

网友投稿 832 2023-01-12

rabbitmq中routingkey的作用说明

rabbitmq中routingkey的作用说明

对于消息发布者而言它只负责把消息发布出去,甚至它也不知道消息是发到哪个queue,消息通过exchange到达queue,exchange的职责非常简单,就是一边接收发布者的消息一边把这些消息推到queue中。

而exchange是怎么知道消息应该推到哪个queue呢,这就要通过绑定queue与exchange时的routingkey了,通过代码进行绑定并且指定routingkey,下面有一张关系图,p(发布者) —> x(exchange) bindding(绑定关系也就是我们的routingkey) 红色代表着queue

我们来看代码:

在消息的生产者端:

@Component

public class RabbitOrderSender {

//自动注入RabbitTemplate模板类

@Autowired

private RabbitTemplate rabbitTemplate;

@Autowired

private BrokerMessageLogMapper brokerMessageLogMapper;

//回调函数: confirm确认

final RabbitTemplate.ConfirmCallback confirmCallback = new RabbitTemplate.ConfirmCallback() {

@Override

public void confirm(CorrelationData correlationData, boolean ack, String cause) {

System.err.println("correlationData: " + correlationData);

String messageId = correlationData.getId();

if(ack){

//如果confirm返回成功 则进行更新

brokerMessageLogMapper.changeBrokerMessageLogStatus(messageId, Constants.ORDER_SEND_SUCCESS, new Date());

} else {

//失败则进行具体的后续操作:重试 或者补偿等手段

System.err.println("异常处理...");

}

}

};

//发送消息方法调用: 构建自定义对象消息

public void sendOrder(Order order) throws Exception {

// 通过实现 ConfirmCallback 接口,消息发送到 Broker 后触发回调,确认消息是否到达 Broker 服务器,也就是只确认是否正确到达 Exchange 中

rabbitTemplate.setConfirmCallback(confirmCallback);

//消息唯一ID

CorrelationData correlationData = new CorrelationData(order.getMessageId());

rabbitTemplate.convertAndSend("order-exchange", "order.ABC", order, correlationData);

}

}

利用rabbitTemplate(import org.springframework.amqp.rabbit.core.RabbitTemplate;需要在pom.xml中导入amqp的依赖)的convertAndSend方法就可以发送,这里order-exchange为交换机exchange,order.ABC为routingKey,并没有指定对应消息需要发往哪个队列,还有指定消息回调。

在消息的消费者端:

@Component

public class OrderReceiver {

//配置监听的哪一个队列,同时在没有queue和exchange的情况下会去创建并建立绑定关系

@RabbitListener(bindings = @QueueBinding(

value = @Queue(value = "order-queue",durable = "true"),

exchange = @Exchange(name="order-exchange",durable = "true",type = "topic"),

key = "order.*"

)

)

@RabbitHandler//如果有消息过来,在消费的时候调用这个方法

public void onOrderMessage(@Payload Order order, @Headers Map headers, Channel channel) throws IOException {

//消费者操作

System.out.println("---------收到消息,开始消费---------");

System.out.println("订单ID:"+order.getId());

/**

* Delivery Tag 用来标识信道中投递的消息。RabbitMQ 推送消息给 Consumer 时,会附带一个 Delivery Tag,

* 以便 Consumer 可以在消息确认时告诉 RabbitMQ 到底是哪条消息被确认了。

* RabbitMQ 保证在每个信道中,每条消息的 Delivery Tag 从 1 开始递增。

*/

Long deliveryTag = (Long) headers.get(AmqpHeaders.DELIVERY_TAG);

/**

* multiple 取值为 false 时,表示通知 RabbitMQ 当pGHWbbJADE前消息被确认

* 如果为 true,则额外将比第一个参数指定的 delivery tag 小的消息一并确认

*/

boolean multiple = false;

//ACK,确认一条消息已经被消费。不然的话,在rabbitmq首页会有Unacked显示为未处理数1.

channel.basicAck(deliveryTag,multiple);

}

}

消费者需要指定监听的队列,routingkey,和exchage,如果在localhost:15672的rabbitmq的首页没有手动创建,@RabbitListener会自动帮我们创建的并绑定关系。rabbitmq的routingkey还可以用来过滤从队列中取的的信息。

对 rabbitmq 基本理解(exchange queue binding-key routing-key)

一 exchange queue binding-key routing-key概念及相互间的关系

1.queue :存储消息的队列,可以指定name来唯一确定

2.exchange:交换机(常用有三种),用于接收生产者发来的消息,并通过binding-key 与 routing-key 的匹配关系来决定将消息分发到指定queue

2.1 Direct(路由模式):完全匹配 > 当消息的routing-key 与 exchange和queue间的binding-key完全匹配时,将消息分发到该queue

2.2 Fanout (订阅模式):与binding-key和routing-key无关,将接受到的消息分发给有绑定关系的所有队列(不论binding-key和routing-key是什么)

2.3 Topic (通配符模式):用消息的routing-key 与 exchange和queue间的binding-key 进行模式匹配,当满足规则时,分发到满足规则的所有队列

二 exchange queue binding-key routing-key的创建与使用

1. Fanout

ConnectionFactory connectionFactory = new ConnectionFactory();

// 获取到tcp连接

Connection connection = connectionFactory.newConnection();

//从tcp连接中创建通道

Channel channel = connection.createChannel();

/ 声明exchange

channel.exchangeDeclare(EXCHANGE_NAME, "fanout");

// 声明队列

channel.queueDeclare(QUEUE_NAME, false, false, false, null);

channel.queueDeclare(QUEUE_NAME2, false, false, false, null);

// 绑定队列到交换机

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

// 绑定队列到交换机 - aaa 是路由键3名称(其实这里无作用)

channel.queueBind(QUEUE_NAME2, EXCHANGE_NAME, "aaa");

这样就创建好队列和交换机并且将它们绑定好了,只要交换机EXCHANGE_NAME收到消息就会分发给队列1和2

// 消息内容

String message = "qqqqqqqq";

channel.basicPublish(EXCHANGE_NAME, "aaa", null, message.getBytes()); // 这里路由键aaa有没有都一样,可以写任何值

2.不显式声明交换机时并且发送消息不指定交换机

则默认使用Direct,并且声明队列时,不显式绑定队列与交换机,则队列以队列名为routing-key绑定到默认的direct交换机,发送消息不指定交换机时,则将消息发到默认的direct交换机

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:小程序生态建设者(小程序生态建设者是谁)
下一篇:企业app开发培训班(app软件培训)
相关文章

 发表评论

暂时没有评论,来抢沙发吧~