马蜂窝消息总线——面向业务的消息服务设计

发布者:上海IT外包来源:http://www.lanmon.net点击数:1055

在消息总线上线前,马蜂窝大局部业务中的异步需求是经由过程 Redis 行列来实现。跟着消息量添加,经常会出现消息积压、不合消息之间互相影响的问题。为处理这些问题,电商研发团队起头规划和设计消息总线。

为什么会有消息总线,而不是让业务体系直接用 PHP 或者其他说话对接 RabbitMQ,Kafka 如许的消息体系?

「消息总线和直接使用消息系列有什么实际的区别?」,这是良多研发同窗一起头不太理解的地方。假设只是为了用一个机能更好的消息体系庖代 Redis,确实并不必要消息总线的这个脚色。

但当我们从实际业务角度动身,对公司团体手艺架构和开发场景的梳理时,创造若是直接让业务体系对接消息体系,并不是一个很好的编制,并且至少接见会面临以下问题:

体系分手。各开发团队必要维护各自的消息办事,互相之间相对隔离。

添加开举事度。用户必要关注详细消息地点消息办事的设置装备安排,关注不合业务的消息可能要对接不合品种的消息体系。

维护本钱高。用户必要办理本身斲丧办事的不变性,措置各类办事非常,保证斲丧的靠得住性。特别对付 PHP 来说,这个本钱仍是斗劲高的。

办理难度大。没法对业务消息的建树和订阅关系停止统一办理,也不便当对业务消息中的敏感数据停止权限办理。

不易扩展。无法统一消息体系扩展功能(路由、延时、重试、斲丧确认等)的使用。

总体来说,直接使用消息体系可以被算作是一个面向手艺的接入编制;而消息总线则期望经由过程潜匿安排、分组和通信等细节,实现一个面向业务的接入编制。

架构设计和手艺实现

1. 架构设计

消息总线潜匿了消息发送、路由、分组、存储、斲丧负载、通信、高可用等一些列问题。对使用者来说,只必要在发送端挪用一个 SDK 消息发送编制,在斲丧端供给一个 PHP 斲丧编制即可。

图1 马蜂窝消息总线架构设计

马蜂窝消息总线当前使用 RabbitMQ 作为消息引擎,在发送端供给了 SDK,作为消息总线的 Broker 脚色,包含了消息路由分组的功能,担任消息的 Publish。

消息的订阅关系,今朝是长期化在 MySQL 中,在消息发送时会按照订阅关系把消息送到达对应的业务斲丧者。

而在斲丧端,并没有直接用 PHP 去接入 RabbitMQ,而是使用 Deliver 办事集群 (Golang 办事) 来担任把 AMQP 和谈转为 HTTP 和谈,然后经由过程 PHPService 停止斲丧 PHP 代码的实行。

这个方案在设计时,同时考虑到了将来体系规模扩展后的消息分组,以及关头环节的可替代性。

  • SDK 充当了消息办事 Broker 的脚色,可以节制消息的路由、分组。将来在微办事体系中可以保持团体架构不变,只接纳其他方案实现 Broker。

  • 可以按照业务场景对接不合的消息引擎,比如对业务同等性要求高的业务使用 RabbitMQ,而对并发要求较高的可以使用 Kafka。对业务来说是无感知的。

  • Deliver 和 Application Service 之间可扩展更多的通信和谈,支撑应用更矫捷的斲丧编制,网罗支撑将来在微办事中的斲丧办事。

2. 手艺实现

1). 减少流转复杂度

为了保证消息在消息总线内各环节约转时减少复杂度,可以被统一措置,消息体被设计为统一的构造。首要分为以下 3 个局部:

图2 消息体的界说

  • Parameter——参数局部包含消息 ID,来历,时辰等参数。

  • Conetent——消息内容,在 PHP 中使用者可以把斲丧编制的输入参数放入 Content 中。

  • Receiver——标注了消息的领受者 (PHP 中为斲丧者的编制)。

2). 在线办事异步

点对点形式是业务中常用的一种异步形式,

图3 点对点消息形式

业务应用把不必要在同步哀求中实行的逻辑放到异步去实行。发送消息的业务必要明晰措置消息的领受者 (斲丧的 PHP 编制)。消息在发送时必要明晰指定独一的一个 Receiver。

当前经由过程消息总线 SDK 供给的 invoke 编制可以指定斲丧的应用编制。

3). 解耦

