以下是根据你提供的 RocketProducer 和 BaseMessage 封装的 多场景测试代码,包含不同 Topic 的生产者调用和对应的消费者监听实现,代码中会覆盖所有发送方式
public class RocketProducer {
@Generated
private static final Logger log = LoggerFactory.getLogger(RocketProducer.class);
private final RocketMQTemplate rocketMQTemplate;
public RocketProducer(RocketMQTemplate rocketMQTemplate) {
this.rocketMQTemplate = rocketMQTemplate;
}
public SendMsgResult send(String topic, BaseMessage message) {
return this.send(topic, (String)null, message);
}
public SendMsgResult send(String topic, String tag, BaseMessage message) {
Message<BaseMessage> sendMessage = this.putMessage(message);
SendResult sendResult = this.rocketMQTemplate.syncSend(this.buildDest(topic, tag), sendMessage);
log.info("send message end({})! messageId:{}, topic:{}, tag:{}, message:{}", new Object[]{sendResult.getSendStatus(), sendResult.getMsgId(), topic, tag, JacksonUtil.obj2String(message)});
return this.convertMsgResult(sendResult);
}
public void sendAsync(final String topic, final BaseMessage message) {
Message<BaseMessage> sendMessage = this.putMessage(message);
this.rocketMQTemplate.asyncSend(topic, sendMessage, new SendCallback() {
public void onSuccess(SendResult sendResult) {
RocketProducer.log.info("send message end({})! messageId:{}, topic:{}, message:{}", new Object[]{sendResult.getSendStatus(), sendResult.getMsgId(), topic, JacksonUtil.obj2String(message)});
}
public void onException(Throwable e) {
RocketProducer.log.info("send message failed!!! topic:{}, message:{}, errorMessage:{}, errorStack:{}", new Object[]{topic, JacksonUtil.obj2String(message), e.getMessage(), JacksonUtil.obj2String(e.getStackTrace())});
}
});
}
public void sendAsync(final String topic, final String tag, final BaseMessage message) {
Message<BaseMessage> sendMessage = this.putMessage(message);
this.rocketMQTemplate.asyncSend(this.buildDest(topic, tag), sendMessage, new SendCallback() {
public void onSuccess(SendResult sendResult) {
RocketProducer.log.info("send message end({})! messageId:{}, topic:{}, tag:{}, message:{}", new Object[]{sendResult.getSendStatus(), sendResult.getMsgId(), topic, tag, JacksonUtil.obj2String(message)});
}
public void onException(Throwable e) {
RocketProducer.log.info("send message failed!!! topic:{}, tag:{}, message:{}", new Object[]{topic, tag, JacksonUtil.obj2String(message)});
}
});
}
public void sendAsync(String topic, BaseMessage message, SendCallback callback) {
Message<BaseMessage> sendMessage = this.putMessage(message);
this.rocketMQTemplate.asyncSend(topic, sendMessage, callback);
log.info("async send message end! topic:{}, message:{}", topic, JacksonUtil.obj2String(message));
}
public SendMsgResult sendDelay(String topic, BaseMessage message, int delayLevel, long timeout) {
Message<BaseMessage> sendMessage = this.putMessage(message);
SendResult sendResult = this.rocketMQTemplate.syncSend(topic, sendMessage, timeout, delayLevel);
log.info("send delay message end({})! messageId:{}, topic:{}, delayLevel:{}, timout:{}, message:{}", new Object[]{sendResult.getSendStatus(), sendResult.getMsgId(), topic, delayLevel, timeout, message});
return this.convertMsgResult(sendResult);
}
public void sendDelayAsync(final String topic, final BaseMessage message, final int delayLevel, final long timeout) {
Message<BaseMessage> sendMessage = this.putMessage(message);
this.rocketMQTemplate.asyncSend(topic, sendMessage, new SendCallback() {
public void onSuccess(SendResult sendResult) {
RocketProducer.log.info("send delay message end({})! messageId:{}, topic:{}, delayLevel:{}, timout:{}, message:{}", new Object[]{sendResult.getSendStatus(), sendResult.getMsgId(), topic, delayLevel, timeout, message});
}
public void onException(Throwable throwable) {
RocketProducer.log.info("send message failed!!! topic:{}, message:{}", topic, JacksonUtil.obj2String(message));
}
}, timeout, delayLevel);
}
public SendMsgResult sendDelayTimeMills(String topic, BaseMessage message, long delayTime) {
Message<BaseMessage> sendMessage = this.putMessage(message);
SendResult sendResult = this.rocketMQTemplate.syncSendDelayTimeMills(topic, sendMessage, delayTime);
log.info("send delay message end({})! messageId:{}, topic:{}, delayTime:{}, message:{}", new Object[]{sendResult.getSendStatus(), sendResult.getMsgId(), topic, delayTime, message});
return this.convertMsgResult(sendResult);
}
public SendMsgResult sendDelayTimeMills(String topic, String tag, BaseMessage message, long delayTime) {
Message<BaseMessage> sendMessage = this.putMessage(message);
SendResult sendResult = this.rocketMQTemplate.syncSendDelayTimeMills(this.buildDest(topic, tag), sendMessage, delayTime);
log.info("send delay message end({})! messageId:{}, topic:{}, delayTime:{}, message:{}", new Object[]{sendResult.getSendStatus(), sendResult.getMsgId(), topic, delayTime, message});
return this.convertMsgResult(sendResult);
}
public void sendOrderly(String topic, String hashKey, BaseMessage message) {
Message<BaseMessage> sendMessage = this.putMessage(message);
SendResult sendResult = this.rocketMQTemplate.syncSendOrderly(topic, sendMessage, hashKey);
log.info("send orderly message end({})! messageId:{}, topic:{}, message:{}, hashKey:{}", new Object[]{sendResult.getSendStatus(), sendResult.getMsgId(), topic, message, hashKey});
}
public void sendOrderly(String topic, String tag, String hashKey, BaseMessage message) {
Message<BaseMessage> sendMessage = this.putMessage(message);
SendResult sendResult = this.rocketMQTemplate.syncSendOrderly(this.buildDest(topic, tag), sendMessage, hashKey);
log.info("send orderly message end({})! messageId:{}, topic:{}, tag:{} message:{}, hashKey:{}", new Object[]{sendResult.getSendStatus(), sendResult.getMsgId(), topic, tag, message, hashKey});
}
public void asyncSendOrderly(String topic, BaseMessage message, String hashKey, SendCallback sendCallback) {
Message<BaseMessage> sendMessage = this.putMessage(message);
this.rocketMQTemplate.asyncSendOrderly(topic, sendMessage, hashKey, sendCallback, 0L, 0);
log.info("send asyncSendOrderly message topic:{}, message:{}, hashKey:{} ", new Object[]{topic, message, hashKey});
}
public void asyncSendOrderly(String topic, String tag, BaseMessage message, String hashKey, SendCallback sendCallback) {
Message<BaseMessage> sendMessage = this.putMessage(message);
this.rocketMQTemplate.asyncSendOrderly(this.buildDest(topic, tag), sendMessage, hashKey, sendCallback, 0L, 0);
log.info("send asyncSendOrderly message topic:{}, message:{}, hashKey:{} ", new Object[]{topic, message, hashKey});
}
public void sendOneWay(String topic, BaseMessage message) {
Message<BaseMessage> sendMessage = this.putMessage(message);
this.rocketMQTemplate.sendOneWay(topic, sendMessage);
log.info("send sendOneWay message topic:{}, message:{}", topic, message);
}
public void sendOneWayOrderly(String topic, BaseMessage message, String hashKey) {
Message<BaseMessage> sendMessage = this.putMessage(message);
this.rocketMQTemplate.sendOneWayOrderly(topic, sendMessage, hashKey);
log.info("send sendOneWay message topic:{}, message:{} hashKey{}", new Object[]{topic, message, hashKey});
}
public void sendBroadcast(String topic, BaseMessage message) {
Message<BaseMessage> sendMessage = this.putMessage(message);
this.rocketMQTemplate.convertAndSend(topic, sendMessage);
log.info("send broadcast message end! topic:{}, message:{}", topic, message);
}
private String buildDest(String topic, String tag) {
StringBuilder dest = new StringBuilder((String)Objects.requireNonNull(topic));
if (StringUtils.hasLength(tag)) {
dest.append(":").append(tag);
}
return dest.toString();
}
private Message<BaseMessage> putMessage(BaseMessage message) {
MessageBuilder<BaseMessage> baseMessageMessageBuilder = MessageBuilder.withPayload(message);
String traceId = message.getTraceId();
try {
traceId = TraceUtil.getTraceId();
if (StringUtils.hasText(traceId)) {
message.setTraceId(traceId);
}
} catch (Throwable var5) {
}
baseMessageMessageBuilder.setHeader("traceId", traceId);
return baseMessageMessageBuilder.build();
}
private SendMsgResult convertMsgResult(SendResult sendResult) {
return SendMsgResult.builder().sendStatus(sendResult.getSendStatus()).msgId(sendResult.getMsgId()).offsetMsgId(sendResult.getOffsetMsgId()).queueId(sendResult.getMessageQueue().getQueueId()).queueOffset(sendResult.getQueueOffset()).topic(sendResult.getMessageQueue().getTopic()).build();
}
/** @deprecated */
@Deprecated
public SendMsgResult sendMessageInTransaction(String topic, BaseMessage message, Object arg) {
Message<BaseMessage> sendMessage = this.putMessage(message);
SendResult sendResult = this.rocketMQTemplate.sendMessageInTransaction(topic, sendMessage, arg);
log.info("send delay message end({})! messageId:{}, topic:{}, delayLevel:{}, timout:{}, message:{}", new Object[]{sendResult.getSendStatus(), sendResult.getMsgId(), topic, arg, message});
return this.convertMsgResult(sendResult);
}
}
public class BaseMessage implements Serializable {
private static final long serialVersionUID = 5708121021148373786L;
protected LocalDateTime sendTime = LocalDateTime.now();
protected String traceId = UUID.randomUUID().toString();
@Generated
public BaseMessage() {
}
@Generated
public LocalDateTime getSendTime() {
return this.sendTime;
}
@Generated
public String getTraceId() {
return this.traceId;
}
@Generated
public void setSendTime(LocalDateTime sendTime) {
this.sendTime = sendTime;
}
@Generated
public void setTraceId(String traceId) {
this.traceId = traceId;
}
@Generated
public boolean equals(Object o) {
if (o == this) {
return true;
} else if (!(o instanceof BaseMessage)) {
return false;
} else {
BaseMessage other = (BaseMessage)o;
if (!other.canEqual(this)) {
return false;
} else {
Object this$sendTime = this.getSendTime();
Object other$sendTime = other.getSendTime();
if (this$sendTime == null) {
if (other$sendTime != null) {
return false;
}
} else if (!this$sendTime.equals(other$sendTime)) {
return false;
}
Object this$traceId = this.getTraceId();
Object other$traceId = other.getTraceId();
if (this$traceId == null) {
if (other$traceId != null) {
return false;
}
} else if (!this$traceId.equals(other$traceId)) {
return false;
}
return true;
}
}
}
@Generated
protected boolean canEqual(Object other) {
return other instanceof BaseMessage;
}
@Generated
public int hashCode() {
int PRIME = true;
int result = 1;
Object $sendTime = this.getSendTime();
result = result * 59 + ($sendTime == null ? 43 : $sendTime.hashCode());
Object $traceId = this.getTraceId();
result = result * 59 + ($traceId == null ? 43 : $traceId.hashCode());
return result;
}
@Generated
public String toString() {
LocalDateTime var10000 = this.getSendTime();
return "BaseMessage(sendTime=" + var10000 + ", traceId=" + this.getTraceId() + ")";
}
}
- 生产者测试类
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
public class RocketMQProducerTest {
@Autowired
private RocketProducer rocketProducer;
// 同步发送测试
@Test
public void testSyncSend() {
BaseMessage message = new BaseMessage();
rocketProducer.send("SYNC_TOPIC", "SYNC_TAG", message);
}
// 异步发送测试
@Test
public void testAsyncSend() {
BaseMessage message = new BaseMessage();
rocketProducer.sendAsync("ASYNC_TOPIC", "ASYNC_TAG", message);
// 等待异步回调完成
try { Thread.sleep(3000); } catch (InterruptedException e) {}
}
// 延迟发送(级别)测试
@Test
public void testDelayLevelSend() {
BaseMessage message = new BaseMessage();
rocketProducer.sendDelay("DELAY_LEVEL_TOPIC", message, 3, 3000); // 延迟级别3(约10秒)
}
// 延迟发送(毫秒)测试
@Test
public void testDelayMsSend() {
BaseMessage message = new BaseMessage();
rocketProducer.sendDelayTimeMills("DELAY_MS_TOPIC", "DELAY_TAG", message, 5000); // 延迟5秒
}
// 顺序发送测试
@Test
public void testOrderlySend() {
BaseMessage message = new BaseMessage();
String hashKey = "order_123"; // 同一订单号确保进入同一队列
rocketProducer.sendOrderly("ORDERLY_TOPIC", "ORDERLY_TAG", hashKey, message);
}
// 单向发送测试
@Test
public void testOneWaySend() {
BaseMessage message = new BaseMessage();
rocketProducer.sendOneWay("ONEWAY_TOPIC", message);
}
// 广播发送测试
@Test
public void testBroadcastSend() {
BaseMessage message = new BaseMessage();
rocketProducer.sendBroadcast("BROADCAST_TOPIC", message);
}
}
- 消费者监听类
import org.apache.rocketmq.spring.annotation.RocketMQMessageListener;
import org.apache.rocketmq.spring.core.RocketMQListener;
import org.springframework.stereotype.Component;
// 同步消息消费者
@Component
@RocketMQMessageListener(topic = "SYNC_TOPIC", selectorExpression = "SYNC_TAG", consumerGroup = "SYNC_GROUP")
public class SyncConsumer implements RocketMQListener<BaseMessage> {
@Override
public void onMessage(BaseMessage message) {
System.out.println("[同步消息] 接收消息: " + message.getTraceId());
}
}
// 异步消息消费者
@Component
@RocketMQMessageListener(topic = "ASYNC_TOPIC", selectorExpression = "ASYNC_TAG", consumerGroup = "ASYNC_GROUP")
public class AsyncConsumer implements RocketMQListener<BaseMessage> {
@Override
public void onMessage(BaseMessage message) {
System.out.println("[异步消息] 接收消息: " + message.getTraceId());
}
}
// 延迟消息消费者(级别)
@Component
@RocketMQMessageListener(topic = "DELAY_LEVEL_TOPIC", selectorExpression = "DELAY_TAG", consumerGroup = "DELAY_LEVEL_GROUP")
public class DelayLevelConsumer implements RocketMQListener<BaseMessage> {
@Override
public void onMessage(BaseMessage message) {
System.out.println("[延迟消息-级别] 接收消息: " + message.getTraceId() + " | 发送时间: " + message.getSendTime());
}
}
// 延迟消息消费者(毫秒)
@Component
@RocketMQMessageListener(topic = "DELAY_MS_TOPIC", selectorExpression = "DELAY_TAG", consumerGroup = "DELAY_MS_GROUP")
public class DelayMsConsumer implements RocketMQListener<BaseMessage> {
@Override
public void onMessage(BaseMessage message) {
System.out.println("[延迟消息-毫秒] 接收消息: " + message.getTraceId() + " | 发送时间: " + message.getSendTime());
}
}
// 顺序消息消费者
@Component
@RocketMQMessageListener(topic = "ORDERLY_TOPIC", selectorExpression = "ORDERLY_TAG", consumerGroup = "ORDERLY_GROUP", consumeMode = ConsumeMode.ORDERLY)
public class OrderlyConsumer implements RocketMQListener<BaseMessage> {
@Override
public void onMessage(BaseMessage message) {
System.out.println("[顺序消息] 接收消息: " + message.getTraceId());
}
}
// 单向消息消费者
@Component
@RocketMQMessageListener(topic = "ONEWAY_TOPIC", selectorExpression = "ONEWAY_TAG", consumerGroup = "ONEWAY_GROUP")
public class OneWayConsumer implements RocketMQListener<BaseMessage> {
@Override
public void onMessage(BaseMessage message) {
System.out.println("[单向消息] 接收消息: " + message.getTraceId());
}
}
// 广播消息消费者(启动多个实例测试广播效果)
@Component
@RocketMQMessageListener(topic = "BROADCAST_TOPIC", selectorExpression = "BROADCAST_TAG", consumerGroup = "BROADCAST_GROUP", messageModel = MessageModel.BROADCASTING)
public class BroadcastConsumer implements RocketMQListener<BaseMessage> {
@Override
public void onMessage(BaseMessage message) {
System.out.println("[广播消息] 接收消息: " + message.getTraceId() + " | 实例ID: " + this.hashCode());
}
}
- 关键配置说明
rocketmq:
name-server: 127.0.0.1:9876
producer:
group: TEST_PRODUCER_GROUP
consumer:
# 不同消费者组需单独配置
SYNC_GROUP:
message-model: CLUSTERING
ASYNC_GROUP:
message-model: CLUSTERING
DELAY_LEVEL_GROUP:
message-model: CLUSTERING
DELAY_MS_GROUP:
message-model: CLUSTERING
ORDERLY_GROUP:
message-model: CLUSTERING
ONEWAY_GROUP:
message-model: CLUSTERING
BROADCAST_GROUP:
message-model: BROADCASTING
5 这个验证逻辑看起来很完整,包含了不同情况下对消息发送和接收的验证步骤。以下是对每个验证步骤的简要解释:
-
同步/异步发送:验证生产者发送消息时是同步还是异步的方式。通过观察控制台日志,确保消息发送成功并且消费者正确接收到消息。
-
延迟发送:检查消息接收时间是否与设置的延迟时间一致。例如,如果设置了5秒的延迟时间,确保消息在5秒后被消费者接收。
-
顺序发送:发送多个带有相同 hashKey 的消息,确保消费者能够单线程按顺序处理这些消息,而不会乱序处理。
-
广播发送:启动多个消费者实例,验证所有实例都能收到同一条消息。这种情况下,消息应该被广播给所有消费者实例,而不是仅发送给其中一个。
6 为了确保顺序消息的正确消费,以下是一些注意事项:
-
在使用RocketMQ时,确保所有的Topic都在RocketMQ控制台中预先创建。这样可以确保消息发送和消费的顺利进行。
-
对于需要按顺序消费的消息,消费者需要设置consumeMode为ConsumeMode.ORDERLY。这可以确保消息按照顺序进行处理。
-
如果使用广播模式发送消息,建议启动多个消费者实例来观察是否所有消息都能被接收。这样可以验证消息的广播是否正常工作。