阿里rocketmq接收消息比较简单,主要是做好接收数据后的处理,消息重试,日志记录等操作...(底下贴,xml文件配置)
1.java代码
package com.tf.ncm.comn.rocketmq.rocketmq;
import com.aliyun.openservices.ons.api.Action;
import com.aliyun.openservices.ons.api.ConsumeContext;
import com.aliyun.openservices.ons.api.Message;
import com.aliyun.openservices.ons.api.MessageListener;
import com.tf.ncm.comn.rocketmq.dao.MqAcceptDao;
import com.tf.ncm.comn.rocketmq.dao.MqSendLogDao;
import com.tf.ncm.comn.rocketmq.rocketmq.mqapi.MQApi;
import com.tf.ncm.comn.util.Utils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.ImportResource;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;
import javax.annotation.Resource;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* RocketMq消息监听
*/
@Component
@ImportResource({"classpath:mq-consumer.xml"})
public class AliMQListener implements MessageListener {
private static Logger log = LoggerFactory.getLogger(AliMQListener.class);
@Autowired
private MqAcceptDao mqAcceptDao;
@Autowired
private RestTemplate restTemplate;
@Autowired
private MQApi mqApi;
@Autowired
private MqSendLogDao mqSendLogDao;
HttpHeaders headers = new HttpHeaders();
@Override
public Action consume(Message msg, ConsumeContext context) {
Map<String, Object> map = new HashMap<>();
Map<String, Object> resultMap = new HashMap<>();
String topic;
String tag;
String key;
String msgId;
String body = null;
String url = null;
try {
//获取监听信息
key = msg.getKey();
topic = msg.getTopic();
tag = msg.getTag();
msgId = msg.getMsgID();
map.put("topic", topic);
map.put("tag", tag);
map.put("key", key);
map.put("msgId", msgId);
//接收body为json字符串数据
body = new String(msg.getBody(), "UTF-8");
map.put("object", body);
log.info("阿里MQ消息监听,收到消息,topic={},tag={},msgId={},key={},body={}",
topic, tag, msgId, key, body);
//MQ消息转发
//如果消息来自主数据Topic=NCM_From_Master,再下发到其他各自topic
if (topic.equals("NCM_FROM_MASTER")) {
Map<String, Object> ncmToRm = mqApi.sendMsg2Mq("NCM_TO_RM", tag, body, key);
Map<String, Object> ncmToPos = mqApi.sendMsg2Mq("NCM_TO_POS", tag, body, key);
// log.info("MQ从topic=NCM_From_Master,下发到NCM_TO_RM和NCM_TO_POS完成!!!,其中NCM_TO_RM为{},NCM_TO_POS为{}", ncmToRm.get("status"), ncmToPos.get("status"));
return Action.CommitMessage;
}
//集合中只存在一个URL接口
List<Map<String, Object>> urlMap = mqAcceptDao.getUrlByDict(map);
if (urlMap.size() > 0) {
//获得URL值
Map<String, Object> mapVal = urlMap.get(0);
url = mapVal.get("val").toString();
log.info("MQ监听请求地址={},数据体={}",url,map);
if (Utils.isNotEmpty(url)) {
//log.debug("阿里MQ消息监听,发送请求url={},map={}", url, map);
// headers.setContentType(MediaType.APPLICATION_JSON);
// HttpEntity<Map<String, Object>> httpEntity = new HttpEntity<>(map, headers);
resultMap = restTemplate.postForObject(url, map, Map.class);
//如果返回isCons为true 则重复消费,反之不重复消费
if (resultMap.get("isCons") != null && (Boolean) resultMap.get("isCons")) {
log.info("阿里MQ消息消费失败监听,进行重复消费!Topic={},tag={},msgId={}", msg.getTopic(), msg.getTag(), msg.getMsgID());
return Action.ReconsumeLater;
//不重复消费
// return Action.CommitMessage;
}
// log.info("阿里MQ消息监听,消费成功哒!msgId={},返回={}", msg.getMsgID(), resultMap);
}
// else {
// map.put("body", body);
// map.put("reqUrl", url);
// map.put("status", "0");
// map.put("dataOrg", "3");//数据来源 1=主数据,2=零管,3=comnMQ平台
// map.put("remark", "没找到对应URL");
// mqSendLogDao.saveMqSendInfo(map);
// }
}
// else {
// //log.error("阿里MQ消息监听,消费成功哒!但是没有找到对应的执行方法,msgId={}", msg.getMsgID());
// map.put("body", body);
// map.put("reqUrl", url);
// map.put("status", "0");
// map.put("dataOrg", "3");//数据来源 1=主数据,2=零管,3=comnMQ平台
// map.put("remark", "没找到对应URL");z
// mqSendLogDao.saveMqSendInfo(map);
// }
log.info("阿里MQ消息监听,消费完成!此次消费调用了{}接口", url);
return Action.CommitMessage;
} catch (
Exception e) {
e.printStackTrace();
map.put("body", body);
map.put("reqUrl", url);
map.put("status", "0");
map.put("dataOrg", "3");//数据来源 1=主数据,2=零管,3=comnMQ平台
map.put("remark", e.getMessage());
log.error("阿里MQ消息监听,消费失败xxx,异常信息={},msgId={}", e.getMessage(), msg.getMsgID());
mqSendLogDao.saveMqSendInfo(map);
//失败重复消费
return Action.ReconsumeLater;
//不重复消费
// return Action.CommitMessage;
}
}
}
2.xml配置
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="msgListener" class="com.tf.ncm.comn.rocketmq.rocketmq.AliMQListener"/> <!--Listener 配置-->
<!-- 多 CID 订阅同一个 Topic,可以创建多个 ConsumerBean-->
<bean id="consumer" class="com.aliyun.openservices.ons.api.bean.ConsumerBean" init-method="start"
destroy-method="shutdown">
<property name="properties"> <!--消费者配置信息-->
<props>
<prop key="GROUP_ID">${openservices.ons.producerBean.producerId}</prop>
<prop key="AccessKey">${openservices.ons.producerBean.accessKey}</prop>
<prop key="SecretKey">${openservices.ons.producerBean.secretKey}</prop>
<!--suppress SpringFacetInspection -->
<prop key="NAMESRV_ADDR">${openservices.ons.producerBean.namesrvAddr}</prop>
<!-- <prop key="MessageModel">BROADCASTING</prop>-->
<!--BROADCASTING广播模式,CLUSTERING集群模式,默认的是 集群消费模式-->
<!--将消费者线程数固定为50个-->
<prop key="ConsumeThreadNums">100</prop>
</props>
</property>
<property name="subscriptionTable">
<map>
<entry value-ref="msgListener">
<key>
<bean class="com.aliyun.openservices.ons.api.bean.Subscription">
<property name="topic" value=""/>
<property name="expression" value="*"/>
</bean>
</key>
</entry>
</beans>