马蜂窝消息总线——面向业务的消息服务设计
App 1 的应用只负责发出消息,至于什么业务需要关注,下游业务应用自己订阅该消息就可以。很大程度上减少了上游业务和下游业务的耦合程度和开发调试成本。
消息总线使用 DB 来进行消息订阅关系的存储,上游业务的消息经过消息总线 时会根据订阅关系,裂变为 是订阅应用的多条消息。这样的消息裂变方式使消息后续在消息总线流转时目标明确,在进行消费负载,消费确认,失败重试等场景时可以按照 进行隔离。
同样调用方可以使用 SDK 提供的 pub 方法进行消息的发送,订阅方通过消息管理系统进行消息订阅的申请。
4). 防消息干扰
很多使用消息总线的同学比较关心不同消息之间是否会相互干扰,比如由于某个消息短时间内大量涌入是否会造成其他消息被阻塞。
通过前面架构的介绍,可以看到所有的消息经过 时可以进行路由、分组。消息总线未来会根据业务和消息量来做一些物理隔离,保障业务之间不会相互影响。
而在一个分组内,消息总线也有一些机制保障分组内的不同消息不会相互影响。
图5 防消息干扰机制
消息经过 默认会进入一个 Queue 的队列中, 集群中会有多个 监听 Queue。在 服务内,通过 来控制消息总并发消费量,以及同类型消息的并发消费量。当某种类型的并发消息数量超过阈值时,就会被转发到 Queue,避免消费 都被同一个类型的消息占用。而 Queue 会被独立的 服务监听进行消费,不影响 Queue 的消费。
5). 消费服务高可用
为了保证消费时的高可用, 群在负责进行消费协议转换之外,也做了一些策略来保证消费端的高可用。
◆ 熔断
在消息一段时间内失败数量超过阈值时,停止对队列的消费,避免由于服务抖动和线上故障引起的大面积消息。
◆ 消费失败
熔断后, 服务会对后端应用服务健康度进行监控,在服务恢复后可自动恢复消费。
◆ 系统失败重试
消息总线服务发生故障时,可对期间的失败消息采用重试策略进行重试,避免由于基础服务问题造成的消费失败。
◆ 业务失败重试
在业务应用消费时产生业务异常,可在订阅消息时指定是否进行重试。消息总线会对需要失败的消息按照一定的时间周期进行多次重试。
◆ 重启
实现了 重启和退出,保障当前正在消费的消息都处理完成后才会进程退出。
未来规划
图7 未来演进方向 1. 产品化
当前消息总线在功能上经过近一年的迭代,已经基本稳定。但在消息管理,监控,统计等环节对开发者来说还不够友好,接下来一段时间会着重优化系统的易用性。
目前已经在规划以下方向的优化改进:
开发者可以通过消息管理系统进行新增消息,订阅消息 (加入权限的审核) 等操作,代替当前手工提 issue 的方式。
开发者可以通过系统关注到自己消息的消费情况,并及时接收到消息处理异常的报警。
完善监控体系,提供更精细维度的系统监控数据。
2. 微服务
关于在微服务架构内提供消息总线服务,也已经在计划当中。包括在微服务内进行消息发送和使用某个微服务进行消息的消费。未来整个消息总线计划会往下图的架构进行演进,增加对多语言和不同架构服务的支持。适应更多的业务开发场景,提供更稳定,友好的消息总线服务。
另外对消息引擎的技术选型,未来也会考虑接入 Kafka, 等其他消息队列服务。根据不同业务场景的消息特性,在发布时选择进入不同的消息队列服务。比如对可靠性,数据安全性要求高的消息会进入 ,而对高吞吐量的消息可以进入 Kafka。但对消息的发送方和订阅方来说都可以不用关心这些细节,仍然按照统一的方式进行接入。
马蜂窝消息总线服务当前也在不断迭代中,在很多地方还有不少没有考虑到的问题。欢迎大家多提宝贵意见,您可以扫描下方二维码订阅「马蜂窝技术」更多内容。