RabbitMQ研究和使用

MQ全稱爲Message Queue,即消息隊列, RabbitMQ是由erlang語言開發,基於AMQP(Advanced Message Queue 高級消息隊列協議)協議實現的消息隊列,它是一種應用程序之間的通信方法,消息隊列在分佈式系統開 發中應用非常廣泛。RabbitMQ官方地址:https://www.rabbitmq.com/

開發中消息隊列通常有如下應用場景:

1、任務異步處理。

將不需要同步處理的並且耗時長的操作由消息隊列通知消息接收方進行異步處理。提高了應用程序的響應時間。

2、應用程序解耦合 MQ相當於一箇中介,生產方通過MQ與消費方交互,它將應用程序進行解耦合;

3、流量削峯,可以限制訪問數量。

市場上還有哪些消息隊列?

ActiveMQ,RabbitMQ,ZeroMQ,Kafka,MetaMQ,RocketMQ、Redis。

爲什麼使用RabbitMQ呢?

1、使得簡單,功能強大。

2、基於AMQP協議(一個提供統一消息服務的應用層標準高級消息隊列協議)。

3、社區活躍,文檔完善。

4、高併發性能好,這主要得益於Erlang語言。

5、Spring Boot默認已集成RabbitMQ

AMQP介紹

AMQP,即Advanced Message Queuing Protocol,一個提供統一消息服務的應用層標準高級消息隊列協議,是應用層協議的一個開放標準,爲面向消息的中間件設計。基於此協議的客戶端與消息中間件可傳遞消息,並不受客戶端/中間件不同產品,不同的開發語言等條件的限制。Erlang中的實現有RabbitMQ等。

總結:AMQP是一套公開的消息隊列協議,最早在2003年被提出,它旨在從協議層定義消息通信數據的標準格式, 爲的就是解決MQ市場上協議不統一的問題。RabbitMQ就是遵循AMQP標準協議開發的MQ服務。

下圖是RabbitMQ的基本結構:

組成部分說明如下:

Broker:消息隊列服務進程,此進程包括兩個部分:Exchange和Queue。

Exchange:消息隊列交換機,按一定的規則將消息路由轉發到某個隊列,對消息進行過慮。

Queue:消息隊列,存儲消息的隊列,消息到達隊列並轉發給指定的消費方。 Producer:消息生產者,即生產方客戶端,生產方客戶端將消息發送到MQ。 Consumer:消息消費者,即消費方客戶端,接收MQ轉發的消息。

消息生產和消費流程:

------------------------------------------------------------發送消息------------------------------------------------------------

1、生產者和Broker建立TCP連接。

2、生產者和Broker建立通道。

3、生產者通過通道消息發送給Broker,由Exchange將消息進行轉發。

4、Exchange將消息轉發到指定的Queue(隊列)

------------------------------------------------------------接收消息------------------------------------------------------------

1、消費者和Broker建立TCP連接

2、消費者和Broker建立通道

3、消費者監聽指定的Queue(隊列)

4、當有消息到達Queue時Broker默認將消息推送給消費者。

5、消費者接收到消息。

-----------------------------------------------------------------------------------------------------------------------------------

1、發送端操作流程

 

 1)創建連接

  2)創建通道

  3)聲明隊列

 4)發送消息

2、接收端

 

 1)創建連接

  2)創建通道

  3)聲明隊列

 4)監聽隊列

5)接收消息

 6)ack回覆

快速入門:

1.Hello World

創建maven工程 創建生產者工程和消費者工程,分別加入RabbitMQ java client的依賴。

test-rabbitmq-producer:生產者工程

test-rabbitmq-consumer:消費者工程

1.Exchange的名稱,如果沒有指定,則使用Default Exchange

2.沒有指定交換機,消息將發送給默認交換機,每個隊列也會綁定那個默認的交換機,但是不能顯 示綁定或解除綁定

3. 默認的交換機,routingKey等於隊列名稱

4.rabbitmq默認虛擬機名稱爲“/”,虛擬機相當於一個獨立的mq服務 器

 工作模式

RabbitMQ有以下幾種工作模式 :

1、Work queues

2、Publish/Subscribe

3、Routing

4、Topics

5、Header

6、RPC

RabbitMQ有四種交換機類型:分別是Direct exchange、Fanout exchange、Topic exchange、Headers exchange

https://blog.csdn.net/rainday0310/article/details/22082503

---------------------------------------------------------------------------------------------------------------------

工作隊列(work queues)模式:

work queues與入門程序相比,多了一個消費端,兩個消費端共同消費同一個隊列中的消息。 應用場景:對於 任務過重或任務較多情況使用工作隊列可以提高任務處理的速度。

---------------------------------------------------------------------------------------------------------------------

測試:

1、使用入門程序,啓動多個消費者。

2、生產者發送多個消息。

結果:

1、一條消息只會被一個消費者接收;

2、rabbit採用輪詢的方式將消息是平均發送給消費者的;

3、消費者在處理完某條消息後,纔會收到下一條消息。

---------------------------------------------------------------------------------------------------------------------

發佈訂閱(Publish/Subscribe)模式:

1、每個消費者監聽自己的隊列。

2、生產者將消息發給broker,由交換機將消息轉發到綁定此交換機的每個隊列,每個綁定交換機的隊列都將接收 到消息

---------------------------------------------------------------------------------------------------------------------

路由(routing)模式:

1、每個消費者監聽自己的隊列,並且設置routingkey

2、生產者將消息發給交換機,由交換機根據routingkey來轉發消息到指定的隊列。

---------------------------------------------------------------------------------------------------------------------

Topics(通配符)模式:

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模式:

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模式:

RPC即客戶端遠程調用服務端的方法 ,使用MQ可以實現RPC的異步調用,基於Direct交換機實現,流程如下:

1、客戶端即是生產者就是消費者,向RPC請求隊列發送RPC調用消息,同時監聽RPC響應隊列。

2、服務端監聽RPC請求隊列的消息,收到消息後執行服務端的方法,得到方法返回的結果

 3、服務端將RPC方法 的結果發送到RPC響應隊列

4、客戶端(RPC調用方)監聽RPC響應隊列,接收到RPC調用結果。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章