场景:在小程序中,发送打招呼后,后端程序主要是给被打招呼的用户推送公众号消息,然后这里改为走MQ。
小程序后端代码流程——controller层,基本无改动主要MQ实现在Service层
@GetMapping("/insert2")
public Object insertViceNumberBase2(@RequestParam("orgId") String orgId,
@RequestParam("thirdSession") String thirdSession,
@RequestParam("readUserId") String readUserId,
@RequestParam("remark") String remark
){
String userIdStr = WeixinXcxUtil.getUserId(redisTemplate,thirdSession);
if(userIdStr == null){
return R.error("请先授权登录",1001);
}
long userId = Long.parseLong(userIdStr);
if(StringUtil.isEmpty(remark)){
throw new RRException("打招呼内容不能为空!");
}
//判断是否有敏感词
String commentWarnKeysStr = systemParameterInfoDubboService.selectValueByKey("commentWarnKey");
String commentWarnKeyStr = systemParameterInfoDubboService.selectValueByKey("commentWarnKeyStr");
String[] commentWarnKeys = commentWarnKeysStr.split(",");
boolean isLegal = true;
for(String key : commentWarnKeys){
if(remark.contains(key)){
isLegal= false;
}
}
if(!isLegal){
throw new RRException(commentWarnKeyStr);
}
long readUserIdLong = Long.parseLong(readUserId);
//具体公众号推送
boolean b = viceSeeRecordService.insertViceSee2(Long.parseLong(orgId), userId,readUserIdLong,remark);
if(b){
//插入日志
commonLogInfoService.insertLog(userId,
CommonConstant.LogBusinessType_SeeViceNumber,readUserId);
return "提交成功";
}else {
return "打招呼失败!可能没关注公众号,无法收到通知!";
}
}
service层代设计MQ开关,在系统参数配置中打开MQ开关时,走MQ
在系统参数表中有一列数据,"y"表示开始MQ,"n"表示关闭MQ。
public boolean insertViceSee2(long orgId, long userId,long readUserId,String remark) {
UserBaseInfoDubbo user = userBaseInfoDubboService.selectRedisUserByUid(userId);
//查询系统参数表中是否开启MQ
String is_open_rocketmq = systemParameterInfoDubboService.selectValueByKey("is_open_rocketmq");
if (is_open_rocketmq.equals(CommonConstant.Y)) {
//开启MQ
ViceSeeRecordMQ viceSeeRecordMQ = new ViceSeeRecordMQ();
viceSeeRecordMQ.setUserId(userId);
viceSeeRecordMQ.setOrgId(orgId);
viceSeeRecordMQ.setRemark(remark);
viceSeeRecordMQ.setReadUserId(readUserId);
rocketMqProducerDubboService.sendAsyncMessage(TopicCommon.Topic_cyjh_greet, TagCommon.Tag_cyjh_vice_viceSeeRecord_insert2,
JSON.toJSONString(viceSeeRecordMQ));
return true;
}else {
//关闭MQ
//业务逻辑代码
}
}
在Dubbo中提供MQ接口及实现
//MQ接口
public interface RocketMqProducerDubboService {
//同步消息
boolean sendSyncMessage(String topic, String tag, String body);
//异步消息
void sendAsyncMessage(String topic,String tag,String body);
}
//实现层
@Component //或者用spring的service
@org.springframework.stereotype.Service("rocketMqProducerDubboService")
@com.alibaba.dubbo.config.annotation.Service(interfaceClass = RocketMqProducerDubboService.class)
public class RocketMqProducerDubboServiceImpl implements RocketMqProducerDubboService {
@Autowired
private RocketMQTemplate rocketMQTemplate;
//发送同步消息 body序列化模式
@Override
public boolean sendSyncMessage(String topic, String tag, String body) {
try {
if(tag == null){
tag="";
}
SendResult sendResult = rocketMQTemplate.syncSend(topic+":"+tag,body);
if(SendStatus.SEND_OK.equals(sendResult.getSendStatus())){
return true;
}else {
System.out.println("-----------dubbo开发发送mq消息--------发送失败--------" + topic+","+tag+","+body );
return false;
}
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
//发送异步消息
@Override
public void sendAsyncMessage(String topic,String tag,String body) {
try {
if(tag == null){
tag="";
}
rocketMQTemplate.asyncSend(topic+ ":" + tag, body, new SendCallback() {
@Override
public void onSuccess(SendResult sendResult) {
}
@Override
public void onException(Throwable e) {
System.out.println("发送异步消息后,回调失败!!!tag:" + ",messageId:"+e.getMessage());
}
});
} catch (Exception e) {
e.printStackTrace();
}
}
}
最后是MQ走的代码,主要是配置好,其它根据业务需求来
@Component
//top配置
@RocketMQMessageListener(topic = TopicCommon.Topic_cyjh_greet,
//消费组
consumerGroup = "cyjh-job-consumer-group-vice-greet",
//tap配置
selectorExpression = TagCommon.Tag_cyjh_vice_viceSeeRecord_insert2,
//集群模式
messageModel = MessageModel.CLUSTERING)
//实现RocketMQListener<MessageExt>
public class ConsumerCyjhViceSeeRecordGreetService implements RocketMQListener<MessageExt> {
@Override
public void onMessage(MessageExt messageExt) {
//mq消息体
byte[] body = messageExt.getBody();
//mq自动生成的这条消息在masmter唯一消息Id
String msgId = messageExt.getMsgId();
String tags = messageExt.getTags();
String topic = messageExt.getTopic();
//接收消息体
String mqBody = new String(body);
ViceSeeRecordMQ viceSeeRecordMQ = JSON.parseObject(mqBody,ViceSeeRecordMQ.class);
//根据msgId查询对象,做去重处理,在极端情况下MQ可能回重复消费信息
SystemMqRecordDubbo systemMqRecordDubbo = mqRecordDubboService.selectOneMqRecord(msgId);
if (systemMqRecordDubbo==null){
//业务操作
insertRecordTable(viceSeeRecordMQ);
//记录mq的日志,消费一条信息,在数据库留下记录,防止重复消费
SystemMqRecordDubbo mqRecordDubbo = new SystemMqRecordDubbo();
mqRecordDubbo.setId(null);
mqRecordDubbo.setIsDeleted(CommonConstant.N);
mqRecordDubbo.setCreateOperator(String.valueOf(viceSeeRecordMQ.getUserId()));
mqRecordDubbo.setCreateTime(new Date());
mqRecordDubbo.setLastOperator(String.valueOf(viceSeeRecordMQ.getUserId()));
mqRecordDubbo.setLastModifyTime(new Date());
mqRecordDubbo.setMsgid(msgId);
mqRecordDubbo.setTags(tags);
mqRecordDubbo.setBrokerName(topic);
mqRecordDubbo.setBody(viceSeeRecordMQ.toString());
int i = mqRecordDubboService.insertOneMqRecord(mqRecordDubbo);
if (i <= 0){
throw new RuntimeException("插入失败~");
}
}
}
}