当前位置: 首页 > news >正文

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

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

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单机环境

系统版本&#xff1a;RockyLinux 8.6 安装方式&#xff1a;非容器化单机部署 安装版本&#xff1a;mysql 8.0.32 redis 6.2.11 rabbitmq 3.11.11 elasticsearch 6.7.1 前置条件&#xff1a;时间同步、关闭selinux、主机名、主机解析host 环境说明&#xff1a;PC电脑VMware Work…...

第一次后端复习整理(JVM、Redis、反射)

1. JVM 文章仅为自身笔记 详情查看一篇文章掌握整个JVM&#xff0c;JVM超详细解析&#xff01;&#xff01;&#xff01; 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(项目管理&#xff0c;启…...

JavaWeb+jsp+Tomcat的叮当书城项目

点击以下链接获取源码&#xff1a; https://download.csdn.net/download/qq_64505944/88123111?spm1001.2014.3001.5503 技术&#xff1a;ssm jsp JDK1.8 MySQL5.7 Tomcat8.3 源码数据库课程设计 功能&#xff1a;管理员与普通用户和超级管理员三个角色&#xff0c;管理员可…...

【嵌入式Linux系统开发】——系统移植概述

目录 &#x1f349;&#x1f349;一、什么是嵌入式系统 &#x1f349;&#x1f349;二、嵌入式系统操作 &#x1f349;&#x1f349;三、嵌入式Linux的特点 &#x1f349;&#x1f349;四、嵌入式系统的组成 1、硬件和软件 2、硬件层 3、中间层 4、软件层 5、 功能层与执…...

升讯威在线客服系统是如何实现对 IE8 完全完美支持的(怎样从 WebSocket 降级到 Http)【干货】

简介 升讯威在线客服与营销系统是基于 .net core / WPF 开发的一款在线客服软件&#xff0c;宗旨是&#xff1a; 开放、开源、共享。努力打造 .net 社区的一款优秀开源产品。 完整私有化包下载地址 &#x1f4be; https://kf.shengxunwei.com/freesite.zip 当前版本信息 发布…...

用VMware给运行在VMware上的CentOS7生成一个以SSH方式连接VMware上的CentOS7的运行在Windows上的命令行窗口

2023年7月27日&#xff0c;周四早上 目录 一个发现生成方法如果上面的方法连接失败&#xff0c;就采取这个方法 一个发现 今天早上无意间发现VMware可以生成一个以SSH方式连接着CentOS7的Windows命令行窗口&#xff0c; 这样做可以带来一定的便利性 &#xff1a; 方便复制、…...

C语言基础-3

1、函数 函数是C语言代码的基本组成部分&#xff0c;它是一个小的模块&#xff0c;整个程序由很多个功能独立的模块&#xff08;函数&#xff09;组成。这就是程序设计的基本分化方法。 main&#xff1a;C语言中所谓的主函数&#xff0c;主函数就是一种特别的函数。特别之处在于…...

Python 编程规范进阶(1) | 命名规范

养成良好的开发、编程习惯 跟着google开源项目走 https://github.com/google/styleguide 近期Target&#xff1a; 命名规范&#xff1b; Pythonic 积累 按照需求写需要的API&#xff1b; 写前先动脑子&#xff0c;比如画流程图&#xff0c;测试接口&#xff1b; Google 推荐的P…...

算法----二叉搜索树中第K小的元素

题目 二叉搜索树中第K小的元素 给定一个二叉搜索树的根节点 root &#xff0c;和一个整数 k &#xff0c;请你设计一个算法查找其中第 k 个最小元素&#xff08;从 1 开始计数&#xff09;。 示例 1&#xff1a; 输入&#xff1a;root [3,1,4,null,2], k 1 输出&#xff…...

阿里Java开发手册~安全规约

1. 【强制】隶属于用户个人的页面或者功能必须进行权限控制校验。 说明&#xff1a; 防止没有做水平权限校验就可随意访问、修改、删除别人的数据&#xff0c;比如查看他人的私信 内容、修改他人的订单。 2. 【强制】用户敏感数据禁止直接展示&#xff0c;必须对展示数据进…...

消息中间件RabbitMQ——学习笔记

❤ 作者主页&#xff1a;欢迎来到我的技术博客&#x1f60e; ❀ 个人介绍&#xff1a;大家好&#xff0c;本人热衷于Java后端开发&#xff0c;欢迎来交流学习哦&#xff01;(&#xffe3;▽&#xffe3;)~* &#x1f34a; 如果文章对您有帮助&#xff0c;记得关注、点赞、收藏、…...

爬虫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的修改方法&#xff0c;在web端的播放器可以参照这个实现&#xff0c;基于wasm H265播放…...

