一、消息中間件概述
關(guān)注于數(shù)據(jù)的發(fā)送和接收,利用高效可靠的異步消息傳遞機(jī)制集成分布式系統(tǒng)
1.優(yōu)點
- 異步處理
- 應(yīng)用解耦
- 流量削峰
- 橫向擴(kuò)展
- 安全可靠
- 順序保證






2.概述
1.大多應(yīng)用中,可通過消息服務(wù)中間件來提升系統(tǒng)異步通信、擴(kuò)展解耦能力
2.消息服務(wù)中兩個重要概念:
- 消息代理(message broker)和目的地(destination)
- 當(dāng)消息發(fā)送者發(fā)送消息以后,將由消息代理接管,消息代理保證消息傳遞到指定目的地。
3.消息隊列主要有兩種形式的目的地
- 隊列(queue):點對點消息通信(point-to-point)
- 主題(topic):發(fā)布(publish)/訂閱(subscribe)消息通信
4.點對點式:
–消息發(fā)送者發(fā)送消息,消息代理將其放入一個隊列中,消息接收者從隊列中獲取消息內(nèi)容,消息讀取后被移出隊列
–消息只有唯一的發(fā)送者和接受者,但并不是說只能有一個接收者
5.發(fā)布訂閱式:
–發(fā)送者(發(fā)布者)發(fā)送消息到主題,多個接收者(訂閱者)監(jiān)聽(訂閱)這個主題,那么就會在消息到達(dá)時同時收到消息
6.JMS(Java Message Service)JAVA消息服務(wù):
–基于JVM消息代理的規(guī)范。ActiveMQ、HornetMQ是JMS實現(xiàn)
7.AMQP(Advanced Message Queuing Protocol)
–高級消息隊列協(xié)議,也是一個消息代理的規(guī)范,兼容JMS
–RabbitMQ是AMQP的實現(xiàn)
8.Spring支持
–spring-jms提供了對JMS的支持
–spring-rabbit提供了對AMQP的支持
–需要ConnectionFactory的實現(xiàn)來連接消息代理
–提供JmsTemplate、RabbitTemplate來發(fā)送消息
–@JmsListener(JMS)、@RabbitListener(AMQP)注解在方法上監(jiān)聽消息代理發(fā)布的消息
–@EnableJms、@EnableRabbit開啟支持
9.Spring Boot自動配置
–JmsAutoConfiguration
–RabbitAutoConfiguration
JMS 和 AMQP區(qū)別:

ActiveMQ及RabbitMQ等區(qū)別

二、RabbitMQ簡介
1.RabbitMQ簡介:
RabbitMQ是一個由erlang開發(fā)的AMQP(Advanved Message Queue Protocol)的開源實現(xiàn)。

