概述
消息队列 RocketMQ 是阿里巴巴集团基于高可用分布式集群技术,自主研发的云正式商用的专业消息中间件,既可为分布式应用系统提供异步解耦和削峰填谷的能力,同时也具备互联网应用所需的海量消息堆积、高吞吐、可靠重试等特性,是阿里巴巴双 11 使用的核心产品
阿里云官方接入文档:https://help.aliyun.com/document_detail/29553.html?spm=a2c4g.11186623.6.570.632b7059ZI0shf
springboot整合接入
pom文件
<dependency>
<groupId>com.aliyun.openservices</groupId>
<artifactId>ons-client</artifactId>
<version>1.8.0.Final</version>
</dependency>
application.yml
mq:
consumerId: @ons.consumerId@
accessKeyId: @ons.accessKeyId@
accessKeySecret: @ons.accessKeySecret@
onsAddr: @ons.onsAddr@
automaticPackagingTopic: @ons.automaticPackagingTopic@
maxReconsumeTimes: @ons.maxReconsumeTimes@
不同的环境中对应不同的properties文件
mq.consumerId=xxx
mq.accessKeyId=xxx
mq.accessKeySecret=xxx
mq.onsAddr=xxx
mq.automaticPackagingTopic=xxx
mq.maxReconsumeTimes=3
mq消费者
@Component
public class MessageConsumer {
@Value("${mq.consumerId}")
private String consumerId;
@Value("${mq.accessKeyId}")
private String accessKey;
@Value("${mq.accessKeySecret}")
private String secretKey;
@Value("${mq.onsAddr}")
private String onsAddr;
@Value("${mq.automaticPackagingTopic}")
private String topic;
@Value("${mq.maxReconsumeTimes}")
private String maxReconsumeTimes;
private Consumer consumer;
private final Map<String, MessageListener> listenerMap =new ConcurrentHashMap<>();
@Autowired
private MessageConsumer(Map<String, MessageListener> listenerMap){
this.listenerMap.clear();
listenerMap.forEach((k,v)->this.listenerMap.put(v.getType(),v));
}
@PostConstruct
public void init(){
LogFactory.mqlog.info("Consumer 开始启动...");
Properties properties = new Properties();
properties.put(PropertyKeyConst.GROUP_ID, consumerId);
properties.put(PropertyKeyConst.AccessKey, accessKey);
properties.put(PropertyKeyConst.SecretKey, secretKey);
properties.put(PropertyKeyConst.NAMESRV_ADDR, onsAddr);
properties.put(PropertyKeyConst.MaxReconsumeTimes, maxReconsumeTimes);
consumer = ONSFactory.createConsumer(properties);
consumer.subscribe(topic,"*", (message,context)->listenerMap.get(message.getTag()).consume(message,context));
consumer.start();
LogFactory.mqlog.info("Consumer 启动完成");
}
}
例如消费两种消息
public interface MessageListener {
/**
* 获取listener类型
* @return
*/
String getType();
/**
* 消费消息
* @param message
* @param context
* @return
*/
Action consume(final Message message, final ConsumeContext context);
}
一类接收足球消息
@Component
public class FootBallListener implements MessageListener {
private static final String TAG_FootBall = "TAG_FootBall";
@Override
public Action consume(Message message, ConsumeContext context) {
LogFactory.mqlog.info("receive :" + message.toString());
try {
// do what u should do
LogFactory.mqlog.info("consume success");
return Action.CommitMessage;
} catch (Exception e) {
LogFactory.mqlog.error("consume fail:" + e);
return Action.ReconsumeLater;
}
}
@Override
public String getType() {
return TAG_FootBall;
}
}
接收乒乓球消息
@Component
public class PingPangListener implements MessageListener {
public static final String TAG_PingPang = "TAG_PingPang";
@Override
public Action consume(Message message, ConsumeContext context) {
LogFactory.jvopfLog.info("receive:" + message.toString());
try {
//你的业务代码
if(true){
LogFactory.mqlog.info("consume Success");
return Action.CommitMessage;
}else {//比较重要的消息,失败后重试
LogFactory.mqlog.info("consume Fail");
return Action.ReconsumeLater;
}
}catch (Exception e){
LogFactory.mqlog.error("consume Exception:" + e);
return Action.ReconsumeLater;
}
}
@Override
public String getType() {
return TAG_PingPang;
}
}
mq 生产者
摘自 : https://help.aliyun.com/document_detail/29553.html?spm=a2c4g.11186623.6.570.dc4d2e77x4Y8BP
package demo;
import com.aliyun.openservices.ons.api.Message;
import com.aliyun.openservices.ons.api.Producer;
import com.aliyun.openservices.ons.api.SendResult;
import com.aliyun.openservices.ons.api.exception.ONSClientException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class ProduceWithSpring {
public static void main(String[] args) {
/**
* 生产者 Bean 配置在 producer.xml 中,可通过 ApplicationContext 获取或者直接注入到其他类(比如具体的 Controller)中
*/
ApplicationContext context = new ClassPathXmlApplicationContext("producer.xml");
Producer producer = (Producer) context.getBean("producer");
//循环发送消息
for (int i = 0; i < 100; i++) {
Message msg = new Message( //
// Message 所属的 Topic
"TopicTestMQ",
// Message Tag 可理解为 Gmail 中的标签,对消息进行再归类,方便 Consumer 指定过滤条件在消息队列 RocketMQ 的服务器过滤
"TagA",
// Message Body 可以是任何二进制形式的数据, 消息队列 RocketMQ 不做任何干预
// 需要 Producer 与 Consumer 协商好一致的序列化和反序列化方式
"Hello MQ".getBytes());
// 设置代表消息的业务关键属性,请尽可能全局唯一
// 以方便您在无法正常收到消息情况下,可通过控制台查询消息并补发
// 注意:不设置也不会影响消息正常收发
msg.setKey("ORDERID_100");
// 发送消息,只要不抛异常就是成功
try {
SendResult sendResult = producer.send(msg);
assert sendResult != null;
System.out.println("send success: " + sendResult.getMessageId());
}catch (ONSClientException e) {
System.out.println("发送失败");
}
}
}
}