Windows使用Notepad++编辑Linux服务器的文件

&#x1f680; Windows使用Notepad编辑Linux服务器的文件 &#x1f680; &#x1f332; 算法刷题专栏 | 面试必备算法 | 面试高频算法 &#x1f340; &#x1f332; 越难的东西,越要努力坚持&#xff0c;因为它具有很高的价值&#xff0c;算法就是这样✨ &#x1f332; 作者简介…...

JavaSec-RCE

简介 RCE(Remote Code Execution)&#xff0c;可以分为:命令注入(Command Injection)、代码注入(Code Injection) 代码注入 1.漏洞场景&#xff1a;Groovy代码注入 Groovy是一种基于JVM的动态语言&#xff0c;语法简洁&#xff0c;支持闭包、动态类型和Java互操作性&#xff0c…...

Android Wi-Fi 连接失败日志分析

1. Android wifi 关键日志总结 (1) Wi-Fi 断开 (CTRL-EVENT-DISCONNECTED reason3) 日志相关部分&#xff1a; 06-05 10:48:40.987 943 943 I wpa_supplicant: wlan0: CTRL-EVENT-DISCONNECTED bssid44:9b:c1:57:a8:90 reason3 locally_generated1解析&#xff1a; CTR…...

多模态2025:技术路线“神仙打架”,视频生成冲上云霄

文&#xff5c;魏琳华 编&#xff5c;王一粟 一场大会&#xff0c;聚集了中国多模态大模型的“半壁江山”。 智源大会2025为期两天的论坛中&#xff0c;汇集了学界、创业公司和大厂等三方的热门选手&#xff0c;关于多模态的集中讨论达到了前所未有的热度。其中&#xff0c;…...

RocketMQ延迟消息机制

两种延迟消息 RocketMQ中提供了两种延迟消息机制 指定固定的延迟级别 通过在Message中设定一个MessageDelayLevel参数&#xff0c;对应18个预设的延迟级别指定时间点的延迟级别 通过在Message中设定一个DeliverTimeMS指定一个Long类型表示的具体时间点。到了时间点后&#xf…...

利用ngx_stream_return_module构建简易 TCP/UDP 响应网关

一、模块概述 ngx_stream_return_module 提供了一个极简的指令&#xff1a; return <value>;在收到客户端连接后&#xff0c;立即将 <value> 写回并关闭连接。<value> 支持内嵌文本和内置变量&#xff08;如 $time_iso8601、$remote_addr 等&#xff09;&a…...

基于uniapp+WebSocket实现聊天对话、消息监听、消息推送、聊天室等功能,多端兼容

基于 ​UniApp + WebSocket​实现多端兼容的实时通讯系统,涵盖WebSocket连接建立、消息收发机制、多端兼容性配置、消息实时监听等功能,适配​微信小程序、H5、Android、iOS等终端 目录 技术选型分析WebSocket协议优势UniApp跨平台特性WebSocket 基础实现连接管理消息收发连接…...

ServerTrust 并非唯一

NSURLAuthenticationMethodServerTrust 只是 authenticationMethod 的冰山一角 要理解 NSURLAuthenticationMethodServerTrust, 首先要明白它只是 authenticationMethod 的选项之一, 并非唯一 1 先厘清概念 点说明authenticationMethodURLAuthenticationChallenge.protectionS…...

Python如何给视频添加音频和字幕

在Python中&#xff0c;给视频添加音频和字幕可以使用电影文件处理库MoviePy和字幕处理库Subtitles。下面将详细介绍如何使用这些库来实现视频的音频和字幕添加&#xff0c;包括必要的代码示例和详细解释。 环境准备 在开始之前&#xff0c;需要安装以下Python库&#xff1a;…...

无人机侦测与反制技术的进展与应用

国家电网无人机侦测与反制技术的进展与应用 引言 随着无人机&#xff08;无人驾驶飞行器&#xff0c;UAV&#xff09;技术的快速发展&#xff0c;其在商业、娱乐和军事领域的广泛应用带来了新的安全挑战。特别是对于关键基础设施如电力系统&#xff0c;无人机的“黑飞”&…...

零知开源——STM32F103RBT6驱动 ICM20948 九轴传感器及 vofa + 上位机可视化教程

STM32F1 本教程使用零知标准板&#xff08;STM32F103RBT6&#xff09;通过I2C驱动ICM20948九轴传感器&#xff0c;实现姿态解算&#xff0c;并通过串口将数据实时发送至VOFA上位机进行3D可视化。代码基于开源库修改优化&#xff0c;适合嵌入式及物联网开发者。在基础驱动上新增…...