消息服务设计

来源:互联网 发布:好用打印软件注册码 编辑:程序博客网 时间:2024/05/16 15:10

消息服务

  1. MS:简称消息服务

主要是方便对业务进行扩展,目前考虑接入activemq和阿里mq,暂时支持这两种消息产品,消息服务对外提供简单的接口,封装具体的实现,尽量做到可灵活配置。

 

消息主要属性

  • id:编号
  • data:消息内容
  • order_id第三方唯一订单号
  • acct_id第三方账号
  • status:状态
  • bus_check_fail_count:验证第三方业务是否成功,验证失败的次数,默认为0
  • bus_check_max_count:允许验证第三方业务是否成功的次数,默认为14
  • bus_check_next_time:下次验证时间
  • send_to_queue_fail_count:当前投递失败次数,默认为0
  • send_to_queue_max_count:允许投递失败的次数,默认为14
  • send_to_queue_next_time:下次投递至队列的时间
  • send_count:已投递至队列的次数,默认为0
  • send_max_count:允许投递的次数,默认为10
  • dispose_fail_count:处理失败的次数,默认为0
  • dispose_max_count:允许处理失败的次数,默认为10
  • add_time:消息入库时间
  • send_time:消息投递至队列的时间
  • timer_time:定时发送时间
  • dispose_time:处理时间
  • type:消息类型,0:默认值,即时消息,1:定时消息
  • update_time:最后更新时间
  • teta_data:消息源信息(最初的消息信息)
  • version:版本号,默认为0,每次更新+1

 

消息状态:

100:初始状态

201:取消投递(业务执行失败)

202:取消投递(手动)

203:业务验证失败,待再次验证

204:业务验证失败,终止验证

301:投递失败,待再次投递

302:投递失败,终止投递

400:投递成功

500:消费成功

600:消费失败,待再次处理

601:消费失败

 

 

消息操作日志:

  • Id:编号
  • ms_id:消息编号
  • start_time:操作开始时间
  • end_time:操作结束时间
  • cost_time:耗时
  • add_time:入库时间
  • step:操作步骤
  • description:操作详细结果描述
  • ms_snapshot:消息快照,消息json格式

 

后台功能:

提供对消息服务的参数配置,消息查询,消息重发,消息日志详情,第三方消息中间件的健康状况等功能,方便运维。

 

  1. 发送消息

业务A中需要发送消息M1,过程如下

  1. 业务A打开本地事务T1
  2. 业务A执行本地业务操作
  3. 生成业务唯一订单号O1
  4. 调用MS,预发送消息M1(将消息先记录下来,未投递至消息队列),此时M1的状态为100
  5. 提交本地事务T1
  6. 调用MS,发送消息M1,此时MS中操作如下:
    1. 根据M1.O1查询业务订单O1是否存在,若存在,将消息投递至队列,投递成功,将消息状态置为400;投递失败,将重复尝试投递次数+1

 

  1. 处理消息

处理器接收到消息时,消息已经从队列中删除,处理过程如下:

  1. 若所有处理器都处理成功,将消息状态置为500
  2. 若处理失败,将处理失败次数+1
    1. 若当前失败次数<最大失败次数,将消息状态置为600
    2. 若当前失败次数=最大失败次数,将消息状态置为601

 

对于php投递消息的处理过程,接受到消息之后,先记录下来,然后投递一条本地消息进行处理。

 

 

为了保证整个消息服务的高可用性,需要有以下几个job来做辅助,几个job中的处理过程可以放在一个job中执行。

  1. JOB1:处理长时间状态为100的消息
  1. 描述

对于长期处于100状态的消息,原因可能有以下几种:

  • 情况1:业务处理成功,消息插入成功,通知消息投递的时候操作失败
  • 情况2:业务操作长时间未完成
  • 情况3:业务操作失败,通知取消发送失败

 

  1. 处理逻辑
  1. 查询待投递的消息

Select * from 消息表 where status = 100 and type=0 and add_time + 10 <= 当前时间

  1. 调用验证业务是否存在
  • 存在,执行1.2.3
  • 不存在,将消息置状态置为201
  • 调用异常,将消息状态置为203bus_check_fail_count+1bus_check_next_time =当前时间后面图表中bus_check_fail_count对应的时间
  1. 若成功,调用投递至队列的方法进行投递
  • 投递成功,将消息状态置为400
  • 投递失败,将消息状态置为301send_to_queue_fail_count+1Send_to_queue_next_time =当前时间后面图表中send_to_queue_fail_count对应的时间

 

  1. job2:处理定时消息
  1. 描述

处理类型为1的消息

 

  1. 处理逻辑
  1. 查询需处理的消息

Select * from 消息表where status = 100 and type=1 and timer_time<=now();

  1. 处理过程和job11.2.21.2.3一样

 

  1. job3:业务验证失败消息的重试操作
  1. 描述

校验业务订单的时候,第三方接口是否稳定直接影响到订单的校验结果,第三方接口不稳定可能会导致校验失败,此处采用多次尝试来确保校验成功

  1. 处理逻辑
  1. 查询需处理的消息

