RabbitMQ使用詳解
##一、訊息中介軟體概述
關注於資料的傳送和接收,利用高效可靠的非同步訊息傳遞機制整合分散式系統
1.優點
- 非同步處理
- 應用解耦
- 流量削峰
- 橫向擴充套件
- 安全可靠
- 順序保證
###2.概述
1.大多應用中,可通過訊息服務中介軟體來提升系統非同步通訊、擴充套件解耦能力 2.訊息服務中兩個重要概念: - 訊息代理(message broker)和目的地(destination) - 當訊息傳送者傳送訊息以後,將由訊息代理接管,訊息代理保證訊息傳遞到指定目的地。 3.訊息佇列主要有兩種形式的目的地 - 佇列(queue):點對點訊息通訊(point-to-point) - 主題(topic):釋出(publish)/訂閱(subscribe)訊息通訊 4.點對點式: –訊息傳送者傳送訊息,訊息代理將其放入一個佇列中,訊息接收者從佇列中獲取訊息內容,訊息讀取後被移出佇列 –訊息只有唯一的傳送者和接受者,但並不是說只能有一個接收者 5.釋出訂閱式: –傳送者(釋出者)傳送訊息到主題,多個接收者(訂閱者)監聽(訂閱)這個主題,那麼就會在訊息到達時同時收到訊息 6.JMS(Java Message Service)JAVA訊息服務: –基於JVM訊息代理的規範。ActiveMQ、HornetMQ是JMS實現 7.AMQP(Advanced Message Queuing Protocol) –高階訊息佇列協議,也是一個訊息代理的規範,相容JMS –RabbitMQ是AMQP的實現 8.Spring支援 –spring-jms提供了對JMS的支援 –spring-rabbit提供了對AMQP的支援 –需要ConnectionFactory的實現來連線訊息代理 –提供JmsTemplate、RabbitTemplate來發送訊息 –@JmsListener(JMS)、@RabbitListener(AMQP)註解在方法上監聽訊息代理髮布的訊息 –@EnableJms、@EnableRabbit開啟支援 9.Spring Boot自動配置 –JmsAutoConfiguration –RabbitAutoConfiguration
JMS 和 AMQP區別:
ActiveMQ及RabbitMQ等區別
二、RabbitMQ簡介
1.RabbitMQ簡介:
RabbitMQ是一個由erlang開發的AMQP(Advanved Message Queue Protocol)的開源實現。 rabbitMQ官網
2.核心概念
2.1Message
訊息,訊息是不具名的,它由訊息頭和訊息體組成。訊息體是不透明的,而訊息頭則由一系列的可選屬性組成,這些屬性包括routing-key(路由鍵)、priority(相對於其他訊息的優先權)、delivery-mode(指出該訊息可能需要永續性儲存)等。
2.2Publisher
訊息的生產者,也是一個向交換器釋出訊息的客戶端應用程式。
2.3Exchange
交換器,用來接收生產者傳送的訊息並將這些訊息路由給伺服器中的佇列。
2.4Exchange有4種類型:
direct(預設),fanout, topic, 和headers,不同型別的Exchange轉發訊息的策略有所區別
2.5Queue
訊息佇列,用來儲存訊息直到傳送給消費者。它是訊息的容器,也是訊息的終點。一個訊息可投入一個或多個佇列。訊息一直在佇列裡面,等待消費者連線到這個佇列將其取走。
2.6Binding
繫結,用於訊息佇列和交換器之間的關聯。一個繫結就是基於路由鍵將交換器和訊息佇列連線起來的路由規則,所以可以將交換器理解成一個由繫結構成的路由表。 Exchange 和Queue的繫結可以是多對多的關係。
2.7Connection
網路連線,比如一個TCP連線。
2.8Channel
通道,多路複用連線中的一條獨立的雙向資料流通道。通道是建立在真實的TCP連線內的虛擬連線,AMQP 命令都是通過通道發出去的,不管是釋出訊息、訂閱佇列還是接收訊息,這些動作都是通過通道完成。因為對於作業系統來說建立和銷燬TCP 都是非常昂貴的開銷,所以引入了通道的概念,以複用一條TCP 連線。
2.9Consumer
訊息的消費者,表示一個從訊息佇列中取得訊息的客戶端應用程式。
2.10Virtual Host
虛擬主機,表示一批交換器、訊息佇列和相關物件。虛擬主機是共享相同的身份認證和加密環境的獨立伺服器域。每個vhost 本質上就是一個mini 版的RabbitMQ 伺服器,擁有自己的佇列、交換器、繫結和許可權機制。vhost 是AMQP 概念的基礎,必須在連線時指定,RabbitMQ 預設的vhost 是/ 。
Broker
表示訊息佇列伺服器實體
-訊息佇列的使用過程大概如下:
-訊息接收
-客戶端連線到訊息佇列伺服器,開啟一個channel。
-客戶端宣告一個exchange,並設定相關屬性。
-客戶端宣告一個queue,並設定相關屬性。
-客戶端使用routing key,在exchange和queue之間建立好繫結關係。
-訊息釋出
-客戶端投遞訊息到exchange。
-exchange接收到訊息後,就根據訊息的key和已經設定的binding,進行訊息路由,將訊息投遞到一個或多個佇列裡。
-AMQP 裡主要要說兩個元件:
-Exchange 和 Queue
-綠色的 X 就是 Exchange ,紅色的是 Queue ,這兩者都在 Server 端,又稱作 Broker
-這部分是 RabbitMQ 實現的,而藍色的則是客戶端,通常有 Producer 和 Consumer 兩種型別。
-Exchange通常分為四種:
-fanout:該型別路由規則非常簡單,會把所有傳送到該Exchange的訊息路由到所有與它繫結的Queue中,相當於廣播功能
-direct:該型別路由規則會將訊息路由到binding key與routing key完全匹配的Queue中
-topic:與direct型別相似,只是規則沒有那麼嚴格,可以模糊匹配和多條件匹配
-headers:該型別不依賴於routing key與binding key的匹配規則來路由訊息,而是根據傳送的訊息內容中的headers屬性進行匹配
三、RabbitMQ安裝
2.1Windows安裝
下載對應的.exe檔案(otp_win64_21.0.1.exe),然後傻瓜式安裝直接下一步.這個檔案安裝的時候儘量不要去修改,包括安裝路徑,使用預設.
2.1.2配置環境變數
設定環境變數:
ERLANG_HOME = C:\Program Files\erl10.0.1
Path = %ERLANG_HOME%\bin;
提供多種安裝版本,可以直接使用windows的解壓版,不需要安裝,直接解壓即可. 本次解壓路徑:D:\soft\rabbitmq_server-3.7.7 ####2.2.2 執行對應的命令 切換cmd命令到指定sbin(D:\soft\rabbitmq_server-3.7.7\sbin )目錄,執行對應的命令 檢視狀態(rabbitmqctl status): 安裝windows服務: 使用:rabbitmq-service install 啟動服務: 可以手動啟動,也可以使用 rabbitmq-service start 啟動 其他rabbitmq-service 可用命令: ####2.3 安裝後臺視覺化管理介面 輸入命令rabbitmq-plugins enable rabbitmq_management,這樣就可以新增視覺化外掛了。 檢視視覺化外掛是否成功: 在web瀏器中輸入地址:http://127.0.0.1:15672/ 輸入預設賬號: guest 密碼: guest 就可以登入檢視rabbitmq裡的資源資訊。
##四、RabbitMQ執行機制 ###1.AMQP 中的訊息路由 •AMQP 中訊息的路由過程和Java 開發者熟悉的JMS 存在一些差別,AMQP 中增加了Exchange和Binding的角色。生產者把訊息釋出到Exchange 上,訊息最終到達佇列並被消費者接收,而Binding 決定交換器的訊息應該傳送到那個佇列。 ###2.Exchange 型別 Exchange分發訊息時根據型別的不同分發策略有區別,目前共四種類型:direct、fanout、topic、headers 。headers 匹配AMQP 訊息的header 而不是路由鍵,headers 交換器和direct 交換器完全一致,但效能差很多,目前幾乎用不到了,所以直接看另外三種類型:
五、程式碼實現
1.匯入jar包
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
2.修改配置檔案
spring.rabbitmq.host=192.168.2.110
spring.rabbitmq.port=5672
spring.rabbitmq.username=guest
spring.rabbitmq.password=guest
3.佇列配置
@Configuration
public class RabbitConfig {
@Bean
public Queue Queue() {
return new Queue("hello");
}
}
4、傳送者
rabbitTemplate是springboot 提供的預設實現
public class HelloSender {
@Autowired
private AmqpTemplate rabbitTemplate;
public void send() {
String context = "hello " + new Date();
System.out.println("Sender : " + context);
this.rabbitTemplate.convertAndSend("hello", context);
}
}
5、接收者
@Component
@RabbitListener(queues = "hello")
public class HelloReceiver {
@RabbitHandler
public void process(String hello) {
System.out.println("Receiver : " + hello);
}
}
6、測試
@RunWith(SpringRunner.class)
@SpringBootTest
public class RabbitMqHelloTest {
@Autowired
private HelloSender helloSender;
@Test
public void hello() throws Exception {
helloSender.send();
}
}
注意,傳送者和接收者的queue name必須一致,不然不能接收