官网地址:http://rocketmq.apache.org/docs/quick-start/
rocketmq下载:https://archive.apache.org/dist/rocketmq/4.7.1/rocketmq-all-4.7.1-bin-release.zip
源码下载:https://github.com/apache/rocketmq
注意:使用jdk1.8
解压完成后,启动
1、bin/mqnamesrv 启动nameServer服务器
2、bin/mqbroker 启动broker服务器
参数:
-n 192.168.1.2:9876;192.168.1.3:9876 指定nameServer地址
-c ../conf broker.conf 指定配置文件
默认nameServer端口9876,默认broker主节点10911端口,默认从节点11011端口
提示:修改服务器jvm信息在runserver.sh和runbroker.sh中
1、执行bin/tools.sh org.apache.rocketmq.example.quickstart.Producer命令模拟生产者发送1000条消息
2、执行bin/tools.sh org.apache.rocketmq.example.quickstart.Consumer命令模拟消费者消费消息
采用2主2从异步复制的模式
在rocketmq/conf 文件夹下有2m-2s-async文件夹,这是专门用于集群的配置,里面是模版,可以大致修改后使用。
每个参数都进行了详细说明
#集群名字,相同集群名字的broker是一个集群
brokerClusterName=rocket-cluster
#broker的名字,相同名字的broker是一对主从节点(根据brokerId判断)
brokerName=broker-a
#当brokerId为0时代表主节点,大于0时表示从节点,可以有多个从节点
brokerId=0
#broker端口
listenPort=10911
#nameServer地址,多个用;分割
namesrvAddr=192.168.1.210:9876;192.168.1.187:9876
#发送消息时,自动创建不存在Topic,默认创建的队列数
defaultTopicQueueNums=4
#是否允许broker自动创建Topic,建议线下开启,线上关闭
autoCreateTopicEnable=true
#是否允许Broker自动创建订阅组,建议线下开启,线上关闭
autoCreateSubscriptionGroup=true
#各种文件存储路径
#文件存储根路径
storePathRootDir=/home/sumengnan/rocketmq-all-4.7.1-bin-release/store-a
#commitLog存储路径
storePathCommitLog=/home/sumengnan/rocketmq-all-4.7.1-bin-release/store-a/commitlog
#消费者队列存储路径
storePathConsumeQueue=/home/sumengnan/rocketmq-all-4.7.1-bin-release/store-a/consumequeue
#消息索引存储路径
storePathIndex=/home/sumengnan/rocketmq-all-4.7.1-bin-release/store-a/index
#checkpoint文件存储路径
storeCheckpoint=/home/sumengnan/rocketmq-all-4.7.1-bin-release/store-a/checkpoint
#abort文件存储路径
abortFile=/home/sumengnan/rocketmq-all-4.7.1-bin-release/store-a/abort
#文件通用配置
#删除文件时间点,默认凌晨4点
deleteWhen=04
#文件保留时间,默认48小时
fileReservedTime=120
#销毁MappedFile被拒绝的最大存活时间,默认120s
#destroyMapedFileIntervalForcibly=120000
#重试删除文件间隔,配合destoryMapedFIleIntervalForcibly,默认120s
#redeleteHangedFileInterval=120000
#Broker角色
#-ASYNC_Master 异步复制Master
#-SYNC_Master 同步复制Master
#Slave 从节点
brokerRole=ASYNC_MASTER
#刷盘方式
#-ASYNC_FLUSH 异步刷盘
#-SYNC_FLUSH 同步刷盘
flushDiskType=ASYNC_FLUSH
#commitlog文件配置
#commitLog文件大小,默认每个1G
#mapedFileSizeCommitLog=1073741824
#commitlog目录所在分区使用比例大于该值,则触发过期文件删除,默认75
#diskMaxUsedSpaceRatio=80
#针对commitlog文件,一次刷盘至少需要的脏页数量,默认4
#flushCommitLogLeastPages=4
#commitlog两次刷盘的最大间隔,如果超过该间隔,将flushCommitLogLeastPages=4要求直接执行刷盘操作,默认10000
#flushCommitLogThroughInterval=10000
#consumeQueue文件配置
#consumeQueue每个文件存储的条数,默认30w条,根据业务调整
#mapedFileSizeConsumeQueue=300000
#针对Consume文件,一次刷盘至少需要脏页的数量,默认2
#flushConsumeQueueLeastPages=2
#Consume两次刷盘的最大间隔,如果超过该间隔,将flushConsumeQueueLeastPages=4要求直接执行刷盘操作,默认60000
#flushConsumeQueueThroughInterval=60000
#消息配置
#限制消息大小
#maxMessageSize=65535
#发送消息线程池数量,服务端处理消息发送线程池数量,默认1
#sendMessageThreadPoolNums=128
#拉消息线程池数量,服务端处理消息拉取线程池数量,默认16+当前操作系统核心数2倍
#pullMessageThreadPoolNums=128
如果使用两台服务器,搭建2主2从模式,则建议交叉复制(备份)。好处是当某台服务器出现问题后,消息不会丢失
服务器A搭建 broker-a 和broker-b-s
服务器B搭建broker-b 和broker-a-s
配置文件需要修改的内容:
brokerName、brokerId、listenPort、各文件路径
启动命令:
服务器A
服务器B
使用bin/mqadmin命令查看
./mqadmin clusterList -n 192.168.1.210:9876;192.168.1.187:9876
github地址:https://github.com/apache/rocketmq-externals
项目下载完毕后,解压打开里面有rocketmq-console模块,这就是一个springboot项目,修改application配置文件属性(配置上namesrvAddr地址):
rocketmq.config.namesrvAddr=192.168.1.210:9876;192.168.1.178:9876
修改完毕使用mvn package -Dmaven.test.skip=true 命令打包,完成后java -jar命令启动jar包。
访问localhost:8080,如图:
1、DefaultMQProducer:producer生产者实例
2、DefaultMQPullConsumer:Consumer消费者的拉模式(已过时)
3、DefaultMQPushConsumer:Consumer消费者的推模式(拉模式升级得来)
2、Message :消息对象
1、同步发送(最慢,但最安全消息不会丢失)
使用send方法,只用一个message参数即可,会返回SendResult对象
代码:
DefaultMQProducer producer = new DefaultMQProducer("my-producer");
producer.setNamesrvAddr("192.168.1.210:9876;192.168.1.187:9876");
producer.start();
for (int i = 0; i <1000; i++) {
Message message = new Message("my-topic","mytag",("hello work"+i).getBytes(Charset.defaultCharset()));
SendResult result = producer.send(message);
System.out.println(result);
}
producer.shutdown();
2、异步发送(中等速度)
还是使用send方法,除了message参数还需要一个SendCallback对象。最好设置上重试次数和超时时间
还需要引入countDownLatch来保证所有消息回调方法执行完毕再关闭Producer
代码:
DefaultMQProducer producer = new DefaultMQProducer("my-producer");
producer.setNamesrvAddr("192.168.1.210:9876;192.168.1.187:9876");
producer.start();
CountDownLatch countDownLatch=new CountDownLatch(1000);
for (int i = 0; i <1000; i++) {
Message message = new Message("my-topic","mytag",("hello work"+i).getBytes(Charset.defaultCharset()));
producer.send(message, new SendCallback() {
@Override
public void onSuccess(SendResult sendResult) {
countDownLatch.countDown();
//业务处理逻辑
System.out.println(sendResult);
}
@Override
public void onException(Throwable e) {
countDownLatch.countDown();
System.out.println("出现异常"+e.getMessage());
}
});
}
countDownLatch.await();//等待全部发送完毕再关闭producer
producer.shutdown();
3、单向发送(最快,消息可能丢失)
使用sendOneway方法,发完消息就不管了。
代码:
DefaultMQProducer producer = new DefaultMQProducer("my-producer");
producer.setNamesrvAddr("192.168.1.210:9876;192.168.1.187:9876");
producer.start();
for (int i = 0; i <1000; i++) {
Message message = new Message("my-topic","mytag",("hello work"+i).getBytes(Charset.defaultCharset()));
producer.sendOneway(message);
System.out.println("发送完毕");
}
producer.shutdown();
1、拉模式(需要自己去mq上拿消息)
代码1(已过期):
使用DefaultMQPullConsumer类。缺点:太复杂,需要自己管理offset
Map offsetMap=new HashMap();//设置一个map,缓存MessageQueue对应的offset位点
DefaultMQPullConsumer consumer = new DefaultMQPullConsumer("my-consumer");
consumer.setNamesrvAddr("192.168.1.210:9876;192.168.1.187:9876");
consumer.start();
Set messageQueues = consumer.fetchSubscribeMessageQueues("my-topic");
for (MessageQueue mq : messageQueues) {
//开始拉取数据
//第一个参数是MessageQueue对象。第二个是tag筛选,*表示所有。第三个表示offset的值(每个队列的消费位置)。第四个是本次拉取的数据量
PullResult pullResult = consumer.pullBlockIfNotFound(mq, "*", (offsetMap.get(mq)!=null?offsetMap.get(mq):0), 32);
//保存此MessageQueue的offset值
offsetMap.put(mq,pullResult.getNextBeginOffset());
//获取pull拉取结果,并判断
PullStatus pullStatus = pullResult.getPullStatus();
if (pullStatus==PullStatus.FOUND){//有数据
}else if (pullStatus==PullStatus.NO_NEW_MSG){//没有新数据
}else if (pullStatus==PullStatus.NO_MATCHED_MSG){//没有匹配的数据
}else if (pullStatus==PullStatus.OFFSET_ILLEGAL){//offset值非法
}
System.out.println(pullResult);
}
consumer.shutdown();
代码2(推荐):
使用DefaultLitePullConsumer类
DefaultLitePullConsumer consumer = new DefaultLitePullConsumer("my-consumer");
consumer.setNamesrvAddr("192.168.1.210:9876;192.168.1.187:9876");
consumer.subscribe("my-topic","*");
consumer.start();
List poll = consumer.poll();
while(!poll.isEmpty()){
//业务处理
System.out.printf("%s%n",poll);
poll = consumer.poll();
}
consumer.shutdown();
2、推模式(mq推送消息过来)
是由拉模式封装的
DefaultMQPushConsumer pushConsumer = new DefaultMQPushConsumer("my-consumer");
pushConsumer.setNamesrvAddr("192.168.1.210:9876;192.168.1.187:9876");
pushConsumer.subscribe("my-topic","*");
pushConsumer.setConsumeFromWhere(ConsumeFromWhere.CONSUME_FROM_LAST_OFFSET);
pushConsumer.registerMessageListener(new MessageListenerConcurrently() {
@Override
public ConsumeOrderlyStatus consumeMessage(List msgs, ConsumeOrderlyContext context) {
System.out.println("收到一批消息:");
msgs.stream().forEach(item->{
System.out.println("消息内容:"+item.toString());
});
return ConsumeConcurrentlyStatus.SUCCESS;
}
});
pushConsumer.start();
保证全局无序,部分有序。(相当于把消息都集中发到某一个MessageQueue上去,不会分开存放)
生产者使用send方法的参数MessageQueueSelector接口实现select方法,同时消费者使用push模式registerMessageListener方法参数MessageListenerOrderly接口实现consumeMessage方法
会把消息发给所有订阅了对应topic的消费者,不管消费者是不是同一个消费者组。
代码:consumer.setMessageModel(MessageModel.BROADCASTING);
还有集群模式:每一条消息只会被同一个消费者组中的一个实例消费到。
代码:consumer.setMessageModel(MessageModel.CLUSTERING);
一般是定时任务使用,可以设置消息在mq中存放的延时时间(不会立刻发到消费者)
代码:message.setDelayTimeLevel(3);
可以通过配置文件修改,有18个等级。
阿里云的商业版此处和开源版不同,商业版java包中message支持设置时间触发,不需要设置延时等级。
同时这个延时消息是各个大公司拿到rocketmq开源版,定制开发改造的一个重点
将多条消息合并成一个批量消息一次发送出去。好处是可以减少磁盘io。
同时有三点限制:
1、批量消息发送的大小不能大于1MB,实际最大4MB
2、必须是相同的topic和WaitStoreMsgOK参数
3、不支持延时消息、事务消息
代码:
消息太大如何拆分消息
计算消息的大小:消息的topic的长度+消息body的长度+消息所有Properties的key+value的长度+20的日志长度
代码表示:message.getTopic().length+message.getBody().length
两种方式
1、通过tag过滤
2、通过sql过滤