侧边栏壁纸
博主头像
清如许博主等级

努力成长为一颗大树,一半洒落阴凉,一半沐浴阳光,非常沉默非常骄傲,从不依靠从不寻找

  • 累计撰写 80 篇文章
  • 累计创建 44 个标签
  • 累计收到 5 条评论

目 录CONTENT

文章目录

A001-消息队列客户端V1.0.0-设计文档.md

清如许
2022-08-05 / 0 评论 / 0 点赞 / 6 阅读 / 1,609 字 / 正在检测是否收录...
温馨提示:
本文最后更新于 2022-08-05,若内容或图片失效,请留言反馈。部分素材来自网络,若不小心影响到您的利益,请联系我们删除。

| --- | --- | --- |
| 更新日期 | 2022年04月05日 | 作 者 | 张留杨 |
| 保密等级 | C | 开放范围 | 研发测试部 |

版本历史

版 本更新日期作 者备注
1.0.02022年04月05日张留杨新建文档




1. 业务背景

开发中经常需要用到定时任务,比如:

  • 当订单一直处于未支付状态时,如何及时的关闭订单,并退还库存?
  • 如何定期检查处于退款状态的订单是否已经退款成功?

为了解决以上问题,最简单直接的办法就是定时去扫表。一般来说我们都是通过定时轮询查询数据库来判断是否有任务需要执行,也就是说不管怎么样,我们需要先查询数据库,而且有些任务对时间准确要求比较高的,需要每秒查询一次,对于系统小倒是无所谓,如果系统本身就大而且数据也多的情况下,这就不大现实了,所以需要选择其他方式,比如使用分布式任务调度,但也避免不了频繁的创建和删除任务。
因为我们项目中本身就使用到了RabbitMQ,所以基于方便开发和维护的原则,于是采用基于RabbitMQ的延迟队列来实现定时任务。

2. 设计目标

  • 消息传输可靠性:消息进入到延迟队列后,保证至少被消费一次
  • 支持丰富:先支持RabbitMQ,后续可考虑支持Kafka
  • 实时性:允许存在一定的时间误差
  • 消费方式:用户可以自定义消费方式
  • 消息推送方式:提供统一的API供调用
  • 延迟消息:可指定延迟时间进行消息消费
  • 多数据源:自定义数据源使用
  • 消息共享:多消费者共享消息消费

3. 设计要点

3.1 基本概念

  • topic

消息类型,比如有一个名为user-changetopic,那么这个topic下的消息应该是与用户变更相关的

  • queue

队列,每一个消息处理器都会有一个队列

  • bind

绑定,比如说一个账单的服务,需要在用户信息变更时执行一些操作,于是,这个服务创建了一个user-change队列,然后告诉MQ当有user-change的消息时,请把消息给我放到queue中。这样,当用户中心的user发生变更时,便会在向MQ推送一条topicuser-change的消息,MQ则会将此消息交给账单服务的消息队列

  • exchange

交换机,生产者生产的消息到达的第一站,根据分发规则,匹配查询表中的routing key分发消息到消息队列中

  • group

消息组,同一服务集群内各个节点成为一组,默认使用spring.application.name作为组名

  • share

消息共享,同一消息组内是否共享消息

3.2 消息结构

每一个消息要有以下几个属性:

  • topic:消息主题,用消费者路由消费消息
  • messageId:消息的唯一标识,用来检索和去重消息
  • delay:消息延迟时间,单位ms
  • headers:消息头
  • extContext:扩展参数

3.3 消息发送

提供一系列API,保证业务需求:

  • 简单消息发送
  • 延迟消息发送
  • 消息属性配置
  • 支持消息扩展
  • 异步消息发送
  • 支持异步发送回调
  • 发布确认机制

3.4 消息订阅

最大程度简化复杂配置,只关注topic,无关队列/交换机,一般业务场景只需要消息生产者和消费者约定好topic,即可完成消息订阅与消费。

  • 自动声明队列
  • 自动声明交换机
  • 自动绑定订阅关系
  • 支持默认消息分组
  • 支持消息组内共享
  • 多数据源
  • 自定义队列属性

3.5 消息消费

消息消费要最大灵活度的支持消息解析、消费配置:

  • 支持广泛消息体解析,payload解码
  • 自动映射属性值
  • 自定义指定消费方法
  • 消费确认

3.6 延迟消息

延迟消息的实现基于rabbitmqrabbitmq_delayed_message_exchange插件。内部实现:

  • 自动创建延迟交换机
  • 自动创建延迟队列
  • 自动路由消息

3.7 消息可靠性

消息可靠性从以下几点来保证:

  • 消息持久化

对于RabbitMQ,默认情况下为了性能考虑,消息是不持久化的。但是这样会导致消息在服务器重启后丢失,这在我们大多数场景下都是不可接受的。
优先使用异步持久化来进行消息持久化,来避免同步持久化的性能问题。同步使用发布确认模式,来防止刷盘前服务重启导致内存中的短时间内的数据丢失问题。

  • 发布者确认

发布确认模式需要手动开启。通过开启发布确认,来避免我们消息发布后,broker没有正确的处理该消息而导致消息丢失。开启发布确认后,broker会在接收到消息并成功处理后返回一个ACK。来保证我们发送的消息并不会丢失。

  • 消费者确认

RabbitMQ的消费确认模型有两种,自动确认和手动确认。自动确认是消费者接收或拉取到消息后,就会自动确认消息已被消费,然后从指定队列中删除,但是此时如果消费者并没有成功处理该消息,而此时队列中的消息已经被删除不会被重新投递,这就意味着消息丢失了。而我们通过采用手动确认模式,只要代码没有问题,基本上不会导致消息丢失。

4. 工作模式

4.1 单组

image.png

4.2 延迟

image.png

4.3 共享

image.png

4.4 多组

image.png

0

评论区