面向业务的微服务消息总线

源宝导读:移动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平台的研发工作。

也许您还想看

Hybrid-APP技术原理

微前端架构在容器平台的应用

前端数据层落地实践

移动建模平台元数据存储架构演进

AI云店小程序演变之路

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/305299.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

java locale.us_JAVA实现国际化

## 1 Java国际化的思路Java程序的国际化的思路是将程序中的标签、提示等信息放在资源文件中,程序需要支持哪些国家、语言环境,就对应提供相应的资源文件。资源文件是key-value对,每个资源文件中的key是不变的,但value则随不同国家…

模拟时钟中断的产生及设计一个对时钟中断事件进行处理的模拟程序_操作系统基础6-支持操作系统的最基本的硬件-中断...

无论是桌面PC操作系统还是嵌入式都是多任务的操作系统,而很遗憾,处理器往往是单个的,即便在硬件成本逐渐下降,而硬件配置直线上升的今天,PC机的核心可能已经达到4核心,8核心&#xf…

XMLhttp学习应用

Client.htm页面代码如下: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns"http://www.w3.org/1999/xhtml"><head><title>客…

机器学习没有想象中的那么难

文末彩蛋&#xff0c;不容错过&#xff01;背景从去年的AlphaGo到今年人工智能首次写进政府工作报告&#xff0c;人工智能正在席卷全球&#xff0c;引发第4次工业革命&#xff0c;而AI的核心技术是机器学习和深度学习。目前&#xff0c;机器学习已广泛应用于数据挖掘、计算机视…

json.net java_java解析JSON (使用net.sf.json)

例如JSON字符串str如下&#xff1a;{"data": [{"basic_title": "运筹帷幄因特网","basic_creator": "马跃&#xff0c;余南阳编著","basic_publisher": "成都市&#xff1a;西南交通大学出版社","…

Docker查看应用的实际内存

前言 我们把应用部署到Docker里面之后&#xff0c;有什么办法查看这个应用占用了多少内存呢&#xff1f;docker本身提供了一个命令让我们可以直接看到当前时间所有容易占用的情况。docker stats --no-stream从上面来看&#xff0c;这几个应用用的内存加起来已经是将近12G了。但…

如何动态的生成某种类型的集合呢_知乎画报」的移动端动态化工程实践

本文基于移动端动态化方案在知乎原生推广落地页「知乎画报」上的实践经验&#xff0c;对该方案技术升级过程中的思考以及技术关键细节做了详尽的解读。商业化是互联网公司发展的重要阶段&#xff0c;App 端的商业广告业务对移动端动态化能力的需求很强烈&#xff0c;一方面需要…

asp.net 得到上一页地址

if(!IsPostBack) ViewState["retu"]Request.UrlReferrer.ToString();

任正非致歉华为前程序员:回来吧,公司错了

近几日&#xff0c;因着任正非连续签发邮件&#xff0c;无处不在热议华为&#xff0c;其中与所有的技术人可谓密切相关。除了一员工因说真话&#xff0c;被晋升两级&#xff0c;根据其自愿选择工作岗位及地点&#xff0c;并由无线网络产品线总裁邓泰华保护其不受打击报复之外&a…

Asp.Net Core之Identity应用(下篇)

一、前言在上篇中简单介绍了 Asp.Net Core 自带的 Identity,一个负责对用户的身份进行认证的框架&#xff0c;当我们按需选择这个框架作为管理和存储我们应用中的用户账号数据的时候&#xff0c;就会添加到自己的项目当中去。这个时候&#xff0c;默认情况我们会使用自带的数据…

python随机数生成验证码_Python随机数random模块学习,并实现生成6位验证码

一、前言学习python随机数random模块的使用 ,并使用模块中的函数&#xff0c;实现6位验证码生成二、random模块1、random.random()返回0-1直接的随机数&#xff0c;类型为float>>>print(random.random())0.12591846916629082、random.randint(1, 8)返回1-8直接的随机数…

python没有菜单栏怎么搞mac_Mac 下 sublime 怎么调出顶端菜单栏

点击Sublime的Preferences->Setting-Default菜单&#xff0c;打开它的配置文件。找到如下一行的配置&#xff1a;"fold_buttons": true&#xff0c;值为true则是显示三角折叠按钮&#xff0c;反之则不显示。当然了&#xff0c;不推荐直接改它的默认配置文件&#…

如果每一种语言都对应一种女生,你会喜欢哪一个?

这几天调试都很顺利&#xff0c;今天很意外的不要加班&#xff0c;哥几个看着窗外还是白天&#xff0c;还有点不适应。没想到哥几个突然开始YY&#xff1a;如果每种语言都对应一种女生&#xff0c;你会喜欢哪一个&#xff1f;程序猿寂寞起来&#xff0c;我自己都害怕。碍于人数…

asp.net core安全事项(下)

越权越权是非常严重的安全漏洞&#xff0c;通常状态是开发人员对请求的限制逻辑不严格导致的。如果系统中有角色的概念&#xff0c;越权可能出现不同角色间的越权和同角色间的越权。相同角色&#xff1a;A用户&#xff0c;B用户是相同的角色。A用户和B用户都可以调用 /photo/{i…

[导入]php 安全基础 第八章 共享主机 文件系统浏览

8.4. 文件系统浏览 除了能在共享服务器上读取任意文件之外&#xff0c;攻击者还能建立一个可以浏览文件系统的脚本。由于你的大多数敏感文件不会保存在网站主目录下&#xff0c;此类脚本一般用于找到你的源文件的所在位置。请看下例&#xff1a; <pre> <?php if (iss…

python求函数极值_python 遗传算法求函数极值的实现代码

废话不多说&#xff0c;大家直接看代码吧&#xff01;"""遗传算法实现求函数极大值—Zjh"""import numpy as npimport randomimport matplotlib.pyplot as pltclass Ga():"""求出二进制编码的长度"""def __init__…

java读取文件跳过_在Java中读取文本文件-为什么跳过行?

我是新来的,只是努力尝试读取文本文件.每行上都有一个单词和相应的数字代码.想法是将其读取并将代码和单词放在单独的变量中.我对这个领域了解不多,但是我一直在网上四处寻找,并提出了以下建议&#xff1a;try{FileReader freadernew FileReader(f);BufferedReader inFilenew B…

程序员的项目周期(表情包版)

0. 需求审评会议进行中1. 开发阶段进行中….2. 代码复查阶段3. 测试阶段….4. 需求突然要改….5. 项目上线

巧用Dictionary实现日志数据批量插入

背景最近再做一个需求&#xff0c;就是对站点的一些事件进行埋点&#xff0c;说白了就是记录用户的访问行为。那么这些数据怎么保存呢&#xff0c;人家点一下保存一下&#xff1f;显然不合适&#xff0c;肯定是需要批量保存&#xff0c;提高效率。问题窥探首先&#xff0c;我想…