微服务消息架构中通用邮件服务事件驱动方案选型
通用邮件服务实现方案选型结论
优先选方案2(搭建独立通用邮件队列,由业务服务投递标准send_email事件),两种方案的实际差异和注意事项如下:
- 方案1本质是职责倒挂,长期维护成本极高
邮件服务本来是不感知业务逻辑的通用基础组件,结果反过来要监听所有业务队列、记全所有业务事件的格式和触发规则,直接把业务和基础服务的边界打穿了:每加个发邮件的新场景,就得改邮件服务代码、加新的队列绑定;业务侧随便改个事件字段、换个事件名,都可能把邮件发送搞挂。后面业务队列做消费限流、重试、死信策略的时候,还得额外考虑邮件服务这个非业务消费者,平白多一堆跨团队协调的破事。小团队两三个人总共两三个服务的时候临时凑活用能跑,只要服务数上了五个、团队分了不同业务组,这方案很快就变成没人敢碰的历史屎山。 - 方案2是符合服务边界的合理设计
邮件服务就守好自己的通用邮件队列,只认标准格式的send_email事件,把模板渲染、发送重试、频率限制、发件人路由、失败告警这些和邮件相关的逻辑全收敛在自己服务里,根本不用管上游是用户注册、订单付款还是找回密码触发的发送请求。业务侧要发邮件就按约定格式往队列丢消息就行,不用管邮件到底怎么发出去的,两边迭代互不干扰,加新的发邮件场景根本不用改邮件服务的代码。
多消费者场景的补充疑问解答
不需要让业务服务手动同时投递两类事件,这是典型的重复逻辑散落在各业务端的坏实践:
你只需要选用支持发布/订阅(Pub/Sub)模式的消息中间件即可:业务服务只需要往自己对应的业务Topic投递一次原生业务事件(比如
user_created),需要消费该事件做业务逻辑处理的服务,直接订阅对应业务Topic消费即可。如果不想让各业务服务自己拼接
send_email消息格式、手动投递到邮件队列,可以加一层极薄的统一事件转换逻辑:单独部署一个轻量消费者,订阅所有需要触发邮件的业务事件,按照预先配置的规则把业务事件转换成标准send_email格式,再投递到通用邮件队列就行。千万别把投递两类消息的逻辑散在各个业务服务代码里,不然后续业务迭代漏投、错投、消息格式不统一的问题会层出不穷,排查问题要跨N个服务翻日志,维护成本极高。把事件转邮件的逻辑收敛在一个地方统一维护,后续要改触发规则、调整邮件模板参数只需要改这一处,成本低很多。
内容的提问来源于stack exchange,提问作者Luka Mikavica
相关产品推荐
相关产品推荐

