目录
架构目标
推送能力的演进
第一阶段(模块化):各自为政、各自封装
第二阶段(框架化):集成框架
第三阶段(服务化):推送服务
推送服务在业务系统中的位置
推送服务功能要求
推送非功能性需求(NFR)
推送系统设计架构
1. 通知客户端
2. 通知服务
3. 模板服务
4. 消息分发服务
5. 事件优先级队列(消息队列)
6. 通用出站处理程序
7. 通知适配器
8. 通道供应商
9. 用户选择服务
10. 用户配置文件服务
11. 分析服务
12. 通知跟踪器
13. 通知数据库:Mysql数据库集群
构建企业级统一基础推送服务,支持通过多渠道推送,能够统一集成的电子邮件、短信、聊天、钉钉、企业微信和其他公共社交应用:
聊天 - 微信Wechat/QQ
站内推送通知(移动设备和Web浏览器)
站外推送通知(移动设备,APP没有开启)
短信(如登录密码、营销活动)
电子邮件
钉钉
企业微信
企业级统一基础推送服务,是一个通用特性,适用于所有现代分布式应用,无论采用何种编程语言和技术。
企业内部,早期业务量比较少,各系统基本都是有自己的推送模块,类型也是五花八门:
聊天模块
短信模块
电子邮件模块
websocket 模块
各自封装模块比较简单,但是实现分散、各系统模块的质量也很难统一保证。
为了减少重复性设计、开发成本, 设计了统一的推送框架
同一套微服务框架,共用一个统一的推送框架
为了解决上述分散实现的问题,企业内部统一实现了一个综合各类推送功能的基础库,供业务方统一调用。
聊天基础starter
短信基础starter
电子邮件基础starter
websocket 基础starter
于是,我们把 springboot-starter的逻辑封装到了服务治理框架内,微服务服务启动时,每一个服务对各种的starter进行运维管理、配置管理。
集成到框架,每一套服务,都需要重复性的解决3高问题。
推送服务,数据量大,需要解决跨库查询问题
推送服务,性能要求高,需要解决高并发问题
大数据量、并发量高,意味着:
硬件资源投入大
运维成本高
这样的基础服务,需要进行沉淀,剥离,集中成统一的、基础服务,由专门团队负责维护、迭代、运维。降低重复投入、重复建设成本, 真正的降本增效。
于是, 推送框架 演进为 推送服务
一个业务应用, 基本上有很多原子服务编排、整合而来,最终构建出一个完整的架构图。
接入层,这是外部请求进入内部系统的门户,所有的请求都必须通过 API 网关。
应用层,也被称为聚合层,它为相关业务提供聚合接口,并调用中台服务进行组合。
原子服务,包括就是原子技术服务,原子业务服务,根据业务需求提供相关的接口。原子服务为整个架构提供可复用的能力。
例如,在B站视频网站平台上,评论服务作为一项原子服务,在B站的视频、文章、社区都需要,那么为了提高复用性,评论服务就可以独立为原子服务,不能与特定需求紧密耦合。
在这种情况下, 评论服务,需要供一种可以适应不同场景的复用能力。
类似的,文件存储、数据存储、推送服务、身份验证服务等功能,都会沉淀为原子服务,业务开发人员,在原子服务基础上,进行编排、配置、组合,可以快速构建业务应用。
发送通知
对通知进行优先级排序
根据客户的保存偏好发送通知
支持单个/简单的通知消息和批量通知消息
各种通知的分析用例
通知消息的报告
高性能:qps > 1W
高可用性(HA):99.99%
低延迟:TP99 在10ms以下
高扩展:可扩展/可插拔的设计,以便添加更多适配器和提供商,与所有通知模块的API集成以及与客户端和服务提供商/供应商的外部集成
跨平台:支持Android/iOS移动设备和桌面/笔记本电脑的Web浏览器
自伸缩:可在本地(VMware Tanzu)和 AWS、GCP 或 Azure 等公共云服务上扩展负载
这些解决方案设计的考虑因素和组件包括:
这些客户端通过 API 调用请求单个和批量消息。它们将向简单和批量通知服务发送通知消息。
简单通知客户端:专门用于发送单个通知的客户端,负责向用户发送单一通知。这些客户端通常用于向特定用户发送重要通知,例如密码找回或账户异常提醒。
批量通知客户端:专门用于发送批量通知的客户端,负责向用户批量推送通知。这些客户端通常用于需要通知大量用户的场景,例如企业内部通知或营销活动。
作为入口点的这些服务,通过暴露 REST API 与客户端互动。
它们负责构建通知消息,通过调用"模板服务"。这些消息将使用"验证服务"进行验证。
简单通知服务:该服务将提供 API,主要负责处理简单通知请求,提供与后端服务集成的 API,以便将通知发送给用户。这种服务通常用于处理较少的通知请求,例如针对特定用户或事件的简单通知。
批量通知服务:该服务将提供 API,主要负责处理批量通知请求,提供与后端服务集成的 API,以便批量发送通知。这种服务通常用于处理大量的通知请求,例如企业内部的批量通知或营销活动的批量推送。
此服务还将管理通知消息。它将发送的消息持久化到数据库并维护活动日志。
可以使用这些服务的 API 重新发送同一条消息。
它将提供添加/更新/删除和查看旧消息和新消息的 API。
它还将提供 Web 仪表板,该仪表板应具有筛选选项,以根据不同的条件(如日期范围、优先级、模块用户、用户组等)筛选消息。
此服务主要负责所有可用的一次性密码(OTP)、短信、电子邮件、聊天以及其他推送通知消息的模板管理。
它还提供了 REST API,以便创建、更新、删除和管理模板。
除此之外,它还将提供一个用户界面(UI)的仪表板页面,使用户能从网络控制台检查和管理各种消息模板。
定时分发服务:
该服务将提供API来安排立即或指定时间的通知。可以是以下任何一种:
秒
分钟
每小时
每天
每周
每月
每年
自定义频率等。
还可能有其他自动触发的服务,基于预定时间进行消息触发。
消息验证服务:
此服务全权负责根据业务规定和预期格式对通知信息进行核实。批量通知需由授权的系统管理员同意。
消息优先级服务:
该服务负责对通知进行优先级排序,分为高、中、低三个等级。
通知信息具有较高的优先级和有时间限制的到期时间,它们将始终以较高优先级发送。
"通用出口处理器"会接收消息并根据相同的优先级从高、中和低三个不同的队列中发送和处理。
在非工作时间,可以以低优先级发送批量通知。
在交易过程中的应用程序通知可以发送到中优先级,如电子邮件等。企业可以根据通知的重要性确定优先级。
此服务提供事件中心功能,负责接收通知服务的高、中、低三个优先级的信息。
它会根据业务的优先级来发送和接收通知。企业可以根据通知的重要性来设定优先级。
服务内部包含三个主题,用于根据业务优先级接收和发送通知:
低优先级:主要用于在非工作时间发送批量通知。
中优先级:适用于在交易过程中发送的应用程序通知,如电子邮件等。
高优先级:通知信息具有较高的优先级和有时间限制的到期时间,它们将始终以较高优先级发送。
该服务通过轮询事件优先级队列来接收事件中心中的通知信息,并根据其优先级进行处理。
高优先级的通知会优先处理"高"队列,依次类推。
最后,它通过事件中心将通知信息发送到特定的适配器。
此外,该服务还从用户选择服务中获取目标用户/应用程序,以便进行通知的分发。
在处理过程中,通用出口处理器会根据事件的优先级进行相应的操作,确保重要事件得到优先处理。
这样,企业可以根据通知的优先级来确定处理顺序,从而提高通知的处理效率。
除此之外, 通用出站处理程序,还能进行消息的进一步按照通道类型进行分发:
该服务将消息发送到各种支持的适配器。
这些适配器会根据不同的设备(如桌面/移动设备)和通知类型(如短信/OTP/电子邮件/聊天/推送通知)进行转换。
这些转换器将从消息队列(rocketmq)接收传入信息并根据其所支持的格式传递给外部合作伙伴。
以下是一些转换器,根据需求可以增加更多:
QQ 通知适配器服务
微信Wechat 聊天通知适配器服务
应用内通知适配器服务
电子邮件适配器服务
短信适配器服务
OTP 适配器服务
这些是外部的 SAAS(云上/本地)服务提供商,利用它们的基础设施和技术实现实际的通知传递。
它们可能是像 AWS SNS、MailChimp 等的付费推送通道服务。
QQ 供应商集成服务
微信Wechat 供应商集成服务
应用推送通知供应商集成服务
电子邮件供应商集成服务
短信供应商集成服务
该服务提供选择目标用户和各种应用程序模块的功能。
这可能包括将批量消息发送到特定的用户组或不同的应用程序模块。
可能是 AD/IAM/eDirectory/用户数据库/用户组,具体取决于客户的偏好。
在服务内部,它将使用"用户配置文件服务"API 来消费和检查客户的通知偏好。
此服务提供各种功能,包括管理用户配置文件及其偏好设置。
还管理内部用户标识,和外部通道标识之间的关联关系
钉钉用户标识 和 用户标识 关联关系
企业微信 用户标识 和 用户标识 关联关系
用户和邮箱的关联关系
等等
它还将提供取消订阅通知以及通知接收频率等功能。
"通知服务"将依赖于此服务,以便根据用户的通知偏好来发送通知。
此外,该服务还可以用于统计和分析用户对通知的偏好,以帮助企业优化通知策略。
该处理器将负责执行所有的分析工作,识别通知使用情况、趋势并生成报告。
它将从分析数据库(Cassandra)和通知数据库中提取所有最终的通知信息,用于分析和报告目的。
以下是一些用例:
每天/每秒的总通知数
哪个通知系统使用最频繁
消息的平均大小和频率
基于优先级过滤消息等等...
此服务将持续监视事件中心队列并跟踪所有发送的通知。
它捕获通知的元数据,如传输时间、传送状态、通信渠道、消息类型等。
通知数据库,用于存储库用于存储所有通知信息,包括发送时间、状态等。
它包括一个数据库集群,其中领导者用于执行所有写操作,读取操作则在读取副本/跟随者上进行。
这个数据库群集将持久化所有通知,供分析和报告使用。
它基于“写入更多,读取更少”的理念。
它能提供良好的性能和低延迟,适应大量的通知,因为它内部处理大量的写操作,并与其他数据库节点同步,保持高可用性和可靠性的冗余数据/消息。
在任何节点崩溃的情况下,消息将始终可用。
当然,也可以是 nosql 集群型数据库。