需求分析案例:消息配置中心

本文介绍了一个很常见的消息推送需求,在系统需要短信、微信、邮件之类的消息推送时,边界如何划分和如何设计技术方案。

1、需求

一个系统,一般会区分多个业务模块,并拆分成不同的业务系统,例如一个商城的架构如下(懒得画,网上找了一张):
在这里插入图片描述

里面会有各种服务,每个服务都会有一些消息通知逻辑,例如:

  • 用户管理:
    • 用户注册成功,需要推送一条站内信,欢迎用户并说明一些商城的介绍之类;
    • 用户登录:如果判断此次登录存在风险,比如跟上次登录的IP、地域有变化,要发邮件或短信通知用户及时修改密码;
    • 关注微信公众号:要给用户推送微信公众号消息表示欢迎;
  • 库存管理:
    • 库存不足时,给商家发短信和微信推送,提醒补充库存;
  • 支付管理:
    • 支付成功:给用户推送微信公众号通知成功;
    • 支付失败:给用户推送微信公众号和站内信通知,并提供链接方便用户再次支付;
    • 超时未支付:给用户发短信、推送微信公众号和站内信通知,提醒用户及时支付;
  • 风控管理:
    • 出现可疑操作时,给用户发短信、推送微信公众号通知等等,提示用户风险行为;
  • 物流管理:
    • 发货通知:推送微信公众号和站内信通知,提醒用户已发货;

2、边界思考

统一的消息服务搭建

基于这些消息通知的需求,为了避免每个模块都进行重复开发,很容易考虑到一个点,就是增加一个消息模块:

  • 对外统一对接各种消息服务:
    • 不同的邮箱服务,如网易邮箱、谷歌邮箱、微软邮箱等等;
    • 微信推送服务,用户关注后记录用户的微信OpenID,以便给用户推送消息;
    • 对接短信网关,根据公司需要,可能要对接多家短信服务商,以便故障切换或价格比对;
    • 站内信通知:提供公司内部统一的,或整个系统统一的站内信通知能力;
    • 其它:如手机移动推送能力、Facebook、Twitter、Instagram等等。
  • 对内提供统一的接口,供所有模块调用和进行消息推送
    • 通常为每个模块提供一个appId、appSecuret,以便进行接口鉴权;
    • 统一接口输入字段一般包括:
      • appId:用于识别是哪一个应用要发消息
      • msgType:要推送的消息类型,如微信、短信、站内信、邮件
      • msgDetail:要推送的消息对象,根据消息类型,定义不同的字段,如:
        • 短信只有模板ID和占位符替换内容
        • 站内信只有标题和内容
        • 邮件有标题、内容、接收人、抄送人、附件、是否HTML邮件等等
      • sign:根据上述字段+对应的appSecuret计算得到的签名信息,可以用md5、sha1等算法加盐实现

一般情况下,这个消息模块,会在公司级统一开发一个,这样就不仅仅是单个系统不重复造轮子,
甚至是整个公司的所有产品线,都不需要再重复造轮子了。
具体流程,可以参考我之前写过的一个短信登录的文章,里面画了一个流程图:https://youbl.blog.csdn.net/article/details/127124527

消息服务使用的具体实现

我见过的很多系统,基本到上一步就算模块拆分结束了,就继续每个模块的设计去了。
以支付服务为例,消息推送的流程简述如下:
在这里插入图片描述
有经验的程序员,知道这么设计会有技术隐患,消息服务接口出现问题时,会把支付服务搞挂,还会引入MQ消息中间件进行优化,如下图:
在这里插入图片描述
注意:这个MQ消息,跟上面说的消息不一样:

  • MQ消息:是程序进行事件中转的一种消息机制,一般只提供给下游的程序,不会被用户直接观测到;
  • 上面说的消息:指短信、邮件、站内信等,直接触达到用户的消息,是为用户提供信息的消息。

进一步问题发现

系统上线一段时间后,用户量大了,一定会有用户反馈,比如:

  • 我不需要支付失败的通知啊,能不能关闭;
  • 几块钱的支付成功消息就别推了,能不能超过100块才推消息;

如果只是支付服务,那很简单,在支付服务这边调用API时,做个判断处理就好。
但是加判断的时候,会不会感觉很别扭?一些非核心逻辑,会导致支付服务的代码不断变化?

而且其它的服务,慢慢也要增加类似的逻辑:消息推送开关、推送阈值判断等等。
这些类似的逻辑,因为分布在不同的服务代码里,无法重用。

有没有办法把这些代码合并呢?比如使用SDK的形式是否OK呢?

我们回到需求本身,再思考一下,比如支付服务,给用户发消息,是不是属于这个支付服务的业务范围呢?
支付成功给用户推支付成功的消息,看上去是支付业务。
但是:
支付成功,要给用户发货,我们知道这个发货不属于支付服务的业务范围,而是物流服务的业务,
一般实现是物流服务监听支付成功事件,触发发货事件,
那么推理一下,发消息给用户,也应该不是支付服务的业务。

