当前位置: 首页 > 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; 作者简介…...

19c补丁后oracle属主变化,导致不能识别磁盘组

补丁后服务器重启&#xff0c;数据库再次无法启动 ORA01017: invalid username/password; logon denied Oracle 19c 在打上 19.23 或以上补丁版本后&#xff0c;存在与用户组权限相关的问题。具体表现为&#xff0c;Oracle 实例的运行用户&#xff08;oracle&#xff09;和集…...

【WiFi帧结构】

文章目录 帧结构MAC头部管理帧 帧结构 Wi-Fi的帧分为三部分组成&#xff1a;MAC头部frame bodyFCS&#xff0c;其中MAC是固定格式的&#xff0c;frame body是可变长度。 MAC头部有frame control&#xff0c;duration&#xff0c;address1&#xff0c;address2&#xff0c;addre…...

汽车生产虚拟实训中的技能提升与生产优化​

在制造业蓬勃发展的大背景下&#xff0c;虚拟教学实训宛如一颗璀璨的新星&#xff0c;正发挥着不可或缺且日益凸显的关键作用&#xff0c;源源不断地为企业的稳健前行与创新发展注入磅礴强大的动力。就以汽车制造企业这一极具代表性的行业主体为例&#xff0c;汽车生产线上各类…...

python爬虫:Newspaper3k 的详细使用(好用的新闻网站文章抓取和解析的Python库)

更多内容请见: 爬虫和逆向教程-专栏介绍和目录 文章目录 一、Newspaper3k 概述1.1 Newspaper3k 介绍1.2 主要功能1.3 典型应用场景1.4 安装二、基本用法2.2 提取单篇文章的内容2.2 处理多篇文档三、高级选项3.1 自定义配置3.2 分析文章情感四、实战案例4.1 构建新闻摘要聚合器…...

成都鼎讯硬核科技!雷达目标与干扰模拟器,以卓越性能制胜电磁频谱战

在现代战争中&#xff0c;电磁频谱已成为继陆、海、空、天之后的 “第五维战场”&#xff0c;雷达作为电磁频谱领域的关键装备&#xff0c;其干扰与抗干扰能力的较量&#xff0c;直接影响着战争的胜负走向。由成都鼎讯科技匠心打造的雷达目标与干扰模拟器&#xff0c;凭借数字射…...

ArcGIS Pro制作水平横向图例+多级标注

今天介绍下载ArcGIS Pro中如何设置水平横向图例。 之前我们介绍了ArcGIS的横向图例制作&#xff1a;ArcGIS横向、多列图例、顺序重排、符号居中、批量更改图例符号等等&#xff08;ArcGIS出图图例8大技巧&#xff09;&#xff0c;那这次我们看看ArcGIS Pro如何更加快捷的操作。…...

图表类系列各种样式PPT模版分享

图标图表系列PPT模版&#xff0c;柱状图PPT模版&#xff0c;线状图PPT模版&#xff0c;折线图PPT模版&#xff0c;饼状图PPT模版&#xff0c;雷达图PPT模版&#xff0c;树状图PPT模版 图表类系列各种样式PPT模版分享&#xff1a;图表系列PPT模板https://pan.quark.cn/s/20d40aa…...

今日学习:Spring线程池|并发修改异常|链路丢失|登录续期|VIP过期策略|数值类缓存

文章目录 优雅版线程池ThreadPoolTaskExecutor和ThreadPoolTaskExecutor的装饰器并发修改异常并发修改异常简介实现机制设计原因及意义 使用线程池造成的链路丢失问题线程池导致的链路丢失问题发生原因 常见解决方法更好的解决方法设计精妙之处 登录续期登录续期常见实现方式特…...

使用Matplotlib创建炫酷的3D散点图:数据可视化的新维度

文章目录 基础实现代码代码解析进阶技巧1. 自定义点的大小和颜色2. 添加图例和样式美化3. 真实数据应用示例实用技巧与注意事项完整示例(带样式)应用场景在数据科学和可视化领域,三维图形能为我们提供更丰富的数据洞察。本文将手把手教你如何使用Python的Matplotlib库创建引…...

数学建模-滑翔伞伞翼面积的设计,运动状态计算和优化 !

我们考虑滑翔伞的伞翼面积设计问题以及运动状态描述。滑翔伞的性能主要取决于伞翼面积、气动特性以及飞行员的重量。我们的目标是建立数学模型来描述滑翔伞的运动状态,并优化伞翼面积的设计。 一、问题分析 滑翔伞在飞行过程中受到重力、升力和阻力的作用。升力和阻力与伞翼面…...