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<String,Object> 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 當前消息被確認 * 如果為 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交換機
以上為個人經驗,希望能給大傢一個參考,也希望大傢多多支持WalkonNet。
推薦閱讀:
- Java RabbitMQ高級特性詳細分析
- SpringBoot+RabbitMQ實現消息可靠傳輸詳解
- SpringBoot整合RabbitMQ實現六種工作模式的示例
- springBoot整合rabbitmq測試常用模型小結
- RabbitMQ 3.9.7 鏡像模式集群與Springboot 2.5.5 整合