一、環境准備
1、補充
如果單機都不會安裝網站
https://blog.csdn.net/ctwctw/article/details/107143968
再次強調,如果單機都不會的話,先抽出2min看看上面文章,因為需要改jvm配置的,默認8G,沒那么大的內存啟動會報錯的。
2、機器
機器 | 用途 |
---|---|
172.17.160.28 | namesrv、broker-a-master、broker-b-slave |
172.17.160.29 | namesrv、broker-b-master、broker-a-slave |
兩台機器分別啟動namesrv
172.17.160.28和172.17.160.29交叉作為彼此的slave
二、開始搭建
搭建2M2S SYNC。
1、說明
Rocket MQ在4.5.0之前版本支持的主從不支持自動切換,也就是並非真正意義上的高可用,比如2M2S,其中1個M掛了后,他的Slave節點不會自動升級為Master,但是在4.5.0開始迎來了Dledger這個“怪物”,他是基於raft的(Redis的哨兵也是這個玩意),讓Rocket MQ真正意義的做到了高可用,Master掛了后Slave自動升級為Master,完全自動,釋放雙手。
2、古老的集群搭建
2.1、准備
進入到2m2s-sync目錄
cd /home/chentongwei/rocketmq/rocketmq-all-4.7.0-bin-release/conf/2m-2s-sync
2.2、Master1
也就是172.17.160.28機器上的broker-a-master節點。
修改其配置文件然后啟動即可。
vi broker-a.properties
修改內容如下:
#所屬集群名字 brokerClusterName=rocketmq-cluster #broker名字,需要注意的是slave節點需要和master節點的brokerName一致,區分m還是s交由下面的brokerId來配置。 brokerName=broker-a #0 表示 Master,>0 表示 Slave brokerId=0 #nameServer地址,分號分割 namesrvAddr=172.17.160.28:9876;172.17.160.29: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 #存儲路徑 storePathRootDir=/home/chentongwei/data/rocketmq/broker-a/store #commitLog 存儲路徑 storePathCommitLog=/home/chentongwei/data/rocketmq/broker-a/store/commitlog #消費隊列存儲路徑存儲路徑 storePathConsumeQueue=/home/chentongwei/data/rocketmq/broker-a/store/consumequeue #消息索引存儲路徑 storePathIndex=/home/chentongwei/data/rocketmq/broker-a/store/index #checkpoint 文件存儲路徑 storeCheckpoint=/home/chentongwei/data/rocketmq/broker-a/store/checkpoint #abort 文件存儲路徑 abortFile=/home/chentongwei/data/rocketmq/broker-a/store/abort #限制的消息大小 maxMessageSize=65536 #Broker 的角色 #- ASYNC_MASTER 異步復制Master #- SYNC_MASTER 同步雙寫Master #- SLAVE brokerRole=SYNC_MASTER #刷盤方式 #- ASYNC_FLUSH 異步刷盤 #- SYNC_FLUSH 同步刷盤 flushDiskType=SYNC_FLUSH
2.3、Slave1
也就是172.17.160.29機器上的broker-a-slave節點。
修改其配置文件然后啟動即可。
vi broker-a-s.properties
修改內容如下:
#所屬集群名字 brokerClusterName=rocketmq-cluster #broker名字,需要注意的是slave節點需要和master節點的brokerName一致,區分m還是s交由下面的brokerId來配置。 brokerName=broker-a #0 表示 Master,>0 表示 Slave # 注意此處是1了,不在是0了,因為0代表Master brokerId=1 #nameServer地址,分號分割 namesrvAddr=172.17.160.28:9876;172.17.160.29:9876 #在發送消息時,自動創建服務器不存在的topic,默認創建的隊列數 defaultTopicQueueNums=4 #是否允許 Broker 自動創建Topic,建議線下開啟,線上關閉 autoCreateTopicEnable=true #是否允許 Broker 自動創建訂閱組,建議線下開啟,線上關閉 autoCreateSubscriptionGroup=true #Broker 對外服務的監聽端口 listenPort=11911 #刪除文件時間點,默認凌晨 4點 deleteWhen=04 #文件保留時間,默認 48 小時 fileReservedTime=120 #commitLog每個文件的大小默認1G mapedFileSizeCommitLog=1073741824 #ConsumeQueue每個文件默認存30W條,根據業務情況調整 mapedFileSizeConsumeQueue=300000 #存儲路徑 storePathRootDir=/home/chentongwei/data/rocketmq/broker-a/store #commitLog 存儲路徑 storePathCommitLog=/home/chentongwei/data/rocketmq/broker-a/store/commitlog #消費隊列存儲路徑存儲路徑 storePathConsumeQueue=/home/chentongwei/data/rocketmq/broker-a/store/consumequeue #消息索引存儲路徑 storePathIndex=/home/chentongwei/data/rocketmq/broker-a/store/index #checkpoint 文件存儲路徑 storeCheckpoint=/home/chentongwei/data/rocketmq/broker-a/store/checkpoint #abort 文件存儲路徑 abortFile=/home/chentongwei/data/rocketmq/broker-a/store/abort #限制的消息大小 maxMessageSize=65536 #Broker 的角色 #- ASYNC_MASTER 異步復制Master #- SYNC_MASTER 同步雙寫Master #- SLAVE brokerRole=SLAVE #刷盤方式 #- ASYNC_FLUSH 異步刷盤 #- SYNC_FLUSH 同步刷盤 flushDiskType=ASYNC_FLUSH
2.4、Master2
也就是172.17.160.29機器上的broker-b-master節點。
修改其配置文件然后啟動即可。
vi broker-b.properties
修改內容如下:
#所屬集群名字 brokerClusterName=rocketmq-cluster #broker名字,需要注意的是slave節點需要和master節點的brokerName一致,區分m還是s交由下面的brokerId來配置。 brokerName=broker-b #0 表示 Master,>0 表示 Slave brokerId=0 #nameServer地址,分號分割 namesrvAddr=172.17.160.28:9876;172.17.160.29: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 #存儲路徑 storePathRootDir=/home/chentongwei/data/rocketmq/broker-b/store #commitLog 存儲路徑 storePathCommitLog=/home/chentongwei/data/rocketmq/broker-b/store/commitlog #消費隊列存儲路徑存儲路徑 storePathConsumeQueue=/home/chentongwei/data/rocketmq/broker-b/store/consumequeue #消息索引存儲路徑 storePathIndex=/home/chentongwei/data/rocketmq/broker-b/store/index #checkpoint 文件存儲路徑 storeCheckpoint=/home/chentongwei/data/rocketmq/broker-b/store/checkpoint #abort 文件存儲路徑 abortFile=/home/chentongwei/data/rocketmq/broker-b/store/abort #限制的消息大小 maxMessageSize=65536 #Broker 的角色 #- ASYNC_MASTER 異步復制Master #- SYNC_MASTER 同步雙寫Master #- SLAVE brokerRole=SYNC_MASTER #刷盤方式 #- ASYNC_FLUSH 異步刷盤 #- SYNC_FLUSH 同步刷盤 flushDiskType=SYNC_FLUSH
2.5、Slave2
也就是172.17.160.28機器上的broker-b-slave節點。
修改其配置文件然后啟動即可。
vi broker-b-s.properties
修改內容如下:
#所屬集群名字 brokerClusterName=rocketmq-cluster #broker名字,需要注意的是slave節點需要和master節點的brokerName一致,區分m還是s交由下面的brokerId來配置。 brokerName=broker-b #0 表示 Master,>0 表示 Slave # 注意此處是1了,不在是0了,因為0代表Master brokerId=1 #nameServer地址,分號分割 namesrvAddr=172.17.160.28:9876;172.17.160.29:9876 #在發送消息時,自動創建服務器不存在的topic,默認創建的隊列數 defaultTopicQueueNums=4 #是否允許 Broker 自動創建Topic,建議線下開啟,線上關閉 autoCreateTopicEnable=true #是否允許 Broker 自動創建訂閱組,建議線下開啟,線上關閉 autoCreateSubscriptionGroup=true #Broker 對外服務的監聽端口 listenPort=11911 #刪除文件時間點,默認凌晨 4點 deleteWhen=04 #文件保留時間,默認 48 小時 fileReservedTime=120 #commitLog每個文件的大小默認1G mapedFileSizeCommitLog=1073741824 #ConsumeQueue每個文件默認存30W條,根據業務情況調整 mapedFileSizeConsumeQueue=300000 #存儲路徑 storePathRootDir=/home/chentongwei/data/rocketmq/broker-b/store #commitLog 存儲路徑 storePathCommitLog=/home/chentongwei/data/rocketmq/broker-b/store/commitlog #消費隊列存儲路徑存儲路徑 storePathConsumeQueue=/home/chentongwei/data/rocketmq/broker-b/store/consumequeue #消息索引存儲路徑 storePathIndex=/home/chentongwei/data/rocketmq/broker-b/store/index #checkpoint 文件存儲路徑 storeCheckpoint=/home/chentongwei/data/rocketmq/broker-b/store/checkpoint #abort 文件存儲路徑 abortFile=/home/chentongwei/data/rocketmq/broker-b/store/abort #限制的消息大小 maxMessageSize=65536 #Broker 的角色 #- ASYNC_MASTER 異步復制Master #- SYNC_MASTER 同步雙寫Master #- SLAVE brokerRole=SLAVE #刷盤方式 #- ASYNC_FLUSH 異步刷盤 #- SYNC_FLUSH 同步刷盤 flushDiskType=ASYNC_FLUSH
2.6、總結
其實就是如下幾個關鍵配置需要注意:
-
brokerClusterName:集群名稱,所有broker配置的必須一致
-
brokerName:broker名稱,M-S之間必須一致,比如broker-a/broker-a(M/S),broker-b/broker-b
-
brokerId:0 表示 Master,>0 表示 Slave,比如1M2S,那么M是0,Slave1是1,Slave2配置為2
-
namesrvAddr:namesrv地址
-
store*:持久化數據存儲目錄
-
brokerRole:Broker的角色
-
flushDiskType:刷盤方式,2m2s-sync中,master默認為SYNC_FLUSH,slave默認為ASYNC_FLUSH
2.7、啟動
2.7.1、啟動namesrv
cd /home/chentongwei/rocketmq/rocketmq-all-4.7.0-bin-release/bin nohup sh mqnamesrv &
兩台機器都要啟動。
2.7.2、啟動broker
172.17.160.28
cd /home/chentongwei/rocketmq/rocketmq-all-4.7.0-bin-release/bin # 啟動Master1 nohup sh mqbroker -c /home/chentongwei/rocketmq/rocketmq-all-4.7.0-bin-release/conf/2m-2s-sync/broker-a.properties & # 啟動Slave2 nohup sh mqbroker -c /home/chentongwei/rocketmq/rocketmq-all-4.7.0-bin-release/conf/2m-2s-sync/broker-b-s.properties &
172.17.160.29
cd /home/chentongwei/rocketmq/rocketmq-all-4.7.0-bin-release/bin # 啟動Master2 nohup sh mqbroker -c /home/chentongwei/rocketmq/rocketmq-all-4.7.0-bin-release/conf/2m-2s-sync/broker-b.properties & # 啟動Slave1 nohup sh mqbroker -c /home/chentongwei/rocketmq/rocketmq-all-4.7.0-bin-release/conf/2m-2s-sync/broker-a-s.properties &
2.8、驗證
直接打開我們的管控台進行查看集群(Cluster)
2.9、問題
他致命的問題就是不能自動主備切換,比如我殺死broker-a-master的進程,然后看管控台broker-a-slave是否會自動升級為master,發現並不會。所以我們的Dledger誕生了。
# 找到broker-a-master的進程號是8983 kill -9 8983
3、Dledger搭建
3.1、說明
是基於raft的一種做法,redis的哨兵也是基於raft的,和這個是一樣的道理。上面【古老的集群搭建】方式並不作廢,Dledger就是基於上面的繼續增加額外配置,上面的配置依然保留,繼續追加新的配置即可。Dledger要求機器數必須是3台或3台以上才行。這也是raft的基礎要求。不懂的可以自行Google下raft。
3.2、搭建
3.2.1、官方搭建手冊
https://github.com/apache/rocketmq/blob/master/docs/cn/dledger/deploy_guide.md
3.2.2、准備
我們多開一台虛擬機:172.17.160.30,采取Dledger搭建一組1M2S的集群,機器規划如下:
機器 | 用途 |
---|---|
172.17.160.28 | namesrv、broker-a-master |
172.17.160.29 | namesrv、broker-a-slave1 |
172.17.160.30 | namesrv、broker-a-slave2 |
3.2.3、配置
上面的【古老的集群搭建】配置不變,在每個properties里新增如下配置:
172.17.160.28
enableDLegerCommitLog=true dLegerGroup=broker-a dLegerPeers=n0-172.17.160.28:40911;n1-172.17.160.29:40911;n2-172.17.160.30:40911 dLegerSelfId=n0 sendMessageThreadPoolNums=4
172.17.160.29
enableDLegerCommitLog=true dLegerGroup=broker-a dLegerPeers=n0-172.17.160.28:40911;n1-172.17.160.29:40911;n2-172.17.160.30:40911 dLegerSelfId=n1 sendMessageThreadPoolNums=4
172.17.160.30
enableDLegerCommitLog=true dLegerGroup=broker-a dLegerPeers=n0-172.17.160.28:40911;n1-172.17.160.29:40911;n2-172.17.160.30:40911 dLegerSelfId=n2 sendMessageThreadPoolNums=4
3.2.4、配置說明
name | 含義 | 舉例 |
---|---|---|
enableDLegerCommitLog | 是否啟動 DLedger | true |
dLegerGroup | DLedger Raft Group的名字,建議和 brokerName 保持一致 | broker-a |
dLegerPeers | DLedger Group 內各節點的端口信息,同一個 Group 內的各個節點配置必須要保證一致 | n0-172.17.160.28:40911;n1-172.17.160.29:40911;n2-172.17.160.30:40911 |
dLegerSelfId | 節點 id, 必須屬於 dLegerPeers 中的一個;同 Group 內各個節點要唯一 | n0 |
sendMessageThreadPoolNums=4 | 發送消息的線程數,建議與CPU核數設置成一樣的 | 4 |
3.2.5、啟動
啟動三台的namesrv和三個broker,跟上面姿勢一樣,不重復貼代碼了。
3.2.6、驗證
管控台去看的話應該是1個master,兩個slave,都叫broker-a,這時候停掉master,會發現其中一個slave自動升級為Master了,這才叫真正的高可用,自動主備切換。
3.3、補充
雖然要求至少三台機器,但是沒條件的可以用一台機器去模擬,弄三個不同的端口號就行了。
三、常見問題
1、Lock failed,MQ already started
1.1、錯誤
[root@iZ2ze84zygpzjw5bfcmh2hZ 2m-2s-sync]# sh ../../bin/mqbroker -c broker-b-s.properties java.lang.RuntimeException: Lock failed,MQ already started at org.apache.rocketmq.store.DefaultMessageStore.start(DefaultMessageStore.java:223) at org.apache.rocketmq.broker.BrokerController.start(BrokerController.java:853) at org.apache.rocketmq.broker.BrokerStartup.start(BrokerStartup.java:64) at org.apache.rocketmq.broker.BrokerStartup.main(BrokerStartup.java:58)
1.2、解決
這個是由於沒配置store*導致的,比如如下:
#存儲路徑 storePathRootDir=/home/chentongwei/data/rocketmq/broker-a/store #commitLog 存儲路徑 storePathCommitLog=/home/chentongwei/data/rocketmq/broker-a/store/commitlog #消費隊列存儲路徑存儲路徑 storePathConsumeQueue=/home/chentongwei/data/rocketmq/broker-a/store/consumequeue #消息索引存儲路徑 storePathIndex=/home/chentongwei/data/rocketmq/broker-a/store/index #checkpoint 文件存儲路徑 storeCheckpoint=/home/chentongwei/data/rocketmq/broker-a/store/checkpoint #abort 文件存儲路徑 abortFile=/home/chentongwei/data/rocketmq/broker-a/store/abort
沒配置這個,我一台機器上部署兩個broker,一個broker-a-master,一個broker-b-slave,都采取默認的store*配置,沖突了,所以報錯。所以手動配上不同目錄即可,我這里目錄區分是broker-a/broker-b。
2、AllocateMappedFileService started:false lastThread:null
這個是由於store*配置的都一樣導致的,比如如下:
#存儲路徑 storePathRootDir=/home/chentongwei/data/rocketmq/broker-a/store #commitLog 存儲路徑 storePathCommitLog=/home/chentongwei/data/rocketmq/broker-a/store #消費隊列存儲路徑存儲路徑 storePathConsumeQueue=/home/chentongwei/data/rocketmq/broker-a/store #消息索引存儲路徑 storePathIndex=/home/chentongwei/data/rocketmq/broker-a/store #checkpoint 文件存儲路徑 storeCheckpoint=/home/chentongwei/data/rocketmq/broker-a/store #abort 文件存儲路徑 abortFile=/home/chentongwei/data/rocketmq/broker-a/store
發現了沒?我都用的/home/chentongwei/data/rocketmq/broker-a/store
,這肯定不行的,所以我們需要采用不同目錄,比如store/commitlog
、store/consumequeue
等。
3、Address already in use
這個更神奇了,見名知意,地址被占用了。也就是端口被占用了。我為什么說他更神奇,不是因為我沒配置listenPort,而是我在單台機器上配置了broker-a-master的端口為默認端口10911,broker-b-slave的端口為10912,就是+1操作了。他為啥說我被占用?
經過查源碼發現,他大爺的,他給我默認啟動了一個進程,端口號就是配置的端口+1,所以啟動一個broker后他其實是給我們啟動了兩個端口,一個原端口,一個原端口+1。所以我配置的時候一個是10911,一個是11911,而不能 是10912!!!
#Broker 對外服務的監聽端口 listenPort=11911
源碼如下:
// {@link org.apache.rocketmq.broker.BrokerStartup#createBrokerController(String[])} messageStoreConfig.setHaListenPort(nettyServerConfig.getListenPort() + 1);
4、管控台配置namesrv
如果namesrv和broker都啟動正常后,管控台上還是沒有集群的話,可以檢查下管控台是否配置了namesrv
這個namesrv配置需要手動敲完后+回車+點擊UPDATE才能生效。
2.8、驗證
直接打開我們的管控台進行查看集群(Cluster)