rabbitMQ官網(wǎng)
2.核心概念
2.1Message
消息,消息是不具名的,它由消息頭和消息體組成。消息體是不透明的,而消息頭則由一系列的可選屬性組成,這些屬性包括routing-key(路由鍵)、priority(相對于其他消息的優(yōu)先權(quán))、delivery-mode(指出該消息可能需要持久性存儲)等。
2.2Publisher
消息的生產(chǎn)者,也是一個向交換器發(fā)布消息的客戶端應(yīng)用程序。
2.3Exchange
交換器,用來接收生產(chǎn)者發(fā)送的消息并將這些消息路由給服務(wù)器中的隊列。
2.4Exchange有4種類型:
direct(默認(rèn)),fanout, topic, 和headers,不同類型的Exchange轉(zhuǎn)發(fā)消息的策略有所區(qū)別
2.5Queue
消息隊列,用來保存消息直到發(fā)送給消費(fèi)者。它是消息的容器,也是消息的終點。一個消息可投入一個或多個隊列。消息一直在隊列里面,等待消費(fèi)者連接到這個隊列將其取走。
2.6Binding
綁定,用于消息隊列和交換器之間的關(guān)聯(lián)。一個綁定就是基于路由鍵將交換器和消息隊列連接起來的路由規(guī)則,所以可以將交換器理解成一個由綁定構(gòu)成的路由表。
Exchange 和Queue的綁定可以是多對多的關(guān)系。
2.7Connection
網(wǎng)絡(luò)連接,比如一個TCP連接。
2.8Channel
信道,多路復(fù)用連接中的一條獨立的雙向數(shù)據(jù)流通道。信道是建立在真實的TCP連接內(nèi)的虛擬連接,AMQP 命令都是通過信道發(fā)出去的,不管是發(fā)布消息、訂閱隊列還是接收消息,這些動作都是通過信道完成。因為對于操作系統(tǒng)來說建立和銷毀TCP 都是非常昂貴的開銷,所以引入了信道的概念,以復(fù)用一條TCP 連接。
2.9Consumer
消息的消費(fèi)者,表示一個從消息隊列中取得消息的客戶端應(yīng)用程序。
2.10Virtual Host
虛擬主機(jī),表示一批交換器、消息隊列和相關(guān)對象。虛擬主機(jī)是共享相同的身份認(rèn)證和加密環(huán)境的獨立服務(wù)器域。每個vhost 本質(zhì)上就是一個mini 版的RabbitMQ 服務(wù)器,擁有自己的隊列、交換器、綁定和權(quán)限機(jī)制。vhost 是AMQP 概念的基礎(chǔ),必須在連接時指定,RabbitMQ 默認(rèn)的vhost 是/ 。
Broker
表示消息隊列服務(wù)器實體
-消息隊列的使用過程大概如下:
-消息接收
-客戶端連接到消息隊列服務(wù)器,打開一個channel。
-客戶端聲明一個exchange,并設(shè)置相關(guān)屬性。
-客戶端聲明一個queue,并設(shè)置相關(guān)屬性。
-客戶端使用routing key,在exchange和queue之間建立好綁定關(guān)系。
-消息發(fā)布
-客戶端投遞消息到exchange。
-exchange接收到消息后,就根據(jù)消息的key和已經(jīng)設(shè)置的binding,進(jìn)行消息路由,將消息投遞到一個或多個隊列里。
-AMQP 里主要要說兩個組件:
-Exchange 和 Queue
-綠色的 X 就是 Exchange ,紅色的是 Queue ,這兩者都在 Server 端,又稱作 Broker
-這部分是 RabbitMQ 實現(xiàn)的,而藍(lán)色的則是客戶端,通常有 Producer 和 Consumer 兩種類型。
-Exchange通常分為四種:
-fanout:該類型路由規(guī)則非常簡單,會把所有發(fā)送到該Exchange的消息路由到所有與它綁定的Queue中,相當(dāng)于廣播功能
-direct:該類型路由規(guī)則會將消息路由到binding key與routing key完全匹配的Queue中
-topic:與direct類型相似,只是規(guī)則沒有那么嚴(yán)格,可以模糊匹配和多條件匹配
-headers:該類型不依賴于routing key與binding key的匹配規(guī)則來路由消息,而是根據(jù)發(fā)送的消息內(nèi)容中的headers屬性進(jìn)行匹配
三、RabbitMQ安裝
2.1Windows安裝
2.1.1下載erlang依賴:http://www.erlang.org/downloads
下載對應(yīng)的.exe文件(otp_win64_21.0.1.exe),然后傻瓜式安裝直接下一步.這個文件安裝的時候盡量不要去修改,包括安裝路徑,使用默認(rèn).
2.1.2配置環(huán)境變量
設(shè)置環(huán)境變量:
ERLANG_HOME = C:\Program Files\erl10.0.1
Path = %ERLANG_HOME%\bin;
2.2.1rabbitMQ下載文件:http://www.rabbitmq.com/download.html
下載路徑

提供多種安裝版本,可以直接使用windows的解壓版,不需要安裝,直接解壓即可.
本次解壓路徑:D:\soft\rabbitmq_server-3.7.7

2.2.2 執(zhí)行對應(yīng)的命令
切換cmd命令到指定sbin(D:\soft\rabbitmq_server-3.7.7\sbin )目錄,執(zhí)行對應(yīng)的命令

安裝windows服務(wù):
使用:rabbitmq-service install


啟動服務(wù):
可以手動啟動,也可以使用 rabbitmq-service start 啟動

其他rabbitmq-service 可用命令:

2.3 安裝后臺可視化管理界面
輸入命令rabbitmq-plugins enable rabbitmq_management,這樣就可以添加可視化插件了。

查看可視化插件是否成功:
在web瀏器中輸入地址:http://127.0.0.1:15672/
輸入默認(rèn)賬號: guest 密碼: guest
就可以登錄查看rabbitmq里的資源信息。

四、RabbitMQ運(yùn)行機(jī)制
1.AMQP 中的消息路由
?AMQP 中消息的路由過程和Java 開發(fā)者熟悉的JMS 存在一些差別,AMQP 中增加了Exchange和Binding的角色。生產(chǎn)者把消息發(fā)布到Exchange 上,消息最終到達(dá)隊列并被消費(fèi)者接收,而Binding 決定交換器的消息應(yīng)該發(fā)送到那個隊列。
2.Exchange 類型
Exchange分發(fā)消息時根據(jù)類型的不同分發(fā)策略有區(qū)別,目前共四種類型:direct、fanout、topic、headers 。headers 匹配AMQP 消息的header 而不是路由鍵,headers 交換器和direct 交換器完全一致,但性能差很多,目前幾乎用不到了,所以直接看另外三種類型:



五、代碼實現(xiàn)
1.導(dǎo)入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、發(fā)送者
rabbitTemplate是springboot 提供的默認(rèn)實現(xiàn)
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();
}
}
注意,發(fā)送者和接收者的queue name必須一致,不然不能接收