介绍
BEN(best-effort-notify)是基于最大努力通知的分布式事务解决方案。
中文文档
- 中文文档地址:https://www.showdoc.cc/cnben
源码地址
架构图
节点角色说明
节点 | 角色说明 |
---|---|
消息中间件 | 提供消息队列功能,ActiveMQ、RocketMQ等 |
通知服务子系统 | 业务服务实现(存储通知记录、存通知日志、更新通知状态查询等) |
通知恢复子系统 | BEN系统重启后,恢复未完成的通知记录,继续通知 |
通知监控子系统 | 监控系统内存、堆积消息数,当达到阈值时发送告警邮件 |
通知管理子系统 | 通知可视化管理后台,通知记录查看、重发、删除、通知日志查看等 |
DelayQueue | JDK自带延时队列,实现在指定时间触发通知请求 |
流程说明
假设两个业务系统的两个业务AB。基于BEN实现分布式事务流程如下:
- 上层业务系统在完成业务处理之后,向消息中间件发送通知消息。
- BEN系统监听通知消息队列,监听到通知消息后添加通知记录到数据库。
- 根据系统配置的通知时间,设置通知任务执行时间,放入DelayQueue。
- 通知任务达到执行时候后,发送Http请求给下层业务系统。
- 添加通知日志到数据库。
异常情况处理
- Http请求异常:网络波动或下层业务系统Down机时(Http请求超时或响应码为5xx)。
- 下层业务处理失败:下层业务系统未返回处理成功。
1. 通知记录会被标记为对应状态,并且添加通知日志。然后通知任务会根据系统配置的通知时间间隔,设定下次通知时间,放入DelayQueue,继续通知。
2. 下层业务系统需事先业务的幂等性
3. 当通知次数超过系统配置的最大次数,通知记录会被标记为通知失败,不再继续通知。可在通知管理子系统人工干预(删除或重新通知)。
通知监控子系统
内存监控
业务主动方(通知消息生产方)产生消息的速率超过业务被动方(通知消息消费方)的消费速率,就会导致消息驻留在内存中,为了防止内存溢出等情况,提前发送告警邮件。
计算公式
JVM剩余内存 < JVM最大内存 * 系统配置阈值百分比
应对策略
- 发送告警邮件。
- 通知任务在保存到数据库后,只执行一次通知,无论通知成功或失败,更新通知结果到数据库,并将任务信息从内存中释放,内存监听器将休眠一段时候后重新计算内存情况,直到内存足够后,从数据库中读取休眠期间未通知成功的通知记录,继续通知。
通知监控
用于监控系统堆积的通知任务数,并发送告警邮件
如果业务被动方(通知消息消费方)停机,而业务主动方(通知消息生产方)依然继续产生通知消息,可能会导致大量通知任务由于通知异常,驻留在内存中,为了防止内存溢出等情况,提前发送告警邮件。
计算公式
- 堆积任务数 > 系统配置阈值数量
- 每分钟新增堆积任务的速率 > 系统配置阈值速率