一 前言
使用Spring Boot 可以非常方便、快速搭建项目,使我们不用关心框架之间的兼容性,适用版本等各种问题,我们想使用任何东西,仅仅添加一个配置就可以。
1.消息队列是什么?
消息队列中间件是分布式系统中重要的组件,主要解决应用耦合、异步消息、流量削锋等问题。实现高性能、高可用、可伸缩和最终一致性架构。
2.RocketMq是什么?
RocketMQ 是一个队列模型的消息中间件,具有高性能、高可靠、高实时、分布式的特点。它是一个采用 Java 语言开发的分布式的消息系统,由阿里巴巴团队开发。
二 使用步骤
1.引入maven库
<dependency>
<groupId>org.apache.rocketmq</groupId>
<artifactId>rocketmq-spring-boot-starter</artifactId>
<version>2.2.0</version>
</dependency>
2.配置
rocketmq.producer.send-message-timeout=3000
rocketmq.producer.max-message-size=4096
rocketmq.name-server=localhost:9876
3.封装RocketMq工具类
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.rocketmq.client.producer.SendCallback;
import org.apache.rocketmq.client.producer.SendResult;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.springframework.messaging.Message;
import org.springframework.messaging.support.MessageBuilder;
import org.springframework.stereotype.Component;
import java.time.LocalDateTime;
@Component
@Slf4j
public class RocketMqSender {
private static final Long TIME_OUT = 20000L;
private final RocketMQTemplate rocketMQTemplate;
public RocketMqSender(RocketMQTemplate rocketmqtemplate) {
this.rocketMQTemplate = rocketmqtemplate;
}
/**
* 发送单向消息
*
* @param topic 主题
* @param tag 标签
* @param context 消息
*/
public void sendOneWay(String topic, String tag, String context) {
String destination = getDestination(topic, tag);
rocketMQTemplate.sendOneWay(destination, buildMessage(context));
}
/**
* 获取destination
*
* @param topic 主题
* @param tag 标签
* @return destination
*/
private String getDestination(String topic, String tag) {
if (StringUtils.isNotBlank(tag)) {
return topic + ":" + tag;
}
return topic;
}
private Message<String> buildMessage(String context) {
return MessageBuilder.withPayload(context).build();
}
/**
* 发送异步消息
*
* @param tag 标签
* @param topic 消息Topic
* @param context 消息实体
*/
public void asyncSend(String topic, String tag, String context) {
String destination = getDestination(topic, tag);
rocketMQTemplate.asyncSend(destination, buildMessage(context), getDefaultSendCallBack(context), TIME_OUT);
}
public void send(String topic, String tag, String context) {
String destination = getDestination(topic, tag);
rocketMQTemplate.send(destination, buildMessage(context));
}
/**
* 发送异步消息
* messageDelayLevel=1s 5s 10s 30s 1m 2m 3m 4m 5m 6m 7m 8m 9m 10m 20m 30m 1h 2h
*
* @param tag 标签
* @param topic 消息Topic
* @param context 消息实体
* @param delayLevel 延迟消息的级别
*/
public void asyncSend(String topic, String tag, String context, int delayLevel) {
String destination = getDestination(topic, tag);
rocketMQTemplate.asyncSend(destination, buildMessage(context), getDefaultSendCallBack(context), TIME_OUT, delayLevel);
}
/**
* 发送顺序消息
*
* @param tag 标签
* @param context 消息
* @param topic 主题
* @param hashKey hashkey
*/
public void syncSendOrderly(String topic, String tag, String context, String hashKey) {
String destination = getDestination(topic, tag);
log.info("发送顺序消息,destination:{},hashKey:{}", destination, hashKey);
rocketMQTemplate.syncSendOrderly(destination, buildMessage(context), hashKey);
}
/**
* 默认CallBack函数
*
* @param context 消息内容
* @return
*/
private SendCallback getDefaultSendCallBack(String context) {
return new SendCallback() {
@Override
public void onSuccess(SendResult sendResult) {
//TODO 需要保证消息的可靠投递
String msgId = sendResult.getMsgId();
log.info("---发送MQ成功---,消息id:{},消息内容:{},发送时间:{}", msgId, context, LocalDateTime.now());
}
@Override
public void onException(Throwable throwable) {
log.error("发送MQ失败", throwable);
}
};
}
}
4.发送消息
// 发送同步消息
rocketMqSender.send("topic","tag", "消息内容");
// 发送异步消息
rocketMqSender.asyncSend("topic","tag", "消息内容");
// 发送延迟消息
rocketMqSender.asyncSend("topic","tag", "消息内容",5);
5.消费消息
import com.cambodia.airways.cam.game.common.api.enums.RechargeOrderStatus;
import com.cambodia.airways.cam.game.common.service.bo.recharge.RechargeOrder;
import com.cambodia.airways.cam.game.common.service.dao.recharge.RechargeOrderMapper;
import com.cambodia.airways.framework.base.enums.SysCode;
import com.cambodia.airways.framework.base.exception.CamException;
import com.cambodia.airways.framework.core.springmvc.transaction.CamAirTransactionTemplate;
import com.cambodia.airways.game.service.pay.support.PaySupport;
import lombok.extern.slf4j.Slf4j;
import org.apache.rocketmq.spring.annotation.RocketMQMessageListener;
import org.apache.rocketmq.spring.annotation.SelectorType;
import org.apache.rocketmq.spring.core.RocketMQListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.Date;
import java.util.Objects;
@RocketMQMessageListener(topic = "topic", consumerGroup = "consumer-1",
selectorExpression = "tag", selectorType = SelectorType.TAG)
@Component
@Slf4j
public class InitRechargeOrderCancelConsumer implements RocketMQListener<String> {
@Override
public void onMessage(String context) {
log.info("开始消费消息,消息内容:{}", context);
}
}
三 最后
本篇文章主要讲解了rocketmq的简单使用与工具类的封装,至于如何保证消息的可靠性,请听小七下回分解