博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
面向业务的微服务消息总线
阅读量:4036 次
发布时间:2019-05-24

本文共 2315 字,大约阅读时间需要 7 分钟。

源宝导读:移动PaaS项目的异步场景中,随着订阅主题数的增加,会出现开发维护成本高、管理难度大等问题,本文将分享如何通过构建面向业务的微服务消息总线应对这些问题。

一、背景

    面向业务的消息总线本质上是对消息队列进行二次封装,而不是让各业务服务直接对接消息中间件。在微服务架构设计下,面向业务的消息总线是服务间异步通信、解耦的核心基础设施。

二、为什么需要消息总线

    在没有消息总线前,移动PaaS项目中的异步请求都是通过直连RabbitMQ来实现,PHP开发的服务往往需要借助Swoole之类的第三方扩展来实现消费端常驻进程消费。当异步任务不多的时候没有问题,但随着订阅主题数的增加,这种客户端消费模式逐渐显现出以下几个缺点:

  • 开发成本高,需要业务服务引入消息中间件SDK需要关注消息中间件的各种复杂繁琐的配置,不同微服务的实现有大量重复逻辑。

  • 维护成本高,PHP的业务服务需要起很多消费容器来跑多进程消费,浪费系统资源,发布部署很麻烦。多语言下的消费实现方式不统一。

  • 管理难度大,随着订阅关系复杂,Topic日益增多,服务之间的订阅关系变得不清晰。

  • 扩展成本高,无法统一消息系统扩展功能,如路由、延时、重试、消费确认等。

    从实际业务角度出发,对整个移动PaaS项目中涉及消息通信的业务场景进行梳理,得出以下几个核心需求点:

  • 集中的消息发布入口,生产端无需关注消息系统的实现细节和复杂配置。

  • 集中化的微服务间订阅关系维护,通过在统一的面板上管理维护订阅关系。

  • 集中化的消息消费,通过集中消费消息,根据微服务间的订阅关系来推送消息。

  • 支持多种协议gRPC、http。

    总体来说,直接使用消息系统可以被看成是一个面向技术的接入方式;而消息总线则期望通过隐藏消息中间件的内部细节,实现一个面向业务的接入方式。

三、架构设计和技术实现

3.1、架构设计

    消息总线隐藏了消息发送、超时处理、消费负载、通信等一系列问题。对于使用者来说,只需要调用一个http或者gRPC接口就能发送消息,无需集成消息系统SDK。在PaaS2.0中消息总线使用RabbitMQ 作为消息引擎,实现了消息生产端的集中发送,并且通过RabbitMQ 的死信队列实现对消息的超时控制。下图为PaaS2.0中消息总线的架构图。

3.2、技术实现

统一消息格式

    提供简单易用的消息体格式,使用者可以很方便的完成一条消息的发送。

{    "id": "5675682526732228",   //消息的id    "timeout": 30,   //超时时间    "topic": "event.workspace.delete",  //消息主题    "content": {} //消息内容 }

统一声明交换机

使用死信队列来处理消息超时

    RabbitMQ的ttl超时属性可以设置在消息上也可以设置在队列上,但是设置到消息上时消息的超时校验只有在消息被消费时才能生效,这就会导致超时控制不精准。所以通过设置超时队列将不同的超时时间设置到不同的队列上,并且绑定死信队列,这样消费端在消息超时的时候就能得到通知。

    PaaS2.0中实现了消息生产端的集中发送,不仅统一了消息体的格式而且也简化了消息超时控制。但是仍然没有解决消费订阅管理、集中消费的问题。

    作为PaaS平台,必须具备开放能力,服务间的通信边界可能会延伸到系统间的通信,比如支持webhook。所以集中式消息消费,消息订阅关系管理成为消息总线迭代的方向。

    下图为基于消息总线实现的webhook。

  • MessageBusBroker 消息发送端服务  用于接收消息写入MQ。

  • MessageBusDeliver 消息投递服务  用于消费MQ中的消息根据订阅关系触发消息通知。

  • MessageBusAdmin  消息总线管理服务  用于服务管理、主题管理、订阅关系维护以及配置参数调整。

 

四、2.0版消息总线架构设计

    2.0版本的消息总线主要屏蔽了消息发送、存储、消费负载、通信、高可用等一系列技术问题,对业务开发者来说只需要调用SDK即可,简化了接入流程并提升了可靠性。同时在PaaS系统中,消息总线也作为WebHook能力的基础设施。

    消息总线整体架构图如下图所示:

  • Publish Service通过集成SDK向Message发送消息。

  • Deliver Service通过订阅关系向相关的服务和站点发起通知请求实现webhook。

  • 消费端服务通过特殊状态码来完成消息确认。

消费端的高可用保证

    为了保证消费时的高可用,Deliever除了在负责进行消费协议转换之外,通过一些策略来保证消费端的高可用。

  • 熔断限流,消费在消息一段时间内失败数据超过阈值时,停止对队列的消费,避免由于服务抖动或者线上故障引起的大面积消息消费失败。

  • 自恢复,熔断后Deliver服务会对应用服务健康度进行监控,在服务恢复后可自动恢复消费。

  • 失败重试,消息总线服务发生故障时,可对期间的失败消息采用重试策略进行重试,在业务应用消费产生异常时,可在订阅消息时指定是否进行重试

  • 优雅重启,Deliver可实现优雅重启和退出,保障当前正在消费的消息都处理完成后才退出进程。

五、总结

    面向业务的消息总线设计的目标,本质上是为了服务间解耦,降低业务开发的复杂度,让业务开发不去关注消息通信细节,从而实现业务的快速迭代,消息系统也可以根据不同的业务场景选用不同的消息引擎。消息总线的设计重点和难点集中在消费端的处理。

------ END ------

作者简介

段同学: 后端研发工程师,目前负责天际移动PaaS平台的研发工作。

也许您还想看

转载地址:http://wsudi.baihongyu.com/

你可能感兴趣的文章
Q24:二叉搜索树的后序遍历序列
查看>>
Q25:二叉树中和为某一值的路径
查看>>
Q27:二叉搜索树与双向链表
查看>>
Best Time to Buy and Sell Stock
查看>>
Binary Tree Zigzag Level Order Traversal
查看>>
ZigZag Conversion
查看>>
[leetcode]:Two Sum
查看>>
leetcode: 3Sum
查看>>
leetcode:3sum closet
查看>>
【剑指offer】面试题37:两个链表的第一个公共结点
查看>>
【剑指offer】面试题39:二叉树的深度
查看>>
【剑指offer】面试题28的习题:正方体,八皇后
查看>>
【剑指offer】面试题42:单词翻转顺序&左右旋转字符串
查看>>
【剑指offer】面试题43:n个骰子的点数
查看>>
堆排序及其相关操作
查看>>
【剑指offer】 堆排序查找最小的K个数
查看>>
【剑指offer】q50:树中结点的最近祖先
查看>>
二叉树的非递归遍历
查看>>
【leetcode】Reorder List (python)
查看>>
【leetcode】Linked List Cycle (python)
查看>>