天天看點

SpringBoot進階_與消息_1

一、概述

 1、大多應用中,可通過消息服務中間件來提升系統異步通信、擴充解耦能力

 2、消息服務中的兩個重要概念:消息代理(message broker,即消息中間件伺服器)和目的地(destination)

  當消息發送者發送消息以後,将由消息代理接管,消息代理保證消息傳遞到指定目的地。

 3、消息隊列主要有兩種形式的目的地

  隊列(queue):點對點消息通信(point-to-point)

   消息發送者發送消息,消息代理将其放入一個隊列中,消息接收者從隊列中擷取消息内容,消息讀取後被移出隊列

   消息隻有唯一的發送者和接受者,但并不是說隻能有一個接收者,這是因為消息一旦被消費就會從隊列中移除

  主題(topic):釋出(publish)/訂閱(subscribe)消息通信

   發送者(釋出者)發送消息到主題,多個接收者(訂閱者)監聽(訂閱)這個主題,那麼就會在消息到達時同時收到消息,不同于點對點的方式,在點對點的方式中一旦一個接收者處理了消息,消息就會被移除,那麼其他的接收者就不會再去處理,而訂閱的方式則是所有的接收者都會對該消息做出相應處理

二、使用場景

 1、異步處理

SpringBoot進階_與消息_1

在使用者注冊時給使用者發送短信和郵件,但是短信和郵件并不需要在注冊成功已完成就發送,是以可以異步處理

 2、應用解耦

SpringBoot進階_與消息_1

 3、流量削峰

SpringBoot進階_與消息_1

 比如秒殺:在10萬個客戶秒殺1萬個商品的時候,每個客戶點選都發送一次請求,這時如果将每個請求都進行判斷(商品是否已被秒殺完,然後響應秒殺結果)是很慢的,可以先将前1萬個請求寫入消息隊列并響應秒殺成功,後續的9萬個請求直接響應秒殺失敗,然後秒殺的具體處理服務再從隊列中擷取前一萬個請求進行處理。

三、消息服務規範

 1、JMS(Java Message Service):JAVA消息服務,基于JVM消息代理的規範,ActiveMQ、HornetMQ是JMS的實作

 2、AMQP(Advanced Message Queuing Protocol):進階消息隊列協定,也是一個消息代理的規範,相容JMS,RabbitMQ是AMQP的實作

 3、對比:

SpringBoot進階_與消息_1

4、支援:

  a、Spring支援:

   spring-jms提供了對JMS的支援

   spring-rabbit提供了對AMQP的支援

   需要ConnectionFactory的實作來連接配接消息代理

   提供JmsTemplate、RabbitTemplate來發送消息

   @JmsListener(JMS)、@RabbitListener(AMQP)注解在方法上監聽消息代理釋出的消息

   @EnableJms、@EnableRabbit開啟支援

  b、Spring Boot自動配置

   JmsAutoConfiguration

   RabbitAutoConfiguration

四、RabbitMQ簡介

1、簡介:RabbitMQ是一個由erlang開發的AMQP(Advanved Message Queue Protocol)的開源實作。

SpringBoot進階_與消息_1