消息的公布订阅形式,是一个标准的业务解耦形式。

图4 公布订阅(播送)

App 1 的应用只担任发出消息,至于什么业务必要关注,卑劣业务应用本身订阅该消息就可以。很洪流平上减少了上游业务和卑劣业务的耦合程度和开发调试本钱。

消息总线使用 DB 来进举措静订阅关系的存储,上游业务的消息经由消息总线 Broker 时会按照订阅关系,裂变为 Receiver 是订阅应用的多条消息。如许的消息裂变编制使消息后续在消息总线流转时方针明晰,在停止斲丧负载,斲丧确认,失败重试等场景时可以按照 Receiver 停止隔离。

同样挪用方可以使用 SDK 供给的 pub 编制进举措静的发送,订阅方经由过程消息办理体系进举措静订阅的申请。

4). 防消息干扰

良多使用消息总线的同窗斗劲关怀不合消息之间是否会互相干扰,比如由于某个消息短时辰内大量涌入是否会形成其他消息被梗阻。

经由过程前面架构的引见,可以看到所有的消息经由 Broker 时可以停止路由、分组。消息总线将来会按照业务和消息量来做一些物理隔离,保障业务之间不会互相影响。

而在一个分组内,消息总线也有一些机制保障分组内的不合消息不会互相影响。

图5 防消息干扰机制

消息经由 Broker 默认会进入一个 Online Queue 的行列中,Deliver 集群中会有多个 Deliver 监听 Online Queue。在 Deliver 办事内,经由过程 Dispatcher 来节制消息总并发斲丧量,以及同类型消息的并发斲丧量。当某品种型的并发动静数目跨越阈值时,就会被转发到 Offline Queue,按捺斲丧 Worker 都被统一个类型的消息占用。而 Offline Queue 会被独立的 Deliver 办事监听停止斲丧,不影响 Online Queue 的斲丧。

5). 斲丧办事高可用

为了保证斲丧时的高可用,Deliever 群在担任停止斲丧和谈转换之外,也做了一些计策来保证斲丧端的高可用。

  • 熔断

在消息一段时辰内失败数目跨越阈值时,停止对行列的斲丧,按捺由于办事股栗和线上故障引起的大面积消息。

  • 斲丧失败

熔断后,Deliver 办事会对后端应用办事安康度停止监控,在办事恢复后可主动恢复斲丧。

  • 体系失败重试

消息总线办事产生故障时,可对时代的失败消息接纳重试计策停止重试,按捺由于根本办事问题形成的斲丧失败。

  • 业务失败重试

在业务应用斲丧时产生业务非常,可在订阅消息时指定是否停止重试。消息总线会对必要失败的消息按照必定的时辰周期停止屡次重试。

  • Graceful 重启

Deliver 实现了 Graceful 重启和退出,保障当前正在斲丧的消息都措置完成后才会历程退出。

将来规划

图7 将来演进标的目的

1. 产物化

当前消息总线在功能上经由近一年的迭代,已经根基不变。但在消息办理,监控,统计等环节对开发者来说还不够友爱,接下来一段时辰会侧重优化体系的易用性。

今朝已经在规划以下标的目的的优化改进:

开发者可以经由过程消息办理体系停止新增消息,订阅消息 (参加权限的审核) 等把持,庖代当前手工提 issue 的编制。

开发者可以经由过程体系关注到本身消息的斲丧情形,并实时领受到消息措置非常的报警。

完满监控体系,供给更邃密维度的体系监控数据。

2. 微办事

关于在微办事架构内供给消息总线办事,也已经在方案傍边。网罗在微办事内进举措静发送和使用某个微办事进举措静的斲丧。将来整个消息总线方案会往下图的架构停止演进,添加对多说话和不合架构办事的支撑。顺应更多的业务开发场景,供给更不变,友爱的消息总线办事。

别的对消息引擎的手艺选型,将来也会考虑接入 Kafka,RocketMQ 等其他消息行列办事。按照不合业务场景的消息特征,在公布时选择进入不合的消息行列办事。比如对靠得住性,数据安然性要求高的消息会进入 RabbitMQ,而对高吞吐量的消息可以进入 Kafka。但对消息的发送方和订阅方来说都可以不消关怀这些细节,仍然按照统一的编制停止接入。

IT外包
>
400-635-8089
立即
咨询
电话咨询
服务热线
400-635-8089
微信咨询
微信咨询
微信咨询
公众号
公众号
公众号
返回顶部