1.概述
分享本人设计的用于app消息模块的设计、分析、实践。
主要是利用
阿里云RocketMQ服务和Redis去实现的。用于app推送消息,和app内置消息模块红点标识。
2.数据库设计

3.业务逻辑实现图

4.实现细节分析
(1)(5)需要特别注意的就是重发机制(因为无法确定第三方服务商是否宕机)
/**
* 重发机制伪代码
* */
List messageList = new ArrayList();
int index = 1;
int retrySize = 5;
while (messageList.size() > 0 && index <= retrySize){
//需要重发的数据
List recryList = new ArrayList();
index++;
//调用发送
for (int i = 0; i < messageList.size(); i++) {
//取出消息
Message msg = (Message)messageList.get(i);
//发送消息
try{
// 同步发送消息,只要不抛异常就是成功
SendResult sendResult = producer.send(msg);
// 进行下一步
}catch (Exception e){
//将失败消息添加到重发消息内
recryList.add(msg);
}
}
//循环结束后查看是否需要重发消息
if( recryList.size() > 0 ){
//如果重发到第retrySize次
if(index == retrySize){
//直接发送报警系统
warniingService.sendErro("重发超过retrySize");
}
try {
Thread.sleep(1000 * 60 * index); //延时 index 分钟 ,第一次1分钟, 第二次两分钟
} catch (InterruptedException e) {
//直接调用 系统警报系统
warniingService.sendErro("重发sleeop报警"+e.getMessage());
}
//赋值重新发送消息
messageList = recryList;
}
}
(2)需要注意的是修改状态的时候需要加一个版本号判断,主要是防止业务系统因为机器原因导致了处理变慢,可能消息系统已经消费过了,然后导致消息重发。
update messge_inform set messageStatus = 1 where vserion = 1(4)为了确保消息不重复消费
//实例化redis
Jedis jedis = new Jedis();
Message msg = 此处为mq消费者获取消息 ;
String msgId = msg.getMsgID();
if(jedis.exists(msgId)) {
//存在就刷新过期时间
jedis.expire(msgId, 1000 * 60 * 5);
}else{
//不存在就存入id并且消费
jedis.setex(msgId, 1000 * 60 * 5, "0");
//消费 消息
messageSendService.send(msg);
}