RocketMQ系列文章
RocketMQ(一):基本概念和环境搭建
RocketMQ(二):原生API快速入门
RocketMQ(三):集成SpringBoot
解耦
pom.xml
<dependency>
<groupId>org.apache.rocketmqgroupId>
<artifactId>rocketmq-spring-boot-starterartifactId>
<version>2.2.2version>
dependency>
生产者配置文件
生产者组
,这样发送消息时就不用指定了rocketmq:
name-server: 127.0.0.1:9876 # rocketMq的nameServer地址
producer:
group: boot-producer-group # 生产者组别
send-message-timeout: 3000 # 消息发送的超时时间
retry-times-when-send-async-failed: 2 # 异步消息发送失败重试次数
max-message-size: 4194304 # 消息的最大长度
生产者配置文件
rocketmq:
name-server: localhost:9876
直接引入即可
@Autowired
private RocketMQTemplate rocketMQTemplate;
生产消息
rocketMQTemplate.syncSend("bootTestTopic", "我是boot的一个消息");
消费消息
消息类型
消息体内容
,没有消息头内容(keys、msgId、延迟时间、重试次数、主题名称...)
@Component
@RocketMQMessageListener(topic = "bootTestTopic", consumerGroup = "boot-test-consumer-group")
public class ABootSimpleMsgListener implements RocketMQListener<MessageExt> {
@Override
public void onMessage(MessageExt message) {
System.out.println(new String(message.getBody()));
}
}
rocketMQTemplate.asyncSend("bootAsyncTestTopic", "我是boot的一个异步消息", new SendCallback() {
@Override
public void onSuccess(SendResult sendResult) {
System.out.println("成功");
}
@Override
public void onException(Throwable throwable) {
System.out.println("失败" + throwable.getMessage());
}
});
rocketMQTemplate.sendOneWay("bootOnewayTopic", "单向消息");
18
个固定的延时等级,等级1就对应1s,以此类推,最高支持2h延迟1s 5s 10s 30s 1m 2m 3m 4m 5m 6m 7m 8m 9m 10m 20m 30m 1h 2h
”;Message<String> msg = MessageBuilder.withPayload("我是一个延迟消息").build();
rocketMQTemplate.syncSend("bootMsTopic", msg, 3000, 4);
生产消息
hash值
决定消息放入哪个队列// 顺序消息 发送者放 需要将一组消息 都发在同一个队列中去 消费者 需要单线程消费
List<MsgModel> msgModels = Arrays.asList(
new MsgModel("qwer", 1, "下单"),
new MsgModel("qwer", 1, "短信"),
new MsgModel("qwer", 1, "物流"),
new MsgModel("zxcv", 2, "下单"),
new MsgModel("zxcv", 2, "短信"),
new MsgModel("zxcv", 2, "物流")
);
msgModels.forEach(msgModel -> {
// 发送 一般都是以json的方式进行处理
// 根据第三个参数计算hash值决定消息放入哪个队列
rocketMQTemplate.syncSendOrderly("bootOrderlyTopic", JSON.toJSONString(msgModel), msgModel.getOrderSn());
});
消费消息
@Component
@RocketMQMessageListener(topic = "bootOrderlyTopic",
consumerGroup = "boot-orderly-consumer-group",
consumeMode = ConsumeMode.ORDERLY, // 顺序消费模式 单线程
maxReconsumeTimes = 5 // 消费重试的次数
)
public class BOrderlyMsgListener implements RocketMQListener<MessageExt> {
@Override
public void onMessage(MessageExt message) {
MsgModel msgModel = JSON.parseObject(new String(message.getBody()), MsgModel.class);
System.out.println(msgModel);
}
}
主题
后面用:
来携带rocketMQTemplate.syncSend("bootTagTopic:tagA", "我是一个带tag的消息");
Message<String> message = MessageBuilder
.withPayload("我是一个带key的消息")
.setHeader(RocketMQHeaders.KEYS, "10086")
.build();
rocketMQTemplate.syncSend("bootKeyTopic", message);
获取带key和tag的消费者
@Component
@RocketMQMessageListener(topic = "bootTagTopic",
consumerGroup = "boot-tag-consumer-group",
selectorType = SelectorType.TAG,// tag过滤模式
selectorExpression = "tagA || tagB"
// selectorType = SelectorType.SQL92,// sql92过滤模式
// selectorExpression = "a in (3,5,7)" // broker.conf中开启enbalePropertyFilter=true
)
public class CTagMsgListener implements RocketMQListener<MessageExt> {
@Override
public void onMessage(MessageExt message) {
System.out.println("获取keys: " + message.getKeys());
System.out.println("消息内容: " + new String(message.getBody()));
}
}
查看源码
负载均衡模式
和广播模式
创建多个消费者监听同一个主题
@Component
@RocketMQMessageListener(topic = "modeTopic",
consumerGroup = "mode-consumer-group-a",
messageModel = MessageModel.CLUSTERING, // 集群模式(负载均衡)
)
public class DC1 implements RocketMQListener<String> {
@Override
public void onMessage(String message) {
System.out.println("我是mode-consumer-group-a组的第一个消费者:" + message);
}
}
@Component
@RocketMQMessageListener(topic = "modeTopic",
consumerGroup = "mode-consumer-group-a",
messageModel = MessageModel.CLUSTERING // 集群模式(负载均衡)
)
public class DC2 implements RocketMQListener<String> {
@Override
public void onMessage(String message) {
System.out.println("我是mode-consumer-group-a组的第二个消费者:" + message);
}
}
@Component
@RocketMQMessageListener(topic = "modeTopic",
consumerGroup = "mode-consumer-group-a",
messageModel = MessageModel.CLUSTERING // 集群模式(负载均衡)
)
public class DC3 implements RocketMQListener<String> {
@Override
public void onMessage(String message) {
System.out.println("我是mode-consumer-group-a组的第三个消费者:" + message);
}
}
生产者发送多条消息
@Test
public void modeTest() throws Exception {
for (int i = 1; i <= 10; i++) {
rocketMQTemplate.syncSend("modeTopic", "我是第" + i + "个消息");
}
}
执行结果:
我是mode-consumer-group-a组的第一个消费者:我是第4个消息
我是mode-consumer-group-a组的第一个消费者:我是第8个消息
我是mode-consumer-group-a组的第三个消费者:我是第3个消息
我是mode-consumer-group-a组的第三个消费者:我是第7个消息
我是mode-consumer-group-a组的第二个消费者:我是第2个消息
我是mode-consumer-group-a组的第二个消费者:我是第6个消息
我是mode-consumer-group-a组的第二个消费者:我是第10个消息
我是mode-consumer-group-a组的第一个消费者:我是第1个消息
我是mode-consumer-group-a组的第一个消费者:我是第5个消息
我是mode-consumer-group-a组的第一个消费者:我是第9个消息
第一个消费者消费了5个消息,第二个消费了3个,第三个消费了2个,为什么没有平均开?
所谓的负载均衡则是队列被平分,而不是消息
创建多个消费者监听同一个主题
@Component
@RocketMQMessageListener(topic = "modeTopic",
consumerGroup = "mode-consumer-group-b",
messageModel = MessageModel.BROADCASTING // 广播模式
)
public class DC4 implements RocketMQListener<String>, RocketMQPushConsumerLifecycleListener {
@Override
public void onMessage(String message) {
System.out.println("我是mode-consumer-group-b组的第一个消费者:" + message);
}
@Override
public void prepareStart(DefaultMQPushConsumer defaultMQPushConsumer) {
defaultMQPushConsumer.setInstanceName("第一个消费者");
}
}
@Component
@RocketMQMessageListener(topic = "modeTopic",
consumerGroup = "mode-consumer-group-b",
messageModel = MessageModel.BROADCASTING // 广播模式
)
public class DC5 implements RocketMQListener<String>, RocketMQPushConsumerLifecycleListener {
@Override
public void onMessage(String message) {
System.out.println("我是mode-consumer-group-b组的第二个消费者:" + message);
}
@Override
public void prepareStart(DefaultMQPushConsumer defaultMQPushConsumer) {
defaultMQPushConsumer.setInstanceName("第二个消费者");
}
}
@Component
@RocketMQMessageListener(topic = "modeTopic",
consumerGroup = "mode-consumer-group-b",
messageModel = MessageModel.BROADCASTING // 广播模式
)
public class DC6 implements RocketMQListener<String>, RocketMQPushConsumerLifecycleListener {
@Override
public void onMessage(String message) {
System.out.println("我是mode-consumer-group-b组的第三个消费者:" + message);
}
@Override
public void prepareStart(DefaultMQPushConsumer defaultMQPushConsumer) {
defaultMQPushConsumer.setInstanceName("第三个消费者");
}
}
生产者发送多条消息
@Test
public void modeTest() throws Exception {
for (int i = 1; i <= 3; i++) {
rocketMQTemplate.syncSend("modeTopic", "我是第" + i + "个消息");
}
}
执行结果: