1. 中間件下載
官網上直接下載,比較簡單就不贅述!
2. 簡介
2.1. RocketMQ是什么
RocketMQ
是一個隊列模型的消息中間件,具有高性能、高可靠、高實時、分布式特點,具體特性如下:
- Producer、Consumer、隊列都可以分布式。
- Producer 向隊列輪流發送消息,隊列集合稱為Topic,Consumer 如果做廣播消費,則一個consumer實例消費這個Topic對應的所有隊列,如果做集群消費,則多個Consumer 實例平均消費這個topic 對應的隊列集合。
- 能夠保證嚴格的消息順序
- 提供豐富的消息拉取模式
- 高效的訂閱者水平擴展能力
- 實時的消息訂閱機制
- 億級消息堆積能力
- 較少的依賴
2.2. 概念
2.2.1. 消息模型(Message Model)
RocketMQ主要由 Producer、Broker、Consumer 三部分組成,其中Producer 負責生產消息,Consumer 負責消費消息,Broker 負責存儲消息。Broker 在實際部署過程中對應一臺服務器,每個 Broker 可以存儲多個Topic的消息,每個Topic的消息也可以分片存儲于不同的 Broker。Message Queue 用于存儲消息的物理地址,每個Topic中的消息地址存儲于多個 Message Queue 中。ConsumerGroup 由多個Consumer 實例構成。
2.2.2. 消息生產者(Producer)
負責生產消息,一般由業務系統負責生產消息。一個消息生產者會把業務應用系統里產生的消息發送到broker服務器。RocketMQ提供多種發送方式,同步發送、異步發送、順序發送、單向發送。同步和異步方式均需要Broker返回確認信息,單向發送不需要。
2.2.3. 消息消費者(Consumer)
負責消費消息,一般是后臺系統負責異步消費。一個消息消費者會從Broker服務器拉取消息、并將其提供給應用程序。從用戶應用的角度而言提供了兩種消費形式:拉取式消費、推動式消費。
2.2.4. 主題(Topic)
表示一類消息的集合,每個主題包含若干條消息,每條消息只能屬于一個主題,是RocketMQ進行消息訂閱的基本單位。
2.2.5. 名字服務(Name Server)
名稱服務充當路由消息的提供者。生產者或消費者能夠通過名字服務查找各主題相應的Broker IP列表。多個Namesrv實例組成集群,但相互獨立,沒有信息交換。
2.2.6. 拉取式消費(Pull Consumer)
Consumer消費的一種類型,應用通常主動調用Consumer的拉消息方法從Broker服務器拉消息、主動權由應用控制。一旦獲取了批量消息,應用就會啟動消費過程。
2.2.7. 推動式消費(Push Consumer)
Consumer消費的一種類型,該模式下Broker收到數據后會主動推送給消費端,該消費模式一般實時性較高。
2.2.8. 生產者組(Producer Group)
同一類Producer的集合,這類Producer發送同一類消息且發送邏輯一致。如果發送的是事務消息且原始生產者在發送之后崩潰,則Broker服務器會聯系同一生產者組的其他生產者實例以提交或回溯消費。
2.2.9. 消費者組(Consumer Group)
同一類Consumer的集合,這類Consumer通常消費同一類消息且消費邏輯一致。消費者組使得在消息消費方面,實現負載均衡和容錯的目標變得非常容易。要注意的是,消費者組的消費者實例必須訂閱完全相同的Topic。RocketMQ 支持兩種消息模式:集群消費(Clustering)和廣播消費(Broadcasting)。
2.2.10. 普通順序消息(Normal Ordered Message)
普通順序消費模式下,消費者通過同一個消費隊列收到的消息是有順序的,不同消息隊列收到的消息則可能是無順序的。
2.2.11. 嚴格順序消息(Strictly Ordered Message)
嚴格順序消息模式下,消費者收到的所有消息均是有順序的。
2.3. 架構設計
2.3.1. 技術架構
2.3.2. 部署架構
3. 安裝
由于RocketMQ安裝比較簡單,在單機這塊就省略。
3.1. 單機
略!!!!
3.2. 集群
3.2.1. 集群的方式
單 Master:這種方式風險較大,一旦Broker重啟或者宕機時,會導致整個服務不可用,不建議線上環境使用。
-
多 Master 模式:一個集群無 Slave,全是 Master,例如 2 個 Master 或者 3 個 Master
優點:配置簡單,單個Master 宕機或重啟維護對應用無影響,在磁盤配置為 RAID10 時,即使機器宕機不可恢復情況下,由與 RAID10磁盤非常可靠,消息也不會丟(異步刷盤丟失少量消息,同步刷盤一條不丟)。性能最高。
缺點:單臺機器宕機期間,這臺機器上未被消費的消息在機器恢復之前不可訂閱,消息實時性會受到受到影響。
-
多 Master 多 Slave 模式,異步復制:每個 Master 配置一個 Slave,有多對Master-Slave,HA
采用異步復制方式,主備有短暫消息延遲,毫秒級。優點:即使磁盤損壞,消息丟失的非常少,且消息實時性不會受影響,因為Master 宕機后,消費者仍然可以從 Slave。
缺點:Master 宕機,磁盤損壞情況,會丟失少量消息。
-
多 Master 多 Slave 模式,同步雙寫:每個 Master 配置一個 Slave,有多對Master-Slave,HA
采用同步雙寫方式,主備都寫成功,向應用返回成功。優點:數據與服務都無單點,Master宕機情況下,消息無延遲,服務可用性與數據可用性都非常高。
缺點:性能比異步復制模式略低,大約低 10%左右,發送單個消息的 RT 會略高。目前主宕機后,備機不能自動切換為主機,后續會支持自動切換功能
后兩種的方式比較復雜,涉及主從同步的問題,非必要的場景,建議采用多Master 這種方式。而我下面的例子也是以 多Master來部署的。
3.2.2. 部署
- 服務器環境準備
序號 | IP | 角色 | 模式 |
---|---|---|---|
A | 192.168.244.128 | nameServer1,brokerServer1 | Master1 |
B | 192.168.244.129 | nameServer2,brokerServer2 | Master2 |
- 修改HOST
在 A、B 兩服務器中將HOST文件修改,vi /etc/hosts
修改內容如下:
192.168.244.128 rocketmq-nameserver1
192.168.244.128 rocketmq-master1
192.168.244.129 rocketmq-nameserver2
192.168.244.129 rocketmq-master2
- 上傳文件
在A、B兩臺機器上傳RockerMQ文件,并解壓。我這里上傳和解壓路徑在/usr/local
[root@centos8 rocketmq]$ pwd
/usr/local/rocketmq
[root@centos8 rocketmq]$ ll
total 40
drwxr-xr-x. 2 root root 83 Jun 24 02:49 benchmark
drwxr-xr-x. 3 root root 4096 Jun 24 02:02 bin
drwxr-xr-x. 6 root root 211 Jun 2 02:09 conf
drwxr-xr-x. 2 root root 4096 Jun 24 02:49 lib
-rw-r--r--. 1 root root 17336 Jun 2 02:09 LICENSE
-rw-r--r--. 1 root root 1338 Jun 2 02:09 NOTICE
-rw-r--r--. 1 root root 5069 Jun 24 02:02 README.md
[root@centos8 rocketmq]$
- 創建存儲路徑
在A、B兩臺機器執行創建路徑。
[root@centos8 rocketmq]$ mkdir /usr/local/rocketmq/store
[root@centos8 rocketmq]$ mkdir /usr/local/rocketmq/store/commitlog
[root@centos8 rocketmq]$ mkdir /usr/local/rocketmq/store/consumequeue
[root@centos8 rocketmq]$ mkdir /usr/local/rocketmq/store/index
- 修改配置文件
這里貼一個標準配置文件,具體如下:
// 所屬集群名字
brokerClusterName=rocketmq-cluster
// broker名字,注意此處不同的配置文件填寫的不一樣
brokerName=broker-a/broker-b ## 需要按機器A/B 區分
// 0 表示 Master,>0 表示 Slave
brokerId=0
// nameServer地址,分號分割
namesrvAddr=rocketmq-nameserver1:9876;rocketmq-nameserver2:9876
// 在發送消息時,自動創建服務器不存在的topic,默認創建的隊列數
defaultTopicQueueNums=4
// 是否允許 Broker 自動創建Topic,建議線下開啟,線上關閉
autoCreateTopicEnable=true
// 是否允許 Broker 自動創建訂閱組,建議線下開啟,線上關閉
autoCreateSubscriptionGroup=true
// Broker 對外服務的監聽端口
listenPort=10911
// 刪除文件時間點,默認凌晨 4點
deleteWhen=04
// 文件保留時間,默認 48 小時
fileReservedTime=120
// commitLog每個文件的大小默認1G
mapedFileSizeCommitLog=1073741824
// ConsumeQueue每個文件默認存30W條,根據業務情況調整
mapedFileSizeConsumeQueue=300000
// destroyMapedFileIntervalForcibly=120000
// redeleteHangedFileInterval=120000
// 檢測物理文件磁盤空間
diskMaxUsedSpaceRatio=88
// 存儲路徑
storePathRootDir=/usr/local/rocketmq/store
// commitLog 存儲路徑
storePathCommitLog=/usr/local/rocketmq/store/commitlog
// 消費隊列存儲路徑存儲路徑
storePathConsumeQueue=/usr/local/rocketmq/store/consumequeue
// 消息索引存儲路徑
storePathIndex=/usr/local/rocketmq/store/index
// checkpoint 文件存儲路徑
storeCheckpoint=/usr/local/rocketmq/store/checkpoint
// abort 文件存儲路徑
abortFile=/usr/local/rocketmq/store/abort
// 限制的消息大小
maxMessageSize=65536
// flushCommitLogLeastPages=4
// flushConsumeQueueLeastPages=2
// flushCommitLogThoroughInterval=10000
// flushConsumeQueueThoroughInterval=60000
// Broker 的角色
// - ASYNC_MASTER 異步復制Master
// - SYNC_MASTER 同步雙寫Master
// - SLAVE
brokerRole=ASYNC_MASTER
// 刷盤方式
// - ASYNC_FLUSH 異步刷盤
// - SYNC_FLUSH 同步刷盤
flushDiskType=ASYNC_FLUSH
// checkTransactionMessageEnable=false
// 發消息線程池數量
// sendMessageThreadPoolNums=128
// 拉消息線程池數量
// pullMessageThreadPoolNums=128
機器A
[root@centos8 rocketmq]$ vi/usr/local/rocketmq/conf/2m-noslave/broker-a.properties
其中brokerName=broker-a
在機器B
[root@centos8 rocketmq]$ vi/usr/local/rocketmq/conf/2m-noslave/broker-a.properties
其中brokerName=broker-b
- 修改日志配置文件
不用說肯定也是A、B兩臺都要改
[root@centos8 rocketmq]$ mkdir -p /usr/local/rocketmq/logs
[root@centos8 rocketmq]$ cd /usr/local/rocketmq/conf && sed -i 's#${user.home}#/usr/local/rocketmq#g' *.xml
- 修改啟動參數(A、B)
在/usr/local/rocketmq/bin
路徑下,找到runbroker.sh
和 runserver.sh
。
我們將這兩個文件的JAVA_OPT
參數修改下,不然默認情況下,JVM配置是 8G
。如 JAVA_OPT="${JAVA_OPT} -server -Xms8g -Xmx8g -Xmn4g"
。
修改后:
...
JAVA_OPT="${JAVA_OPT} -server -Xms1g -Xmx1g -Xmn512m"
....
- 啟動NameServer(A、B)
[root@centos8 rocketmq]$ cd /usr/local/rocketmq/bin
[root@centos8 rocketmq]$ nohup sh mqnamesrv &
- 啟動BrokerServer(A)
[root@centos8 rocketmq]$ cd /usr/local/rocketmq/bin
[root@centos8 rocketmq]$ nohup sh mqbroker -c /usr/local/rocketmq/conf/2m-noslave/broker-a.properties &
- 啟動BrokerServer(B)
[root@centos8 rocketmq]$ cd /usr/local/rocketmq/bin
[root@centos8 rocketmq]$ nohup sh mqbroker -c /usr/local/rocketmq/conf/2m-noslave/broker-b.properties &
- rocketmq-console安裝
這個包需要利用maven編譯打包。我這里打包一個,放百度云盤上,供下載!
鏈接: https://pan.baidu.com/s/1hfvzJeyBG7TXnvPHtn3C5Q
提取碼: atkq
最后執行jar文件
[root@centos8 rocketmq]$ java -jar rocketmq-console-ng-1.0.0.jar
頁面的端口是 8082,剛開始啟動有點慢,稍微等會!!
- 數據清理
[root@centos8 rocketmq]$ cd /usr/local/rocketmq/bin
[root@centos8 rocketmq]$ sh mqshutdown broker
[root@centos8 rocketmq]$ sh mqshutdown namesrv
這里需要等待完全停止!
[root@centos8 rocketmq]$ rm -rf /usr/local/rocketmq/store
[root@centos8 rocketmq]$ mkdir /usr/local/rocketmq/store
[root@centos8 rocketmq]$ mkdir /usr/local/rocketmq/store/commitlog
[root@centos8 rocketmq]$ mkdir /usr/local/rocketmq/store/consumequeue
[root@centos8 rocketmq]$ mkdir /usr/local/rocketmq/store/index
最終按照以上步驟重啟NameServer和BrokerServer即可!
4. SpringBoot集成
- POM文件添加依賴
<dependency>
<groupId>org.apache.rocketmq</groupId>
<artifactId>rocketmq-spring-boot-starter</artifactId>
<version>{換成相應版本}</version>
</dependency>
- application.yml
######### 4.1. RocketMQ ##########
rocketmq:
name-server: 192.168.244.128:9876;192.168.244.129:9876;
producer:
group: drunkard
send-message-timeout: 30000
- 生產者
@Slf4j
@RestController
public class RocketMqDemo {
@Autowired
RocketMQTemplate rocketMQTemplate;
@GetMapping("send/{id}")
public String send(@PathVariable("id") String id){
UserVo userVo = new UserVo(id,"侯征");
log.warn(JSON.toJSONString(userVo));
rocketMQTemplate.send("rocket-topic-01", MessageBuilder.withPayload(userVo).build());
return "SUCESS";
}
}
- 消費者
@Slf4j
@Component
@RocketMQMessageListener(topic = "rocket-topic-01", consumerGroup = "my-rocket-topic-01")
public class UserConsumer implements RocketMQListener<UserVo> {
@Override
public void onMessage(UserVo message) {
log.warn("接受到消息: {}",message.toString());
}
}
5. 案例下載
Gitee下載,希望多多給Star。
Github下載,希望多多給Star。