前言
RabbitMQ 是在 AMQP(Advanced Message Queuing Protocol) 協(xié)議標(biāo)準(zhǔn)基礎(chǔ)上完整的,可復(fù)用的企業(yè)消息系統(tǒng)。它遵循 Mozilla Public License 開(kāi)源協(xié)議,采用 Erlang 實(shí)現(xiàn)的工業(yè)級(jí)的消息隊(duì)列(MQ)服務(wù)器,建立在 Erlang OTP 平臺(tái)上(因?yàn)椴捎?Erlang 開(kāi)發(fā),所以 RabbitMQ 穩(wěn)定性和可靠性比較高)
其他主流 MQ 產(chǎn)品
- ActiveMQ:Apache 出品,最流行的,能力強(qiáng)勁的開(kāi)源消息總線,基于 JMS(Java Message Service)規(guī)范
- RocketMQ:阿里低延遲、高并發(fā)、高可用、高可靠的分布式消息中間件,基于 JMS,目前由 Apache 基金會(huì)維護(hù)
- Kafka:分布式,分區(qū)的,多副本的,多訂閱者的消息發(fā)布訂閱系統(tǒng)(分布式 MQ 系統(tǒng)),可以用于搜索日志,監(jiān)控日志,訪問(wèn)日志等
本文為 RabbitMQ 入門教程,主要將會(huì)講解 RabbitMQ 安裝配置(Windows),相關(guān)概念,及項(xiàng)目中具體應(yīng)用
安裝
Erlang
官網(wǎng)下載鏈接:Downloads - Erlang/OTP
RabbitMQ 服務(wù)器必須首先安裝 Erlang 運(yùn)行環(huán)境,同時(shí)安裝時(shí)需要注意 RabbityMQ 所依賴的 Erlang 版本,我們可以查看下方官方版本對(duì)應(yīng)信息
版本對(duì)應(yīng):RabbitMQ Erlang Version Requirements — RabbitMQ
本次使用版本 Erlang OTP 25.3(點(diǎn)擊跳轉(zhuǎn)下載鏈接)
雙擊執(zhí)行 exe 安裝程序,除了安裝路徑其他都按照默認(rèn)即可
然后配置環(huán)境變量
ERLANG_HOME = D:\Erlang\Erlang\Erlang OTP
并且添加 /bin 目錄到 Path 環(huán)境變量中,即添加 %ERLANG_HOME%\bin
到 Path 中
安裝配置之后,打開(kāi) CMD,輸入 erl 然后回車鍵,會(huì)彈出版本信息,表示 Erlang 安裝成功
RabbitMQ
官方下載頁(yè)面:RabbitMQ Changelog — RabbitMQ
下載鏈接: RabbitMQ 3.12.0
安裝 exe 文件,執(zhí)行安裝包,同樣除了安裝路徑外其他保持默認(rèn)
配置環(huán)境變量
RABBITMQ_SERVER = D:\RabbitMQ\RabbitMQ\rabbitmq_server-3.12.0
然后添加 %RABBITMQ_SERVER%\sbin
到 Path 環(huán)境變量中
查看所有插件
rabbitmq-plugins list
注:如果出現(xiàn)問(wèn)題請(qǐng)參考最后一章 徹底卸載
之后我們需要安裝 rabbitmq_management 插件,可以使用可視化的方式查看 RabbitMQ 服務(wù)器實(shí)例的狀態(tài),以及操控 RabbitMQ 服務(wù)器
# 安裝插件
rabbitmq-plugins enable rabbitmq_management
訪問(wèn)管理界面: http://localhost:15672/ (賬號(hào)密碼:guest / guest)
前期安裝配置完畢,下面可以配合官方入門文檔學(xué)習(xí)
官方文檔:RabbitMQ Tutorials — RabbitMQ
消息隊(duì)列
定義
消息指的是兩個(gè)應(yīng)用間傳遞的數(shù)據(jù)。數(shù)據(jù)的類型有很多種形式,可能只包含文本字符串,也可能包含嵌入對(duì)象。
“消息隊(duì)列(Message Queue)”是在消息的傳輸過(guò)程中保存消息的容器。在消息隊(duì)列中,通常有生產(chǎn)者和消費(fèi)者兩個(gè)角色。生產(chǎn)者只負(fù)責(zé)發(fā)送數(shù)據(jù)到消息隊(duì)列,誰(shuí)從消息隊(duì)列中取出數(shù)據(jù)處理,他不管。消費(fèi)者只負(fù)責(zé)從消息隊(duì)列中取出數(shù)據(jù)處理,他不管這是誰(shuí)發(fā)送的數(shù)據(jù)
作用
解耦。如圖所示。假設(shè)有系統(tǒng) B、C、D 都需要系統(tǒng) A 的數(shù)據(jù),于是系統(tǒng) A 調(diào)用三個(gè)方法發(fā)送數(shù)據(jù)到 B、C、D。這時(shí),系統(tǒng) D 不需要了,那就需要在系統(tǒng) A 把相關(guān)的代碼刪掉。假設(shè)這時(shí)有個(gè)新的系統(tǒng) E 需要數(shù)據(jù),這時(shí)系統(tǒng) A 又要增加調(diào)用系統(tǒng) E 的代碼。為了降低這種強(qiáng)耦合,就可以使用 MQ,系統(tǒng) A 只需要把數(shù)據(jù)發(fā)送到 MQ,其他系統(tǒng)如果需要數(shù)據(jù),則從 MQ 中獲取即可
異步。如圖所示。一個(gè)客戶端請(qǐng)求發(fā)送進(jìn)來(lái),系統(tǒng) A 會(huì)調(diào)用系統(tǒng) B、C、D 三個(gè)系統(tǒng),同步請(qǐng)求的話,響應(yīng)時(shí)間就是系統(tǒng) A、B、C、D 的總和,也就是 800ms。如果使用 MQ,系統(tǒng) A 發(fā)送數(shù)據(jù)到 MQ,然后就可以返回響應(yīng)給客戶端,不需要再等待系統(tǒng) B、C、D 的響應(yīng),可以大大地提高性能。對(duì)于一些非必要的業(yè)務(wù),比如發(fā)送短信,發(fā)送郵件等等,就可以采用 MQ
削峰。如圖所示。這其實(shí)是 MQ 一個(gè)很重要的應(yīng)用。假設(shè)系統(tǒng) A 在某一段時(shí)間請(qǐng)求數(shù)暴增,有 5000 個(gè)請(qǐng)求發(fā)送過(guò)來(lái),系統(tǒng) A 這時(shí)就會(huì)發(fā)送 5000 條 SQL 進(jìn)入 MySQL 進(jìn)行執(zhí)行,MySQL 對(duì)于如此龐大的請(qǐng)求當(dāng)然處理不過(guò)來(lái),MySQL 就會(huì)崩潰,導(dǎo)致系統(tǒng)癱瘓。如果使用 MQ,系統(tǒng) A 不再是直接發(fā)送 SQL 到數(shù)據(jù)庫(kù),而是把數(shù)據(jù)發(fā)送到 MQ,MQ 短時(shí)間積壓數(shù)據(jù)是可以接受的,然后由消費(fèi)者每次拉取 2000 條進(jìn)行處理,防止在請(qǐng)求峰值時(shí)期大量的請(qǐng)求直接發(fā)送到 MySQL 導(dǎo)致系統(tǒng)崩潰
特點(diǎn)
可靠性:通過(guò)支持消息持久化,支持事務(wù),支持消費(fèi)和傳輸?shù)?ack 等來(lái)確??煽啃?/p>
路由機(jī)制:支持主流的訂閱消費(fèi)模式,如廣播,訂閱,headers 匹配等
擴(kuò)展性:多個(gè) RabbitMQ 節(jié)點(diǎn)可以組成一個(gè)集群,也可以根據(jù)實(shí)際業(yè)務(wù)情況動(dòng)態(tài)地?cái)U(kuò)展集群中節(jié)點(diǎn)
高可用性:隊(duì)列可以在集群中的機(jī)器上設(shè)置鏡像,使得在部分節(jié)點(diǎn)出現(xiàn)問(wèn)題的情況下隊(duì)仍然可用
多種協(xié)議:RabbitMQ 除了原生支持 AMQP 協(xié)議,還支持 STOMP,MQTT 等多種消息中間件協(xié)議
多語(yǔ)言客戶端:RabbitMQ 幾乎支持所有常用語(yǔ)言,比如 Java、Python、Ruby、PHP、C#、JavaScript 等
管理界面:RabbitMQ 提供了易用的用戶界面,使得用戶可以監(jiān)控和管理消息、集群中的節(jié)點(diǎn)等
插件機(jī)制:RabbitMQ 提供了許多插件,以實(shí)現(xiàn)從多方面進(jìn)行擴(kuò)展,當(dāng)然也可以編寫自己的插件
應(yīng)用
本章將會(huì)集成 rabbitmq 到 SpringBoot 中,并使用 rabbitmq-provider (生產(chǎn)者)和 rabbitmq-consumer(消費(fèi)者) 兩個(gè)項(xiàng)目進(jìn)行具體講解, 也可以在父項(xiàng)目中創(chuàng)建這兩個(gè)模塊(本文采用父子模塊方式)
所有代碼示例已經(jīng)上傳到 GitHub 倉(cāng)庫(kù)
倉(cāng)庫(kù)地址:ReturnTmp/rabbitmq-demo: rabbitmq 實(shí)例代碼 (github.com)
生產(chǎn)者
配置
創(chuàng)建子模塊 rabbitmq-provider
依賴配置(也可以 IDEA 初始化模塊直接勾選)
<!--rabbitmq-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
application.yml
server:
port: 8021
spring:
application:
name: rabbitmq-provider
rabbitmq:
host: 127.0.0.1
port: 5672
username: root
password: 111111
virtual-host: RootHost
其中虛擬 host 配置項(xiàng)不是必須的,需要自行創(chuàng)建 vhost,如果未自行創(chuàng)建,默認(rèn)為 virtual-host: /
注:vhost 可以理解為虛擬 broker,即 mini-RabbitMQ?server,其內(nèi)部均含有獨(dú)立的 queue、bind、exchange 等,最重要的是擁有獨(dú)立的權(quán)限系統(tǒng),可以做到 vhost 范圍內(nèi)的用戶控制。當(dāng)然,從 RabbitMQ 全局角度,vhost 可以作為不同權(quán)限隔離的手段
可以按照如下步驟創(chuàng)建 vhost
然后創(chuàng)建用戶(管理員)
然后我們需要為用戶分配權(quán)限,指定使用我們剛剛創(chuàng)建的 vhost
代碼
創(chuàng)建直連交換機(jī)配置類
注:RabbitMQ 共有四種交換機(jī),分別為:直連交換機(jī),扇形交換機(jī),主題交換機(jī),首部交換機(jī)。這里使用直連交換機(jī)演示,其他讀者可以自行嘗試
@Configuration
public class DirectRabbitConfig {
//隊(duì)列 起名:TestDirectQueue
@Bean
public Queue TestDirectQueue() {
// durable:是否持久化,默認(rèn)是false,持久化隊(duì)列:會(huì)被存儲(chǔ)在磁盤上,當(dāng)消息代理重啟時(shí)仍然存在,暫存隊(duì)列:當(dāng)前連接有效
// exclusive:默認(rèn)也是false,只能被當(dāng)前創(chuàng)建的連接使用,而且當(dāng)連接關(guān)閉后隊(duì)列即被刪除。此參考優(yōu)先級(jí)高于durable
// autoDelete:是否自動(dòng)刪除,當(dāng)沒(méi)有生產(chǎn)者或者消費(fèi)者使用此隊(duì)列,該隊(duì)列會(huì)自動(dòng)刪除。
// return new Queue("TestDirectQueue",true,true,false);
//一般設(shè)置一下隊(duì)列的持久化就好,其余兩個(gè)就是默認(rèn)false
return new Queue("TestDirectQueue", true);
}
//Direct交換機(jī) 起名:TestDirectExchange
@Bean
DirectExchange TestDirectExchange() {
// return new DirectExchange("TestDirectExchange",true,true);
return new DirectExchange("TestDirectExchange", true, false);
}
//綁定 將隊(duì)列和交換機(jī)綁定, 并設(shè)置用于匹配鍵:TestDirectRouting
@Bean
Binding bindingDirect() {
return BindingBuilder.bind(TestDirectQueue()).to(TestDirectExchange()).with("TestDirectRouting");
}
@Bean
DirectExchange lonelyDirectExchange() {
return new DirectExchange("lonelyDirectExchange");
}
}
然后寫簡(jiǎn)單的接口進(jìn)行消息推送(可以視情況寫為定時(shí)任務(wù))
@RestController
public class SendMessageController {
@Autowired
RabbitTemplate rabbitTemplate; //使用RabbitTemplate,這提供了接收/發(fā)送等等方法
@GetMapping("/sendDirectMessage")
public String sendDirectMessage() {
String messageId = String.valueOf(UUID.randomUUID());
String messageData = "test message, hello!";
String createTime = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
Map<String, Object> map = new HashMap<>();
map.put("messageId", messageId);
map.put("messageData", messageData);
map.put("createTime", createTime);
//將消息攜帶綁定鍵值:TestDirectRouting 發(fā)送到交換機(jī)TestDirectExchange
rabbitTemplate.convertAndSend("TestDirectExchange", "TestDirectRouting", map);
return "ok";
}
}
啟動(dòng)項(xiàng)目,調(diào)用接口: http://localhost:8021/sendDirectMessage
查看 RabbitMQ 管理頁(yè)面查看是否推送成功
消費(fèi)者
配置
創(chuàng)建子模塊 rabbitmq-consumer
依賴配置
<!--rabbitmq-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
application.yml
server:
port: 8022
spring:
application:
name: rabbitmq-consumer
rabbitmq:
host: 127.0.0.1
port: 5672
username: root
password: 111111
virtual-host: RootHost
代碼
創(chuàng)建消息接收監(jiān)聽(tīng)類
@Component
@RabbitListener(queues = "TestDirectQueue")
public class DirectReceiver {
@RabbitHandler
public void process(Map testMessage) {
System.out.println("DirectReceiver receive message: " + testMessage.toString());
}
}
之后啟動(dòng)項(xiàng)目,查看消費(fèi)者接收情況
序列化
發(fā)送接收消息可能出現(xiàn) Failed to convert message
問(wèn)題,可以通過(guò)使用 JSON 序列化傳輸信息方式解決
生產(chǎn)者
@Configuration
public class RabbitMQConfig implements InitializingBean {
/**
* 自動(dòng)注入RabbitTemplate模板
*/
@Resource
private RabbitTemplate rabbitTemplate;
/**
* 發(fā)送消息JSON序列化
*/
@Override
public void afterPropertiesSet() {
//使用JSON序列化
rabbitTemplate.setMessageConverter(new Jackson2JsonMessageConverter());
}
}
消費(fèi)者
@Configuration
public class RabbitMQConfig {
@Bean
public MessageConverter jsonMessageConverter(ObjectMapper objectMapper) {
return new Jackson2JsonMessageConverter(objectMapper);
}
}
徹底卸載
我們安裝中可能出現(xiàn)各種問(wèn)題,一般情況下是 RabbitMQ 和 Erlang 版本不對(duì)應(yīng),需要完全卸載 RabbitMQ 和 Erlang,可以按照如下步驟卸載
注:博主首次安裝使用的是 Erlang 20.3 Rabbit 3.7.15 ,之后似乎小版本不對(duì)應(yīng),出現(xiàn)問(wèn)題,需要重新卸載安裝
(1)打開(kāi) Windows 控制面板,雙擊“程序和功能”。
(2)在當(dāng)前安裝的程序列表中,右鍵單擊 RabbitMQ Server,然后單擊“卸載”。
(3)在當(dāng)前安裝的程序列表中,右鍵單擊“Erlang OTP”,然后單擊“卸載”。
(4)打開(kāi) Windows 任務(wù)管理器。
(5)在任務(wù)管理器中,查找進(jìn)程 epmd.exe。 如果此進(jìn)程仍在運(yùn)行,請(qǐng)右鍵單擊該進(jìn)程,然后單擊“結(jié)束進(jìn)程”。
(6)刪除 RabbitMQ 和 Erlang 的所有安裝目錄。
(7)刪除文件 C:\Windows\System32\config\systemprofile.erlang.cookie
(如果存在)。
(8)轉(zhuǎn)到用戶文件夾:C:\Users\[username]
,然后刪除文件.erlang.cookie。
(9)同樣在 User 文件夾中,轉(zhuǎn)到 AppData \ Roaming \ RabbitMQ
。刪除 RabbitMQ 文件夾。
(10)刪除注冊(cè)表 HKEY_LOCAL_MACHINE\SOFTWARE\Ericsson\Erlang\ErlSrv
的子項(xiàng)。
(11)打開(kāi)運(yùn)行 cmd->sc delete RabbitMQ。
(12)打開(kāi)運(yùn)行->regedit 找到 RabbitMQ 節(jié)點(diǎn),刪掉即可(如果存在)文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-751459.html
參考鏈接
- Windows 下安裝 RabbitMQ 服務(wù)器及基本配置 - 藍(lán)之風(fēng) - 博客園 (cnblogs.com)
- RabbitMQ Windows 安裝、配置、使用 - 小白教程-阿里云開(kāi)發(fā)者社區(qū) (aliyun.com)
- Windows 如何完全卸載 RabbitMQ 和 Erlang 刪除注冊(cè)表
- windows 下 Erlang 與 RabbitMQ 重新安裝時(shí),由于卸載不干凈導(dǎo)致各類錯(cuò)誤
- 超詳細(xì)的 RabbitMQ 入門,看這篇就夠了!-阿里云開(kāi)發(fā)者社區(qū) (aliyun.com)
- RabbitMQ 整合 Spring Boot,實(shí)現(xiàn) Hello World
- Springboot 整合 RabbitMq ,用心看完這一篇就夠了
- RabbitMq 核心知識(shí)點(diǎn)小結(jié) - 知乎 (zhihu.com)
- RabbitMQ消費(fèi)消息坑:failed to convert serialized Message content - jiuchengi
本文由博客一文多發(fā)平臺(tái) OpenWrite 發(fā)布!文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-751459.html
到了這里,關(guān)于『RabbitMQ』入門指南(安裝,配置,應(yīng)用)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!