一、rocketmq簡介
- rocketmq是一款分佈式、隊列模型的消息中間件,由阿里巴巴研發借鑑參考了JMS規範MQ實習,更參考了優秀的開源消息中間件kafka,並結合阿里巴巴的實際業務需求,在天貓雙十一的場景,實現業務消峯,分佈式事務的優秀框架。
- 底層代碼編寫清晰優秀,採用Netty NIOl框架實現數據通信。
- 3.X版本棄用Zookeeper,內部使用更輕量級的NameServer進行網絡路由,提供了服務性能,並支持消息失敗重試機制。
- 支持集羣模式、消費者負載均衡、水平擴展能力,支持廣播模式。
- 採用零拷貝原理,順序寫盤、支持億級消息堆積能力。
- 提供豐富的消息機制,比如順序消息、事務消息。
二、核心概念講解
1.專業術語
- Producer: 消息生成者,負責消息產生,由業務系統負責產生。
- Consumer:消息消費者,負責消費消費,由後臺業務系統負責異步消費。
- Push Consumer:Consumer的一種,應用通常向Consumer對象註冊一個Listener接口,一旦接收到消息,Consumer對象立刻回調Listener接口方法。
- Pull Consumer:Consumer的一種,應用通常主動調用Consumer的拉消息方法從Broker拉消息,主動權由應用控制。
- Producer Group:一類producer的集合名稱,這類Producer通常發送一類消息,且發送邏輯。
- Consumer Group:一類Consumer的集合名稱,這類Consumer通常消費一類消息,且發送邏輯。
- Broker:消息中轉角色,負責存儲消息,轉發消息,一般也稱爲Server。
- 集羣消費:一個Consumer Group中的Consumer實例平均分攤消費消息。例如某個Topic有9條消息,其中一個Consumer Group有3個 實例(可能是3個進程或3臺機器),那麼每隔實例只消費其中的3條消費。
- 廣播消費:一條消息被多個Consumer消息,即使這些 Consumer屬於同一個 Consumer Group,消息也會被Consumer Group中的每隔 Consumer都消費一次。
- 順序消費:指消息的消費順序和產生順序相同,在有些業務邏輯 下 ,必須保證順序。比如訂單的生成、付款、發貨,這3個消息必須按順序處理才行。
三、rocketmq應用場景
四、rocketmq可視化管理控制檯代建
1. 下載開源的rocketmq-externals項目:https://github.com/apache/rocketmq-externals
2. 找到rocketmq-console,先編輯一下rocketmq-console裏面的application.properties文件,將項目使用的rocketmq.config.namesrvAddr配置上去(或者在項目啓動時,以參數的形式配進去)
server.contextPath=
server.port=8082
#spring.application.index=true
spring.application.name=rocketmq-console
spring.http.encoding.charset=UTF-8
spring.http.encoding.enabled=true
spring.http.encoding.force=true
logging.config=classpath:logback.xml
#if this value is empty,use env value rocketmq.config.namesrvAddr NAMESRV_ADDR | now, you can set it in ops page.default localhost:9876
rocketmq.config.namesrvAddr=127.0.0.1:9876
#if you use rocketmq version < 3.5.8, rocketmq.config.isVIPChannel should be false.default true
rocketmq.config.isVIPChannel=
#rocketmq-console's data path:dashboard/monitor
rocketmq.config.dataPath=/tmp/rocketmq-console/data
#set it false if you don't want use dashboard.default true
rocketmq.config.enableDashBoardCollect=true
3.將rocktmq-console打成jar包,得到rocketmq-console-ng-1.0.0.jar
mvn clean package -Dmaven.test.skip=true
4.運行jar包,啓動項目(在本地可以直接導入項目到IDEA啓動項目),這裏也可以設置rocketmq.config.namesrvAdd
java -jar rocketmq-console-ng-1.0.0.jar --server.port=12581 --rocketmq.config.namesrvAddr=127.0.0.1:9876
5.控制檯界面如下:
6.參考博客 :https://www.cnblogs.com/miaoying/p/10319840.html
五、rocketmq項目搭建
參考官網:http://rocketmq.apache.org/docs/quick-start/
步驟如下:
1.環境:IDEA2019、Maven、JDK1.8(由於Rocketmq項目基於SpringBoot)
2.下載地址:https://www.apache.org/dyn/closer.cgi?path=rocketmq/4.4.0/rocketmq-all-4.4.0-bin-release.zip
3.配置環境變量:
變量名:ROCKETMQ_HOME
變量值:F:\rocketmq-all-4.4.0-bin-release
4.啓動nameserver命令爲: start mqnamesrv.cmd
啓動broker命令爲: start mqbroker.cmd -n 127.0.0.1:9876 autoCreateTopicEnable=true
5.在IDEA中創建Producer和consumer實現消息通信
Demo案例演示
consumer消費者----配置參數
consumer.setConsumeFromWhere(ConsumeFromWhere.CONSUME_FROM_LAST_OFFSET):Consumer啓動後,默認從什麼位置開發消費,默認爲CONSUME_FROM_LAST_OFFSET
consumer.setAllocateMessageQueueStrategy():設置負載均衡算法實現策略
consumer.setSubscription():設置訂閱關係
consumer.setMessageListener():設置消息監聽
consumer.setOffsetStore():設置消息進度存儲
consumer.setConsumeThreadMax():設置消費線程的最大數量,默認爲64個線程
consumer.setConsumeThreadMin():設置消費線程的最小數量,默認爲20個線程
consumer.setPullThresholdForQueue():本地隊列緩存消息最大數,默認爲1000
consumer.setConsumeMessageBatchMaxSize():批量消費消息,一次消費多少條消息,默認爲1條
consumer.setPullBatchSize():批量拉取消息,一次性最多拉取多少條消息,默認爲32條
consumer.setPullInterval():設置消息拉取間隔,默認爲0
consumer端應用
/**
* 源碼分析DefaultMQPushConsumer的處理流程:
* DefaultMQPushConsumer主要功能實現在DefaultMQPushConsumerImpl類中
* 處理消息是在:pullMessage()方法中的PullCallBack()方法中
*/
public class Consumer {
public static void main(String[] args) throws InterruptedException, MQClientException {
/**
* 1.使用消費者組名稱進行實例化(消費者類型:DefaultMQPushConsumer,DefaultMQPullConsumer)
* 2.同一個GroupName下的多個消費者Consumer可以提高併發處理能力,GroupName需要和消息模式(MessageModel)配合使用
* 3.RocketMQ支持兩種消息模式:
* Clusting:一個Consumer只能消費同一個GroupName裏面的一部分消息,從而實現負載均衡
* Broadcasting:一個Consumer可以消費GroupName裏面的所有消息
*/
DefaultMQPushConsumer consumer = new DefaultMQPushConsumer("please_rename_unique_group_name");
/**
* 指定nameserver的地址和端口號,可以填寫多個使用分號隔開。例如:172.22.41.203;172.21.42.204:9876
* 達到消除單點故障
*/
consumer.setNamesrvAddr("localhost:9876");
/**
* 消費者訂閱消費主題,可以訂閱一個或多個,"null"或"*"表示訂閱多個主題
* consumer.subscribe("TopicTest", "tag1||tag2||tagn");
*/
consumer.subscribe("TopicTest", "*");
// Register callback to execute on arrival of messages fetched from brokers.
consumer.registerMessageListener(new MessageListenerConcurrently() {
@Override
public ConsumeConcurrentlyStatus consumeMessage(List<MessageExt> msgs,
ConsumeConcurrentlyContext context) {
for (MessageExt msg :msgs) {
System.out.println(msg);
}
//System.out.printf("%s Receive New Messages: %s %n", Thread.currentThread().getName(), msgs);
return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
}
});
//啓動消費者
consumer.start();
System.out.printf("Consumer Started.%n");
}
}
producer生產者----配置參數
producer.createTopic():在發送消息時,自動創建服務器不存在的topic,需要指定key
producer.setDefaultTopicQueueNums():在發送消息時,自動創建服務器不存在的topic,默認創建隊列數爲4
producer.send():設置發送消息超時時間,單位爲毫秒
producer.setCompressMsgBodyOverHowmuch():發送消息體超過多大進行壓縮(Consumer收到消息自動壓縮),默認爲1024*4,單位字節
producer.setRetryTimesWhenSendFailed():設置生產者發送消息重試次數,默認重試2次
producer.setMaxMessageSize():設置發送消息的大小,默認 maxMessageSize = 1024 * 1024 * 4; // 4M,如果超過最大設置就會報異常。
producer端應用
/**
* Consumer和Producer都必須設置Topic,GroupName,NameServer地址以及端口號
* 最後再進入發送和接收邏輯
*/
public class SyncProducer {
public static void main(String[] args) throws Exception {
//使用生產者組名稱進行實例化
DefaultMQProducer producer = new
DefaultMQProducer("please_rename_unique_group_name");
//指定nameserver的地址
producer.setNamesrvAddr("localhost:9876");
//啓動生產者
producer.start();
for (int i = 0; i < 3; i++) {
//創建消息實例,指定topic、tag、消息內容
//topic:只允許是^[%|a-zA-Z0-9_-]+$組成的字符串,不能是漢字
Message msg = new Message("TopicTest",
"TagA",
("Hello RocketMQ " + i).getBytes(RemotingHelper.DEFAULT_CHARSET)
);
//生產將消息發送給一個broker對象處理
SendResult sendResult = producer.send(msg);
System.out.println("發送對象信息爲"+JSON.toJSONString(sendResult));
}
//關閉生產者實例後此對象不再使用
//producer.shutdown();
}
}