《大型网站系统与Java中间件实践》-消息中间件

1. 消息系统的价值

1.1没有消息系统的时候

假设你负责系统的用户注册模块开发,突然有一天接到产品的要求让你增加注册成功之后发短信任务,此时你屁颠屁颠的找到用户注册部分的代码,然后你快速的在代码后面加上调用短信服务的代码,心满意足的提交了。又过了几天,心得需求是增加注册送积分活动,然后,呵呵......

《大型网站系统与Java中间件实践》-消息中间件_第1张图片
服务直接调用

1.2引入消息系统

用户注册成功时,发送消息给消息中间件,其他系统向消息中间件订阅这个消息,完成相应工作。通过消息中间件的解耦,注册系统不关心有多少系统需要知道注册成功这件事,也不用关心如何通知它们,只需要把登录成功这件事转化为一个消息发送到消息中间件。这样,需要了解登录成功这件事的系统自己去消息中间件订阅就行。

《大型网站系统与Java中间件实践》-消息中间件_第2张图片
消息中间件对服务解耦

2. 互联网时代的消息中间件

消息中间件的两个重要特点解耦异步。需要思考的问题:消息的顺序保证、扩展性、可靠性、业务操作与消息发送的一致性,以及多集群订阅者问题。

2.1消息发送的一致性

《大型网站系统与Java中间件实践》-消息中间件_第3张图片
最终一致性正流向

异常分析:

  1. 业务应用发送消息给消息中间件。如果失败,业务操作没有做,消息也没有存储在消息中间件,业务操作和消息的状态是一致的,没有问题。
  1. 消息中间件把消息入库。如果失败,可能情况:消息中间件失效,应用收不到返回结果;插入消息失败,收到返回失败结果给应用。
  2. 业务应用收到消息中间件结果异常。如果有业务应用正常,业务应用不知道在消息中间件的处理结果,按照失败来处理,如果入库成功,就会造成不一致;
    如果业务应用自身有问题,消息入库成功,也会造成不一致;如果入库失败,则还是一致的。
  3. 业务应用进行业务操作。
  4. 业务应用发送业务操作结果给消息中间件。如果出现问题,消息中间件不知道如何操作存储的消息,可能会造成不一致。
  5. 消息中间件更新消息状态。出现问题同上。

从业务应用的视角分析异常情况:

异常情况 可能的状态
发送消息给消息中间件失败 业务操作未进行,消息未存储
消息发出后没有收到消息中间件响应 业务操作未进行,消息存储,待处理
业务操作未进行,消息未存储
收到消息中间件返回成功,业务操作失败 业务操作未进行,消息存储,待处理

从消息中间件的视角分析异常情况:

异常情况 可能的状态
没有收到业务应用的业务操作结果 业务操作未进行,消息存储,待处理
业务操作未进行(操作完又回滚),消息存储,待处理
业务操作成功,消息存储,待处理
收到业务应用的业务处理结果,更新消息状态失败 业务操作未进行,消息存储,待处理
业务操作未进行(操作完又回滚),消息存储,待处理
业务操作成功,消息存储,待处理

各种异常情况状态:

  1. 业务操作未进行,消息未存储
  2. 业务操作未进行,消息存储,状态待处理
  3. 业务操作成功,消息存储,状态待处理
    情况1,无需处理,因为本身一致;情况2和情况3需要进行补偿。
《大型网站系统与Java中间件实践》-消息中间件_第4张图片
最终一致性补偿流程

最终一致性接口封装伪代码:

  • 发送消息给消息中间件
  • 获取返回结果
  • 如果失败,返回失败
  • 进行业务操作
  • 获取业务操作结果
  • 发送业务操作结果给消息中间件
  • 返回处理结果
    可以把实现逻辑封装在一个调用中,然后把业务操作包装成一个对象传进来,然后整个流程就可以控制在这个方法中。

2.2消息中间件与使用者的强依赖问题

如果消息中间件系统出现问题,就会导致业务操作无法继续执行。

2.3消息重复投递

  • 分布式事务:实现复杂
  • 接收者消息处理幂等性:降低消息中间件复杂,增加接受者门槛

2.4消息优先级

局部顺序:和某件事相关的多条消息之间有顺序,创建->付款->发货->确认。

3结束

章节中很多是作者解决问题的思路和实践,所以很多就略过。

你可能感兴趣的:(《大型网站系统与Java中间件实践》-消息中间件)