支持延迟消息
RocketMQ 支持定时消息,但是不支持任意时间精度,仅支持特定的 level,例如定时 5s, 10s, 1m 等。其中,level=0 级表示不延时,level=1 表示 1 级延时,level=2 表示 2 级延时,以此类推。
配置
打开安装目录的./conf/broker.conf 文件,并添加如下延迟级别的时长设置:
messageDelayLevel = 1s 5s 10s 30s 1m 2m 3m 4m 5m 6m 7m 8m 9m 10m 20m 30m 1h 2h
配置文件内容:
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
brokerClusterName = DefaultCluster
brokerName = broker-a
brokerId = 0
deleteWhen = 04
fileReservedTime = 48
brokerRole = ASYNC_MASTER
flushDiskType = ASYNC_FLUSH
messageDelayLevel = 1s 5s 10s 30s 1m 2m 3m 4m 5m 6m 7m 8m 9m 10m 20m 30m 1h 2h
延迟配置说明:
- 配置项配置了从1级开始,各级延时的时间,可以修改这个指定级别的延时时间;
- 时间单位支持:s、m、h、d,分别表示秒、分、时、天;
- 默认值就是上面声明的,可手工调整;
- 默认值已够用,不建议修改这个值。
如何发送和接收延迟消息?
首先建一个发送消息的服务类 RocketMQProvider
package com.ms.demo.demo.service;
import org.apache.rocketmq.client.producer.DefaultMQProducer;
import org.apache.rocketmq.client.producer.MessageQueueSelector;
import org.apache.rocketmq.client.producer.SendResult;
import org.apache.rocketmq.common.message.Message;
import org.apache.rocketmq.common.message.MessageQueue;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.StopWatch;
import java.util.Date;
import java.util.List;
/**
* @ClassName RocketMQProvider
* @Description <p>TODO</p>
* @Author Jakemanse
* @Date 2018/10/24 15:22
* @Version 1.0
**/
@Service
public class RocketMQProvider {
@Value("${apache.rocketmq.producer.producerGroup}")
private String produerGroup;
@Value("${apache.rocketmq.namesrvAddr}")
private String namesrvAddr;
/**
* @Desc <p> 延迟消息发送</p>
* @Author Jakemanse
* @Date 2018/10/24 15:59
* @Param
* @Return void
*/
public void delayMQProducer() {
DefaultMQProducer producer = new DefaultMQProducer(produerGroup);
producer.setNamesrvAddr(namesrvAddr);
try {
producer.start();
Message message = new Message("TopicTest", "push", "发送延迟消息---".getBytes());
message.setDelayTimeLevel(3);
StopWatch stopWatch = new StopWatch();
stopWatch.start();
for (int i = 0; i < 1; i++) {
SendResult result = producer.send(message, new MessageQueueSelector() {
@Override
public MessageQueue select(List<MessageQueue> list, Message message, Object o) {
Integer id = (Integer) o;
int index = id % list.size();
return list.get(index);
}
}, 1,3000);
}
stopWatch.stop();
System.out.println(new Date().toString() + " 发送1条延迟消息耗时:" + stopWatch.getTotalTimeMillis());
} catch (Exception e) {
e.printStackTrace();
} finally {
producer.shutdown();
}
}
}
注意最重的一个设置 message.setDelayTimeLevel(3);
然后我们再创建一个消息消费端服务类 RocketConsumer
package com.ms.demo.demo.service;
import org.apache.rocketmq.client.consumer.DefaultMQPushConsumer;
import org.apache.rocketmq.client.consumer.listener.ConsumeConcurrentlyStatus;
import org.apache.rocketmq.client.consumer.listener.MessageListenerConcurrently;
import org.apache.rocketmq.common.consumer.ConsumeFromWhere;
import org.apache.rocketmq.common.message.MessageExt;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import java.util.Date;
/**
* @ClassName RocketConsumer
* @Description <p>TODO</p>
* @Author Jakemanse
* @Date 2018/10/24 15:16
* @Version 1.0
**/
@Service
public class RocketConsumer {
@Value("${apache.rocketmq.producer.consumerGroup}")
private String consumerGroup;
@Value("${apache.rocketmq.namesrvAddr}")
private String namesrvAddr;
public void defaultMQPushConsumer() {
DefaultMQPushConsumer consumer = new DefaultMQPushConsumer(consumerGroup);
consumer.setNamesrvAddr(namesrvAddr);
try {
consumer.subscribe("TopicTest", "push");
consumer.setConsumeFromWhere(ConsumeFromWhere.CONSUME_FROM_FIRST_OFFSET);
consumer.registerMessageListener((MessageListenerConcurrently) (list,context)->{
try {
for (MessageExt messageExt : list) {
// System.out.println("messageExt:" + messageExt);
String messageBody = new String(messageExt.getBody());
System.out.println( new Date().toString() + " 消费响应:"+ messageExt.getMsgId() +", MsgBody:" + messageBody);
}
} catch (Exception e) {
e.printStackTrace();
return ConsumeConcurrentlyStatus.RECONSUME_LATER;
}
return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
});
consumer.start();
} catch (Exception e) {
e.printStackTrace();
}
}
}
这里注意,一定不要忘记写 cosumer.start(); 让监听和接收消息服务启动。
消息配置properties 内容:
# 消费者的组名
apache.rocketmq.producer.consumerGroup=PushConsumer
# 生产者的组名
apache.rocketmq.producer.producerGroup=Producer
# NameServer地址
apache.rocketmq.namesrvAddr=127.0.0.1:9876
参考文章:
https://blog.csdn.net/u014380653/article/details/52883356
https://www.jianshu.com/p/33aa208ea058
https://blog.csdn.net/gesanghuakaisunshine/article/details/80261628?utm_source=blogxgwz6