那么,发消息给用户是消息模块的业务范围吗?很明显不是,消息模块,我们前面的定义,是对接各种消息渠道,减少各个业务对这些渠道的耦合,而消息要不要发,怎么发,明显不应该属于这个消息模块的业务范围。

我们能不能把消息开关、消息改善阈值处理,单独部署一个模块呢?把所有服务的“消息要不要发,怎么发”的逻辑全部合并在这里呢?
答案当然是可以,参考我们上次的餐厅排队发券需求,排队超时发券看上去是排队业务,实际上是营销业务,不应该影响排队服务的正常逻辑,
怎么发消息同样不应该让业务过多的关心,每个业务方,比如支付服务,只关心支付这个动作,并在相应节点抛出事件,就完事了,后续是要发货,还是要发消息,都是外部的业务,不应该让支付服务来操心。

3、最后的设计与实现

统一的消息服务

负责提供站内信通知能力,并负责对接各种消息渠道,如微信、短信、邮件等等,减少各个业务对这些渠道的耦合,具体参考上面的文字描述。
消息服务不仅可以提供API,甚至可以提供全局统一的消息查看界面,可以查看所有的消息类型,消息渠道,推送与否等内容;
我找了一张京东云的消息中心图片参考:
在这里插入图片描述

统一的消息配置中心

负责配置每种消息的发送与否,以及每种消息进行发送的阈值(下图没画),配置界面参考:
在这里插入图片描述
消息配置中心的主要工作流程如下:
在这里插入图片描述
注:这个图把所有业务的消息开关,全部集中在消息配置中心服务,并且因为消息配置中心是一个单独的服务,它拥有独立的数据库设计,而上面的支付服务虽然也使用了消费者,但是因为设计师把它当成支付服务的一部分,一般会直接复用支付服务的数据库,跟支付服务耦合在一起。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/12737.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

webpack基础配置

webpack基础 webpack 处理css兼容问题webpack 处理css闪屏问题webpack 优化压缩css代码总结webpack 两种开发模式webpack 基本的功能webpack配置 5概念devServer 生产环境webpack配置实例开发环境webpack配置实例webpack优化 webpack 处理css兼容问题 下载loader 引入 package…

day45-Netflix Mobile Navigation(左边侧边栏动态导航)

50 天学习 50 个项目 - HTMLCSS and JavaScript day45-Netflix Mobile Navigation&#xff08;左边侧边栏动态导航&#xff09; 效果 index.html <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8" /><meta name&…

k8s集群安装v1.20.9

参考网上资料并将异常问题解决&#xff0c;经测试可正常安装集群。 1.我的环境准备 本人使用vmware pro 17新建三个centos7虚拟机&#xff0c;每个2cpu&#xff0c;20GB磁盘存储&#xff0c;内存2GB&#xff0c;其中主节点的内存3GB&#xff0c;可使用外网. 2.所有节点安装D…

33. 本地记事本

