需求分析案例:消息配置中心
本文介绍了一个很常见的消息推送需求,在系统需要短信、微信、邮件之类的消息推送时,边界如何划分和如何设计技术方案。
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,甚至可以提供全局统一的消息查看界面,可以查看所有的消息类型,消息渠道,推送与否等内容;
我找了一张京东云的消息中心图片参考:

统一的消息配置中心
负责配置每种消息的发送与否,以及每种消息进行发送的阈值(下图没画),配置界面参考:

消息配置中心的主要工作流程如下:

注:这个图把所有业务的消息开关,全部集中在消息配置中心服务,并且因为消息配置中心是一个单独的服务,它拥有独立的数据库设计,而上面的支付服务虽然也使用了消费者,但是因为设计师把它当成支付服务的一部分,一般会直接复用支付服务的数据库,跟支付服务耦合在一起。
相关文章:
需求分析案例:消息配置中心
本文介绍了一个很常见的消息推送需求,在系统需要短信、微信、邮件之类的消息推送时,边界如何划分和如何设计技术方案。 1、需求 一个系统,一般会区分多个业务模块,并拆分成不同的业务系统,例如一个商城的架构如下&am…...
自动化测试——环境
一、搭建环境 1、安装Slenium pip install selenium 2、安装浏览器驱动-》查询浏览器版本-》下载对应版本驱动-》在path路径中配置(浏览器更新需要重新下载) pip install webdriver -helper(自动化)python3.9以上 pip install 安…...
短视频矩阵营销系统技术开发者开发笔记分享
一、开发短视频seo抖音矩阵系统需要遵循以下步骤: 1. 确定系统需求:根据客户的需求,确定系统的功能和特点,例如用户注册登录、视频上传、视频浏览、评论点赞等。 2. 设计系统架构:根据系统需求,设计系统的…...
vue2和vue3引用ueditor的区别
官方文档入口 UEditor Docs vue2使用方式 UE.vue组件 <template><div><script id"editor" type"text/plain"></script><Upload v-if"isupload" :config"{total:9}" :isupload"isupload" ret…...
【每日运维】RockyLinux8非容器化安装Mysql、Redis、RabitMQ单机环境
系统版本:RockyLinux 8.6 安装方式:非容器化单机部署 安装版本:mysql 8.0.32 redis 6.2.11 rabbitmq 3.11.11 elasticsearch 6.7.1 前置条件:时间同步、关闭selinux、主机名、主机解析host 环境说明:PC电脑VMware Work…...
第一次后端复习整理(JVM、Redis、反射)
1. JVM 文章仅为自身笔记 详情查看一篇文章掌握整个JVM,JVM超详细解析!!! 1.1 什么是JVM jvm是Java虚拟机 1.2 Java文件的编译过程 程序员编写代码形成.java文件经过javac编译成.class文件再通过JVM的类加载器进入运行时数据…...
python的web学习(一)-初识django
文章目录 软件创建项目默认项目文件说明App的概念(应用)apps.py编写URL和视图函数对应关系【urls.py】编写视图函数【views.py】启动服务 软件 python下载 django下载 创建项目 django-admin startproject 文件名默认项目文件说明 项目名 manage.py(项目管理,启…...
JavaWeb+jsp+Tomcat的叮当书城项目
点击以下链接获取源码: https://download.csdn.net/download/qq_64505944/88123111?spm1001.2014.3001.5503 技术:ssm jsp JDK1.8 MySQL5.7 Tomcat8.3 源码数据库课程设计 功能:管理员与普通用户和超级管理员三个角色,管理员可…...
【嵌入式Linux系统开发】——系统移植概述
目录 🍉🍉一、什么是嵌入式系统 🍉🍉二、嵌入式系统操作 🍉🍉三、嵌入式Linux的特点 🍉🍉四、嵌入式系统的组成 1、硬件和软件 2、硬件层 3、中间层 4、软件层 5、 功能层与执…...
升讯威在线客服系统是如何实现对 IE8 完全完美支持的(怎样从 WebSocket 降级到 Http)【干货】
简介 升讯威在线客服与营销系统是基于 .net core / WPF 开发的一款在线客服软件,宗旨是: 开放、开源、共享。努力打造 .net 社区的一款优秀开源产品。 完整私有化包下载地址 💾 https://kf.shengxunwei.com/freesite.zip 当前版本信息 发布…...
用VMware给运行在VMware上的CentOS7生成一个以SSH方式连接VMware上的CentOS7的运行在Windows上的命令行窗口
2023年7月27日,周四早上 目录 一个发现生成方法如果上面的方法连接失败,就采取这个方法 一个发现 今天早上无意间发现VMware可以生成一个以SSH方式连接着CentOS7的Windows命令行窗口, 这样做可以带来一定的便利性 : 方便复制、…...
C语言基础-3
1、函数 函数是C语言代码的基本组成部分,它是一个小的模块,整个程序由很多个功能独立的模块(函数)组成。这就是程序设计的基本分化方法。 main:C语言中所谓的主函数,主函数就是一种特别的函数。特别之处在于…...
Python 编程规范进阶(1) | 命名规范
养成良好的开发、编程习惯 跟着google开源项目走 https://github.com/google/styleguide 近期Target: 命名规范; Pythonic 积累 按照需求写需要的API; 写前先动脑子,比如画流程图,测试接口; Google 推荐的P…...
算法----二叉搜索树中第K小的元素
题目 二叉搜索树中第K小的元素 给定一个二叉搜索树的根节点 root ,和一个整数 k ,请你设计一个算法查找其中第 k 个最小元素(从 1 开始计数)。 示例 1: 输入:root [3,1,4,null,2], k 1 输出ÿ…...
阿里Java开发手册~安全规约
1. 【强制】隶属于用户个人的页面或者功能必须进行权限控制校验。 说明: 防止没有做水平权限校验就可随意访问、修改、删除别人的数据,比如查看他人的私信 内容、修改他人的订单。 2. 【强制】用户敏感数据禁止直接展示,必须对展示数据进…...
消息中间件RabbitMQ——学习笔记
❤ 作者主页:欢迎来到我的技术博客😎 ❀ 个人介绍:大家好,本人热衷于Java后端开发,欢迎来交流学习哦!( ̄▽ ̄)~* 🍊 如果文章对您有帮助,记得关注、点赞、收藏、…...
爬虫005_python类型转换_其他类型转换为整型_转换为Float类型_转换为字符串_转换为布尔值---python工作笔记023
首先来看,字符串转换成int 很简单 float转换成int 会把小数点后面的内容丢掉 boolean转换为int true是1 false 是0 然后字符串转换为int,要注意 不能有特殊字符比如1.23 中有点 就报错 上面字符串12ab,有ab也报错 看上面...
SpringBoot复习:(5)使用PropertySource注解
一、自定义的一个配置文件 age33 nameliu二、实体类 package com.example.demo.domain;public class Student {private String name;private int age;public String getName() {return name;}public void setName(String name) {this.name name;}public int getAge() {retur…...
webrtc 支持H265(三) 总结
文章目录 web端的解码及渲染的实现应用场景单向视频流的场景datachannel通道的稳定性解码性能 双向视频流的场景有音频流的场景 web端的解码及渲染的实现 在前面的文章中介绍了ZLMediaKit的修改方法,在web端的播放器可以参照这个实现,基于wasm H265播放…...
Windows使用Notepad++编辑Linux服务器的文件
🚀 Windows使用Notepad编辑Linux服务器的文件 🚀 🌲 算法刷题专栏 | 面试必备算法 | 面试高频算法 🍀 🌲 越难的东西,越要努力坚持,因为它具有很高的价值,算法就是这样✨ 🌲 作者简介…...
Linux应用开发之网络套接字编程(实例篇)
服务端与客户端单连接 服务端代码 #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <arpa/inet.h> #include <pthread.h> …...
synchronized 学习
学习源: https://www.bilibili.com/video/BV1aJ411V763?spm_id_from333.788.videopod.episodes&vd_source32e1c41a9370911ab06d12fbc36c4ebc 1.应用场景 不超卖,也要考虑性能问题(场景) 2.常见面试问题: sync出…...
【杂谈】-递归进化:人工智能的自我改进与监管挑战
递归进化:人工智能的自我改进与监管挑战 文章目录 递归进化:人工智能的自我改进与监管挑战1、自我改进型人工智能的崛起2、人工智能如何挑战人类监管?3、确保人工智能受控的策略4、人类在人工智能发展中的角色5、平衡自主性与控制力6、总结与…...
Unity3D中Gfx.WaitForPresent优化方案
前言 在Unity中,Gfx.WaitForPresent占用CPU过高通常表示主线程在等待GPU完成渲染(即CPU被阻塞),这表明存在GPU瓶颈或垂直同步/帧率设置问题。以下是系统的优化方案: 对惹,这里有一个游戏开发交流小组&…...
Objective-C常用命名规范总结
【OC】常用命名规范总结 文章目录 【OC】常用命名规范总结1.类名(Class Name)2.协议名(Protocol Name)3.方法名(Method Name)4.属性名(Property Name)5.局部变量/实例变量(Local / Instance Variables&…...
Psychopy音频的使用
Psychopy音频的使用 本文主要解决以下问题: 指定音频引擎与设备;播放音频文件 本文所使用的环境: Python3.10 numpy2.2.6 psychopy2025.1.1 psychtoolbox3.0.19.14 一、音频配置 Psychopy文档链接为Sound - for audio playback — Psy…...
项目部署到Linux上时遇到的错误(Redis,MySQL,无法正确连接,地址占用问题)
Redis无法正确连接 在运行jar包时出现了这样的错误 查询得知问题核心在于Redis连接失败,具体原因是客户端发送了密码认证请求,但Redis服务器未设置密码 1.为Redis设置密码(匹配客户端配置) 步骤: 1).修…...
算法岗面试经验分享-大模型篇
文章目录 A 基础语言模型A.1 TransformerA.2 Bert B 大语言模型结构B.1 GPTB.2 LLamaB.3 ChatGLMB.4 Qwen C 大语言模型微调C.1 Fine-tuningC.2 Adapter-tuningC.3 Prefix-tuningC.4 P-tuningC.5 LoRA A 基础语言模型 A.1 Transformer (1)资源 论文&a…...
Spring是如何解决Bean的循环依赖:三级缓存机制
1、什么是 Bean 的循环依赖 在 Spring框架中,Bean 的循环依赖是指多个 Bean 之间互相持有对方引用,形成闭环依赖关系的现象。 多个 Bean 的依赖关系构成环形链路,例如: 双向依赖:Bean A 依赖 Bean B,同时 Bean B 也依赖 Bean A(A↔B)。链条循环: Bean A → Bean…...
[免费]微信小程序问卷调查系统(SpringBoot后端+Vue管理端)【论文+源码+SQL脚本】
大家好,我是java1234_小锋老师,看到一个不错的微信小程序问卷调查系统(SpringBoot后端Vue管理端)【论文源码SQL脚本】,分享下哈。 项目视频演示 【免费】微信小程序问卷调查系统(SpringBoot后端Vue管理端) Java毕业设计_哔哩哔哩_bilibili 项…...