Select * from 消息表 where status = 203 and bus_check_fail_count< bus_check_max_count and bus_check_time<=now();

  1. 处理过程和job11.2.21.2.3一样

每次重复验证对应的时间间隔如下:

bus_check_fail_count

每次重复间隔时间

1

5

2

10

3

20

4

30分钟

5

1分钟

6

2分钟

7

3分钟

8

4分钟

9

5分钟

10

10分钟

11

20分钟

12

30分钟

13

1小时

14

2小时

bus_check_fail_count= bus_check_max_count,将消息状态置为204

 

  1. job4:投递失败消息的重试操作
  1. 描述

投递至队列的过程中,队列是否稳定直接影响到投递的结果,此处采用多次尝试来确保投递成功

send_to_queue_fail_count

每次重复间隔时间

1

5

2

10

3

20

4

30分钟

5

1分钟

6

2分钟

7

3分钟

8

4分钟

9

5分钟

10

10分钟

11

20分钟

12

30分钟

13

1小时

14

2小时

      

  1. 处理逻辑
  1. 查询需投递的消息

select * from 消息表 where status = 301 and send_to_queue_fail_count< send_to_queue_max_count and send_to_queue_next_time<=now();

  1. 处理过程和job11.2.3一样

send_to_queue_fail_count= send_to_queue_max_count,将消息状态置为302

 

  1. Job5:处理投递成功长时间未知结果的消息
  1. 描述

长时间处于投递成功的消息有以下几种情况

  • 消息堆积,长时间未处理
  • 消息处理成功,修改消息状态失败
  1. 处理逻辑
  1. 对于长时间未知处理结果的消息,再次投递一次
  2. 查询需处理的消息

Select * from 消息表 where status = 400 and send_time+send_count对应的时间表<=当前时间 and send_count<send_max_count;

  1. 将消息初始化为最初状态,类型置为定时消息,send_count+1,将timer_time置为当前时间

Send_count

时间

1

10分钟

2

20分钟

3

30分钟

4

1小时

5

2小时

6

3小时

7

4小时

8

5小时

9

12小时

10

24小时

经过上面10次都不知道结果,将消息置为处理失败状态

 

  1. Job6:失败消息的补偿操作
  1. 描述

对于处理失败的消息,采用再次投递,再次处理的方式,来达到最终处理成功

  1. 处理逻辑
  1. 查询需处理的消息

Select * from 消息表 where status=600 and dispose_fail_count< dispose_max_count;

  1. 将消息初始化为最初状态,类型置为定时消息,将timer_time置为当前时间+ dispose_fail_count对应的时间

dispose_fail_count

每次间隔时间

1

5

2

10

3

20

4

1分钟

5

2分钟

6

5分钟

7

10分钟

8

30分钟

9

1小时

10

2小时

如果重试10次仍然失败,将消息状态置为601,将不再重试

 

技术点:

  1. 发送消息的实现
    1. 新增一个注解,用户标注发送消息的方法
    2. 添加一个环绕通知,切点为所有发送消息的方法,order置为100,在环绕通知中方法执行完毕之后,调用消息服务发送消息;或者取消消息的发送(此处根据业务方法是否执行成功来判断)。
  2. 消息处理

需保证消息处理的幂等性,一条消息可以被多个处理器处理,每个处理器只能成功处理一次消息。

 

 

如果喜欢,请关注公众号,我们将最好的内容分享与你!

0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 淘宝受到卖家威胁怎么办 消费者被外卖商家威胁怎么办 拼多多商家打电话威胁怎么办 退款被拒商家还威胁怎么办? 打错电话给领导怎么办 领导送礼物给我怎么办 南瓜饼和面很稀怎么办 包饺子剩的肉馅怎么办 发好的面团粘手怎么办 富士变频器减速时间过电流怎么办 铺木地板地面不是很平怎么办 眼镜被铁锈烫了怎么办 平车机针头小了怎么办 mk包五金坏了怎么办 迁坟原来的棺材怎么办 新建定额项目没有措施项目怎么办 太岁符忘记烧了怎么办 穿裙子去了寺庙怎么办 美甲彩绘胶干了怎么办 美甲彩绘胶稀怎么办 彩绘胶弄衣服上怎么办 彩绘胶买来太稠怎么办 做指甲没有底胶怎么办 交定金后发现房屋不合法怎么办 买车付了定金不想要了怎么办 买车付定金后不想要怎么办 非法经营的产品至人伤亡怎么办 返修漆施工不对色怎么办 叶子板撞变形了怎么办 挤了三角区疖子怎么办 三角部位太鼓的怎么办 美利车车贷逾期怎么办? 外墙保温层坏了怎么办 双胞胎34周血压高怎么办 夏天穿凉鞋脚后跟干裂起硬皮怎么办 穿凉鞋脚后跟干裂起硬皮怎么办 夏天穿凉鞋磨脚怎么办 lv皮带黑色掉漆怎么办 黑色衣服穿在身上掉色怎么办 电信卡流量超了怎么办 移动卡流量超了怎么办