本地记事本 html部分 <button class"add"><i class"iconfont icon-jiahao"></i> </button>css部分 *{margin: 0;padding: 0; } body{background-color: #7bdaf3;display: flex;padding-top: 3rem;flex-wrap: wrap; } .add{pos…

每日一题——删除有序数组中的重复项

删除有序数组中的重复项 题目链接 注&#xff1a;本题所采用的方法是建立在移除元素的基础之上的&#xff0c;如果大家对双指针的方法不大了解&#xff0c;或者不会做《移除元素》这一题&#xff0c;建议先去看看&#x1f449;传送门 具体步骤 定义两个指针slow和fast&#…

【计算机网络】传输层协议 -- UDP协议

文章目录 1. 传输层相关知识1.1 端口号1.2 端口号范围划分1.3 知名端口号1.4 一些相关命令 2. UDP协议2.1 UDP协议格式2.2 UDP协议的特点2.3 什么是面向数据报2.4 UDP的缓冲区2.5 UDP使用注意事项2.6 基于UDP的应用层协议 1. 传输层相关知识 传输层是计算机网络中的一个重要层…

【如何训练一个中英翻译模型】LSTM机器翻译模型部署之onnx(python)(四)

系列文章 【如何训练一个中英翻译模型】LSTM机器翻译seq2seq字符编码&#xff08;一&#xff09; 【如何训练一个中英翻译模型】LSTM机器翻译模型训练与保存&#xff08;二&#xff09; 【如何训练一个中英翻译模型】LSTM机器翻译模型部署&#xff08;三&#xff09; 【如何…

云原生架构

1. 何为云原生&#xff1f; 很多IT业内小伙伴会经常听到这个名词&#xff0c;那么什么是云原生呢&#xff1f;云原生是在云计算环境中构建、部署和管理现代应用程序的软件方法。 当今时代&#xff0c;众多企业希望构建高度可扩展、灵活且有弹性的应用程序&#xff0c;以便能够快…

OAID学习

为了在包含用户隐私的同时&#xff0c;让广告商可以了解用户在应用中的行为&#xff0c;安卓系统提供了OAID&#xff08;Open Anonymous Device Identifier&#xff09;用来跟踪设备。OAID是一种非永久的、近似唯一的设备标识符&#xff0c;由字母和数字组成&#xff0c;长度不…

13 亿美金买个寂寞?No!AI 时代的数据行业蓄势待发

6月底&#xff0c;全球数据分析领域彻底炸锅了。 两大数据分析企业Databricks和Snowflake纷纷将目光瞄准了AI大模型。要知道&#xff0c;这两位对手平时没少对台戏&#xff0c;为性能、产品和技术经常开撕。但在今年的自家大会上&#xff0c;两家企业却出奇的一致&#xff0c;…

用sqoop导出hive parquet 分区表到mysql

用sqoop导出hive parquet 分区表到mysql 确保你已经安装并配置好了Sqoop工具&#xff0c;并且可以连接到Hadoop集群和MySQL数据库。 创建一个MySQL表来存储导出的数据。请确保MySQL表的结构与Hive Parquet分区表的结构匹配。 使用Sqoop的export命令来执行导出操作。以下是一…

Mybatis 动态 sql 是做什么的?都有哪些动态 sql?能简述动态 sql 的执行原理不?

OGNL表达式 OGNL&#xff0c;全称为Object-Graph Navigation Language&#xff0c;它是一个功能强大的表达式语言&#xff0c;用来获取和设置Java对象的属性&#xff0c;它旨在提供一个更高的更抽象的层次来对Java对象图进行导航。 OGNL表达式的基本单位是"导航链"&a…

云安全攻防(二)之 云原生安全

云原生安全 什么是云原生安全&#xff1f;云原生安全包含两层含义&#xff1a;面向云原生环境的安全和具有云原生特征的安全 面向云原生环境的安全 面向云原生环境的安全的目标是防护云原生环境中的基础设施、编排系统和微服务系统的安全。这类安全机制不一定会具有云原生的…

关于vue3 按钮权限的控制,使用自定义指令来实现

关于vue3 按钮权限的控制&#xff0c;使用自定义指令来实现 需求 根据不同的权限展示或者隐藏按钮 实现 使用自定义指令来控制按钮&#xff0c;当有权限时就显示&#xff0c;没有就移除元素 代码 src/directives/components/button-permission.ts components文件下可以创…

flutter开发实战-请求dio设置Cookie

flutter开发实战-请求dio设置Cookie 在最近开发中碰到了需要websocket长链接收到响应的auth&#xff0c;在之后的请求中需要将其设置为cookie中。 如Cookie:authDHSfQQSAXf89xZqJTLdEDVI2hwzc7p2lUmSNNdUSlgW2MyfQINpYr7jUbkX/; 设置cookie用到了dio_cookie_manager组件 一、…

Java 设计模式 - 简单工厂模式 - 创建对象的简便之道

简单工厂模式是一种创建型设计模式&#xff0c;它提供了一种简单的方式来创建对象&#xff0c;而无需暴露对象创建的逻辑。在本篇博客中&#xff0c;我们将深入了解简单工厂模式的概念、实现方式以及如何在Java中使用它来创建对象。 为什么使用简单工厂模式&#xff1f; 在软…

JMM的特征:可见性,有序性,原子性

1.volatile关键字(保证可见性、有序性) volatile关键字可以有效的保证可见性和有序性。一旦一个共享变量被volatile修饰后&#xff0c;保证了线程在工作内存中对变量进行操作的可见性&#xff0c;一个线程修改了其值&#xff0c;对其他线程来说是立即可见的。而且禁止对程序的…

【无标题】深圳卫视专访行云创新马洪喜:拥抱AI与云原生,深耕云智一体化创新

人工智能&#xff08;AI&#xff09;是引领新一轮科技革命和产业变革的重要驱动力。因此&#xff0c;深圳出台相关行动方案&#xff0c;统筹设立规模1,000亿元的人工智能基金群&#xff0c;引导产业集聚培育企业梯队&#xff0c;积极打造国家新一代人工智能创新发展试验区和国家…

【高压架构】AP5199S LED平均电流型恒流驱动IC 0.01调光 景观舞台汽车灯驱动照明

说明 AP5199S 是一款外围电路简单的多功能平均电流型 LED 恒流驱动器&#xff0c;适用于宽电压范围的非隔离式大功率恒流 LED 驱动领域。芯片 PWM 端口支持超小占空比的 PWM 调光&#xff0c;可响应 60ns 脉宽。为客户提供解决方案&#xff0c;限度地发挥灯具优势&#xff0c;…

解锁ChatGPT的潜能:API调用中运用聊天记录

在过去我通过chatgpt调用api时只知道进行孤立的调用&#xff0c;即这一次调用时&#xff0c;chatgpt并没有拿到上一次调用的上下文&#xff0c;这无疑损失很大。通过探索&#xff0c;我知道了如何通过修改messages这个字典类型的list来告知chatgpt我和它的聊天历史。 关键代码…