MQ全稱爲Message Queue,即消息隊列, RabbitMQ是由erlang語言開發,基於AMQP(Advanced Message Queue 高級消息隊列協議)協議實現的消息隊列,它是一種應用程序之間的通信方法,消息隊列在分佈式系統開 發中應用非常廣泛。RabbitMQ官方地址:https://www.rabbitmq.com/
將不需要同步處理的並且耗時長的操作由消息隊列通知消息接收方進行異步處理。提高了應用程序的響應時間。
2、應用程序解耦合 MQ相當於一箇中介,生產方通過MQ與消費方交互,它將應用程序進行解耦合;
ActiveMQ,RabbitMQ,ZeroMQ,Kafka,MetaMQ,RocketMQ、Redis。
2、基於AMQP協議(一個提供統一消息服務的應用層標準高級消息隊列協議)。
AMQP,即Advanced Message Queuing Protocol,一個提供統一消息服務的應用層標準高級消息隊列協議,是應用層協議的一個開放標準,爲面向消息的中間件設計。基於此協議的客戶端與消息中間件可傳遞消息,並不受客戶端/中間件不同產品,不同的開發語言等條件的限制。Erlang中的實現有RabbitMQ等。
總結:AMQP是一套公開的消息隊列協議,最早在2003年被提出,它旨在從協議層定義消息通信數據的標準格式, 爲的就是解決MQ市場上協議不統一的問題。RabbitMQ就是遵循AMQP標準協議開發的MQ服務。
Broker:消息隊列服務進程,此進程包括兩個部分:Exchange和Queue。
Exchange:消息隊列交換機,按一定的規則將消息路由轉發到某個隊列,對消息進行過慮。
Queue:消息隊列,存儲消息的隊列,消息到達隊列並轉發給指定的消費方。 Producer:消息生產者,即生產方客戶端,生產方客戶端將消息發送到MQ。 Consumer:消息消費者,即消費方客戶端,接收MQ轉發的消息。
------------------------------------------------------------發送消息------------------------------------------------------------
3、生產者通過通道消息發送給Broker,由Exchange將消息進行轉發。
------------------------------------------------------------接收消息------------------------------------------------------------
4、當有消息到達Queue時Broker默認將消息推送給消費者。
-----------------------------------------------------------------------------------------------------------------------------------
創建maven工程 創建生產者工程和消費者工程,分別加入RabbitMQ java client的依賴。
1.Exchange的名稱,如果沒有指定,則使用Default Exchange
2.沒有指定交換機,消息將發送給默認交換機,每個隊列也會綁定那個默認的交換機,但是不能顯 示綁定或解除綁定
4.rabbitmq默認虛擬機名稱爲“/”,虛擬機相當於一個獨立的mq服務 器
RabbitMQ有四種交換機類型:分別是Direct exchange、Fanout exchange、Topic exchange、Headers exchange
https://blog.csdn.net/rainday0310/article/details/22082503
---------------------------------------------------------------------------------------------------------------------
work queues與入門程序相比,多了一個消費端,兩個消費端共同消費同一個隊列中的消息。 應用場景:對於 任務過重或任務較多情況使用工作隊列可以提高任務處理的速度。
---------------------------------------------------------------------------------------------------------------------
---------------------------------------------------------------------------------------------------------------------
2、生產者將消息發給broker,由交換機將消息轉發到綁定此交換機的每個隊列,每個綁定交換機的隊列都將接收 到消息
---------------------------------------------------------------------------------------------------------------------
1、每個消費者監聽自己的隊列,並且設置routingkey。
2、生產者將消息發給交換機,由交換機根據routingkey來轉發消息到指定的隊列。
---------------------------------------------------------------------------------------------------------------------
1、每個消費者監聽自己的隊列,並且設置帶統配符的routingkey。
2、生產者將消息發給broker,由交換機根據routingkey來轉發消息到指定的隊列。
【比routing模式強大點在於相同的消息,只需配置共有的routingKey發送即可】
//創建一個連接
connection = factory.newConnection();
//創建與交換機的通道,每個通道代表一個會話
channel = connection.createChannel();
/**
* 聲明交換機
* param1:交換機名稱
* param2:交換機類型 四種交換機類型:direct、fanout、topic、headers
*/
channel.exchangeDeclare(EXCHANGE_TOPICS_INFORM, BuiltinExchangeType.TOPIC);
/**
*聲明隊列
* 參數明細:
* 1、隊列名稱
* 2、是否持久化
* 3、是否獨佔此隊列
* 4、隊列不用是否自動刪除
* 5、參數
*/
channel.queueDeclare(QUEUE_INFORM_EMAIL, true, false, false, null);
channel.queueDeclare(QUEUE_INFORM_SMS, true, false, false, null);
/**
*交換機和隊列綁定String queue, String exchange, String routingKey
* 參數明細
* 1、隊列名稱
* 2、交換機名稱
* 3、路由key
*/
channel.queueBind(QUEUE_INFORM_EMAIL,EXCHANGE_ROUTING_INFORM,QUEUE_INFORM_EMAIL);
channel.queueBind(QUEUE_INFORM_SMS,EXCHANGE_ROUTING_INFORM,QUEUE_INFORM_SMS);
//Email通知
channel.basicPublish(EXCHANGE_TOPICS_INFORM, "inform.email", null, message.getBytes());
//sms通知
channel.basicPublish(EXCHANGE_TOPICS_INFORM, "inform.sms", null, message.getBytes());
//兩種都通知
channel.basicPublish(EXCHANGE_TOPICS_INFORM, "inform.sms.email", null, message.getBytes());
//聲明隊列
channel.queueDeclare(QUEUE_INFORM_EMAIL, true, false, false, null);
channel.queueDeclare(QUEUE_INFORM_SMS, true, false, false, null);
//聲明交換機
channel.exchangeDeclare(EXCHANGE_TOPICS_INFORM, BuiltinExchangeType.TOPIC);
//綁定email通知隊列
channel.queueBind(QUEUE_INFORM_EMAIL,EXCHANGE_TOPICS_INFORM,"inform.#.email.#");
//綁定sms通知隊列
channel.queueBind(QUEUE_INFORM_SMS,EXCHANGE_TOPICS_INFORM,"inform.#.sms.#");
---------------------------------------------------------------------------------------------------------------------
header模式與routing不同的地方在於,header模式取消routingkey,使用header中的 key/value(鍵值對)匹配 隊列。
根據用戶的通知設置去通知用戶,設置接收Email的用戶只接收Email,設置接收sms的用戶只接收sms,設置兩種 通知類型都接收的則兩種通知都有效。
Map<String, Object> headers_email = new Hashtable<String, Object>();
headers_email.put("inform_type", "email");
Map<String, Object> headers_sms = new Hashtable<String, Object>();
headers_sms.put("inform_type", "sms");
channel.queueBind(QUEUE_INFORM_EMAIL,EXCHANGE_HEADERS_INFORM,"",headers_email);
channel.queueBind(QUEUE_INFORM_SMS,EXCHANGE_HEADERS_INFORM,"",headers_sms);
String message = "email inform to user"+i;
Map<String,Object> headers = new Hashtable<String, Object>();
headers.put("inform_type", "email");//匹配email通知消費者綁定的header
//headers.put("inform_type", "sms");//匹配sms通知消費者綁定的header
AMQP.BasicProperties.Builder properties = new AMQP.BasicProperties.Builder();
properties.headers(headers);
//Email通知
channel.basicPublish(EXCHANGE_HEADERS_INFORM, "", properties.build(), message.getBytes());
channel.exchangeDeclare(EXCHANGE_HEADERS_INFORM, BuiltinExchangeType.HEADERS);
Map<String, Object> headers_email = new Hashtable<String, Object>();
headers_email.put("inform_email", "email");
//交換機和隊列綁定
channel.queueBind(QUEUE_INFORM_EMAIL,EXCHANGE_HEADERS_INFORM,"",headers_email);
//指定消費隊列
channel.basicConsume(QUEUE_INFORM_EMAIL, true, consumer)
------------------------------------------------------------------------------------------------------------------------
RPC即客戶端遠程調用服務端的方法 ,使用MQ可以實現RPC的異步調用,基於Direct交換機實現,流程如下:
1、客戶端即是生產者就是消費者,向RPC請求隊列發送RPC調用消息,同時監聽RPC響應隊列。
2、服務端監聽RPC請求隊列的消息,收到消息後執行服務端的方法,得到方法返回的結果