微服务间通信形式次要有 2 种:RPC 和消息传递。
通常来说在申请 / 响应的场景下应用 RPC 更加适合,具体实现通常是 REST API 或者基于长链接的协定(例如 gRPC/Thrift/Zero ICE 等)。两个服务有比拟强的依赖关系,调用者依赖被调用者的处理结果,调用者解决该申请被梗塞以期待响应后果,同时还要进行负载平衡、限流、熔断、错误处理等。通常是同步的、一对一的交互,异步 RPC 实质也是要期待响应后果能力持续解决该申请。
消息传递以异步音讯作为载体,通过事件代理(消息中间件)连贯音讯解决的上游和上游,上游和上游涣散耦合,通常上游的解决逻辑不依赖上游的处理结果,具体实现通常有发布者 / 订阅者和事件流等。而事件驱动架构(EDA)就是基于消息传递,通过解耦生成、传输和处理事件,协调事件生产者、消息中间件、消费者工作的一种架构模式,具备涣散耦合、流量削峰、非阻塞、易于扩大、更高的弹性和错误处理能力等长处。不过也带来性能损耗、复杂性等方面的问题。
推送零碎的业务状态
在推送零碎中,一个推送申请的解决流程大抵如下:
- 接管申请,进行用户身份认证、参数校验、申请权限校验
- 申请解析,构建推送工作
- 依据推送工作,筛选推送指标用户,以及获取推送指标用户的根本信息
- 依据推送策略以及各推送指标用户的信息抉择推送通道执行推送工作
- 各推送通道负责具体的推送操作。
从业务场景看,极光推送均匀每秒接管 2 万~3 万的推送申请,包含 regid、tag、alias、播送等推送形式。各推送指标的推送指标用户数量也不同,少则几个,多则几千万甚至上亿的指标数量。极光反对多推送通道,客户能够依据须要抉择应用哪个通道进行推送,各个通道因为服务质量、地区间隔等方面的因素,申请耗时、稳定性各有不同,此外还有各自的限速逻辑。业务面临着很大的挑战:
- 接管内部推送申请数大,峰值尖刺甚至可能翻倍
- 一个推送申请可能产生大量的音讯,例如一个播送或者一个大 tag 推送,有千万级别的指标用户,意味着一个推送申请扩充为千万级别的零碎外部申请。
- 整个零碎中同时解决的音讯体量十分大,常态化的业务峰值超过千万级别,并且一天工夫有多个峰值,不可准确预测。
- 解决流程中波及多个解决环节,各个环节的处理速度并不相同,甚至有可能有微小的差别,例如某些推送通道解决快,某些通道推送解决绝对慢。
推送零碎如何应用事件驱动晋升零碎的整体性能
从客户的需要和产品需要登程,心愿每个申请可能疾速、正确地响应并解决,可能及时地把音讯推送给每个指标用户。因而咱们须要解决大量音讯以最快的速度推送的问题。
从业务的角度看,能够从租户分级、租户隔离、推送形式、推送指标规模等维度进行部署隔离,减小各租户、各申请间的相互影响,更加疾速更加稳固地解决整个推送申请,提供更好的服务质量。
从纯技术角度看,采纳了多种技术手段和策略,包含缓存优化、异步解决、并行处理等,晋升整体性能,实现更高效的推送操作和更好的零碎稳定性。
其中采纳事件驱动架构来组织整个解决流程,并行、异步解决,实现零碎整体性能的晋升,并且在突增流量、异样解决方面都可能很不便地应答。
推送流程的 EDA 实现
首先,将上述流程简化为多个外围解决环节,并构建为服务,通过消息中间件进行交互。
- pushAPI 接管申请,构建推送工作
- segmentGateway 筛选推送指标用户,抉择推送通道,执行推送工作
- pushChannel 负责各个推送通道的推送操作,其中蕴含多个具体的推送通道。
各服务基于事件传递状态转移(Event Carried State Transfer)或者事件告诉(Event Notification)模式生成事件音讯,而后投递到消息中间件中。同时各服务通过音讯队列或者订阅的形式从消息中间件生产音讯,依据理论须要由消息中间件推送事件音讯给消费者或者由消费者被动拉取事件音讯。对于反复音讯的解决,通常有 Exactly once 和 At least once + 业务幂等性解决,倡议以第二种形式解决。
注:消息中间件的选型、音讯投递服务质量的原理不在本文的形容范畴,未开展阐明。
pushAPI 接管推送申请,生成推送工作事件音讯,而后投递到消息中间件。消息中间件依据相干信息发送到指定队列中。
segmentGateway 生产指定队列,生产其中的事件音讯。通过解决后(查问指标用户和相干根本信息),批量填充各推送通道的指标用户到推送工作,并生成新的推送工作事件音讯投递到消息中间件中。消息中间件依据相干信息发送到各推送通道相干的队列中。
pushChannel 的各推送通道服务生产各自的队列,执行推送操作。
以上流程中,事件音讯的生产者不须要消费者的处理结果,消费者也不依赖生产者,齐全解耦。
EDA 解决推送零碎的痛点
并行处理: 各服务多节点部署,并行处理申请 / 音讯,当服务呈现性能不足以解决业务时,K8S 环境下减少节点正本数横向扩容即可;此外同一个推送申请通过不同推送通道推送时,多个推送通道并行推送音讯。
异步解决: 各服务专一本人的业务逻辑,不依赖业务上游,通常也不受上游的影响,无需期待处理结果,整个流程异步解决,缩小闲暇等待时间,能够最大化利用资源。
异样解决: 当有突增流量时,申请流量压力过大,超过了某个解决环节的所有服务节点的解决能力;或者某个推送通道因为网络抖动、网络中断等解决慢。这些服务节点作为消息中间件的消费者,因为解决能力有余或者解决变慢,未来得及解决的申请沉积在消息中间件,期待扩容或者采取其余解决措施。缓存申请到消息中间件中,从某种程度上也是背压(Back Pressure)模式的一种解决形式,当然还能够进一步的向上游反馈负载压力信息,由上游采取解决措施。例如大量音讯须要推送到苹果的推送服务,因为网络稳定或者苹果服务器限流,可能呈现推送变慢,这个时候推送 iOS 音讯可能会沉积在消息中间件中;其余推送通道并不受此影响,仍然可能失常地疾速推送音讯给其余通道。
其余: 涣散耦合使各服务更加独立,在进行业务变更时(包含代码逻辑变更和公布变更)通常影响面很小,某些状况下甚至可能不影响上下游逻辑,例如某些推送通道没有进行推送速率的限度,当减少限速逻辑时只影响该通道的服务,对于其余通道和上游服务都不影响。
借助 EDA,极光推送可能轻松解决高并发推送申请,实现数千万级别的音讯的疾速推送,有更大的弹性应答不可预测的、更大流量的音讯推送,以及有更好的异样解决能力。
将来的瞻望:ServiceMesh/EvenMesh 混合架构,对立平台化
实际上,在极光推送零碎中,同时存在 2 种通信形式,例如在下面的推送流程中,须要依据推送形式获取推送指标用户以及相干根本信息,须要从其余子系统服务通过 RPC 进行查问获取后果。整个推送零碎的其余性能也是如此,依据业务场景、数据 / 业务量级做衡量取舍,抉择适合的架构模式来构建零碎,保证系统整体性能以及零碎的可用性、可维护性。
为了让开发者更专一地解决外围的业务代码逻辑,缩小各种通信交互的解决细节(例如超时解决、限流等),目前申请 / 响应的模式比拟支流的做法是 Service Mesh,并且经验了 Sidecar/Proxyless/Sidecarless 几种模式的倒退,也做了各种衡量取舍。
EDA 也有绝对应的模式,Event Mesh 就是其中之一,通过创立可能高效牢靠地解决工作的网状代理网络,解决大规模事件驱动架构的挑战,包含事件路由、发现和交付,实现跨简单分布式系统的事件驱动通信。
咱们的推送零碎实际上是混合 2 个通信形式的架构,更现实、更适宜咱们的架构应该是二者并存。
咱们也继续关注相干技术,在充沛验证的状况下引入相干技术,放弃架构继续更新优化,防止架构腐化,保障推送零碎的高性能、高可用性、高可维护性。
对于极光
极光(Aurora Mobile,纳斯达克股票代码:JG)成立于 2011 年,是中国当先的客户互动和营销科技服务商。成立之初,极光专一于为企业提供稳固高效的音讯推送服务,凭借先发劣势,曾经成长为市场份额遥遥领先的挪动音讯推送服务商。随着企业对客户触达和营销增长需要的不断加强,极光前瞻性地推出了音讯云和营销云等解决方案,帮忙企业实现多渠道的客户触达和互动需要,以及人工智能和大数据驱动的营销科技利用,助力企业数字化转型。