2、核心概念

  a、Message

   消息,消息是不具名的,它由消息頭和消息體組成。消息體是不透明的,而消息頭則由一系列的可選屬性組成,這些屬性包括routing-key(路由鍵)、priority(相對于其他消息的優先權)、delivery-mode(指出該消息可能需要持久性存儲)等。

  b、Publisher

   消息的生産者,也是一個向交換器釋出消息的用戶端應用程式。

  c、Exchange

   交換器,用來接收生産者發送的消息并将這些消息路由給伺服器中的隊列。

   Exchange有4種類型:direct(預設,處理點對點模式的消息)、fanout、topic、 和headers(後三個都是處理主題訂閱模式的消息),不同類型的Exchange轉發消息的政策有所差別。

  d、Queue

   消息隊列,用來儲存消息直到發送給消費者。它是消息的容器,也是消息的終點。一個消息可投入一個或多個隊列。消息一直在隊列裡面,等待消費者連接配接到這個隊列将其取走。

  e、Binding

   綁定,用于消息隊列和交換器之間的關聯。一個綁定就是基于路由鍵将交換器和消息隊列連接配接起來的路由規則,是以可以将交換器了解成一個由綁定構成的路由表。

   Exchange 和Queue的綁定可以是多對多的關系。

  f、Connection

   網絡連接配接,比如一個TCP連接配接。

  g、Channel

   信道,多路複用連接配接中的一條獨立的雙向資料流通道。信道是建立在真實的TCP連接配接内的虛拟連接配接,AMQP 指令都是通過信道發出去的,不管是釋出消息、訂閱隊列還是接收消息,這些動作都是通過信道完成。因為對于作業系統來說建立和銷毀 TCP連接配接(Connection) 都是非常昂貴的開銷,是以引入了信道的概念,以複用一條 TCP 連接配接。

  h、Consumer

   消息的消費者,表示一個從消息隊列中取得消息的用戶端應用程式。

  i、Virtual Host

   虛拟主機,表示一批交換器、消息隊列和相關對象。虛拟主機是共享相同的身份認證和加密環境的獨立伺服器域。每個 vhost 本質上就是一個 mini 版的 RabbitMQ 伺服器,擁有自己的隊列、交換器、綁定和權限機制。vhost 是 AMQP 概念的基礎,必須在連接配接時指定,RabbitMQ 預設的 vhost 是 / 。

  j、Broker

   表示消息隊列伺服器實體

 總結:一個Brokker中可能有多個虛拟主機(vhost),一個虛拟主機中可能有多個交換器(Exchange),一個交換器可能綁定多個隊列(Queue),一個隊列也可能被多個交換器綁定,消費者在消費某個隊列的消息時需要建立連接配接(Connection),由于建立連接配接的開銷比較大,是以引入了信道(Channel)的概念,一個連接配接中拆分出多個信道,分别負責連接配接不同的隊列。

五、RabbitMQ的消息路由機制

 1、概述

  AMQP 中消息的路由過程和 Java 開發者熟悉的 JMS 存在一些差别,AMQP 中增加了 Exchange 和 Binding 的角色。生産者把消息釋出到 Exchange 上,消息最終到達隊列并被消費者接收,而 Binding 決定交換器的消息應該發送到那個隊列。

 a、Direct

SpringBoot進階_與消息_1

2、類型

  Exchange分發消息時根據類型的不同分發政策有差別,目前共四種類型:direct、fanout、topic、headers 。headers 比對 AMQP 消息的 header 而不是路由鍵, headers 交換器和 direct 交換器完全一緻,但性能差很多,目前幾乎用不到了。

   a、Direct

SpringBoot進階_與消息_1

消息中的路由鍵(routing key)如果和 Binding 中的 binding key 一緻, 交換器就将消息發到對應的隊列中。路由鍵與隊列名完全比對,如果一個隊列綁定的交換機要求路由鍵為“dog”,則隻轉發 routing key 标記為“dog”的消息,不會轉發“dog.puppy”,也不會轉發“dog.guard”等等。它是完全比對、單點傳播的模式。

  b、Fanout

SpringBoot進階_與消息_1

每個發到 fanout 類型交換器的消息都會分到所有綁定的隊列上去,類似于廣播。fanout 交換器不處理路由鍵,隻是簡單的将隊列綁定到交換器上,每個發送到交換器的消息都會被轉發到與該交換器綁定的所有隊列上。很像子網廣播,每台子網内的主機都獲得了一份複制的消息。fanout 類型轉發消息是最快的。

  c、Topic

SpringBoot進階_與消息_1

topic 交換器通過模式比對配置設定消息的路由鍵屬性,将路由鍵和某個模式進行比對,此時隊列需要綁定到一個模式上。它将路由鍵和綁定鍵的字元串切分成單詞,這些單詞之間用點隔開。它同樣也會識别兩個通配符:符号“#”和符号“*”。#比對0個或多個單詞,*比對一個單詞。

六、安裝和測試RabbitMQ

1、安裝RabbitMQ:Docker方式

SpringBoot進階_與消息_1
SpringBoot進階_與消息_1

預設賬号和密碼都是guest

 2、添加交換器(Exchanges)

SpringBoot進階_與消息_1

按照整合的要求添加三個交換器:

SpringBoot進階_與消息_1

3、添加隊列(Queue)

SpringBoot進階_與消息_1

按照需求添加的隊列:

SpringBoot進階_與消息_1

4、将隊列和交換器綁定

  點選每一個交換器,在頁面中都綁定添加的四個隊列:

SpringBoot進階_與消息_1
SpringBoot進階_與消息_1

在綁定topic類型的交換器時路由鍵有點不同,可以寫通配符:

SpringBoot進階_與消息_1

5、測試:可以選擇任何一個交換器進行測試

繼續閱讀