消息通知模块的设计原理

文章讨论了数据库设计中公告消息的处理方式,主张根据需求记录用户的阅读状态。推荐使用MongoDB存储大量消息数据,并提出冷热数据分离和数据销毁策略。在系统消息发送与收取方面,引入RabbitMQ作为消息队列以减轻数据库压力,通过用户登录和首页轮询实现消息的异步处理和显示。此外,文章还提及了系统登录、首页轮询和用户资料修改等业务场景下的消息通知机制。
摘要由CSDN通过智能技术生成

目录

介绍

一、数据库设计

公告消息记录应该全局唯一,还是为每个用户创建一条公告消息? 

用MongoDB存储消息数据 

1. 搞冷热数据分离,热数据定期归档

2. 冷数据存储一段时间后就销毁,释放存储空间 

二、系统消息的发送与收取

三、业务说明

1. 系统登录 

2. 首页定时轮询

3. 修改用户资料 


介绍

        Kafka快,RabbitMQ也不慢,即支持同步收发消息,又支持异步收发消息。队列有五种模式,功能上强于Kafka。综合考虑选择RabbitMQ。

一、数据库设计

        很多人以为消息模块的数据表设计起来很简单,创建一个 消息表 就可以存储系统消息了,我只能说,你把问题想简单了。 

公告消息记录应该全局唯一,还是为每个用户创建一条公告消息? 

        这个问题取决于你是怎么理解系统消息的,如果你不希望系统记录用户是否阅读了某条消息,哪些消息是未读消息,那么一个公告消息在数据表中就是一条唯一的记录,存储起来非常节省空间。但是很少有系统会这么设计,如果系统消息很多,又不告诉用户哪些是已读消息,哪些是未读消息,造成用户体验非常不好。所以系统必须要记录下来,用户阅读了哪些消息,还有哪些消息是未读的。 

        如果一个电商系统有800万注册用户,那么系统发出一条公告消息之后,意味着要在消息表中插入800万条消息记录,每条记录是发给某位用户的公告消息。瞬间数据库的负载达到顶峰,数据库被大量的写入操作占用,导致电商系统正常的业务无法展开。请记住,一条公告消息就能让电商系统濒临崩溃。微信有11亿的日活用户,如果微信给所有用户发出一条公告消息,岂不是微信的服务器就挂了?看来消息模块的数据库架构确实有技术含量。 

 

用MongoDB存储消息数据 

        因为消息模块的要存储的数据量太大,普通MySQL单表超过2000万记录,MySQL数据库就难以支撑,所以我们要换能存储海量数据的数据库产品,于是MongoDB数据库就进入到我的视线里。MongoDB适合存储海量低价值的数据,正好符合消息模块的存储要求。 

        即便MongoDB能存储TB级别的数据,但是消息数据日积月累,MongoDB也会有撑不下来的时候,那该怎么办呢? 

1. 搞冷热数据分离,热数据定期归档

 

        根据数据被使用的频率,可以划分成热数据和冷数据。一年内的数据被看做是热数据,超过一年的数据被当做冷数据。我们编写定时程序,每天凌晨的时候把冷数据从MongoDB_1,转移到另一个MongoDB_2。这样MongoDB_1的数据量减小了,所以CRUD的速度变快了。MongoDB_2存放的是冷数据,即便数据量很大,但是冷数据很少被用到,所以MongoDB_2仅仅充当归档库而已。

2. 冷数据存储一段时间后就销毁,释放存储空间 

        归档库存储的冷数据太多,也难免出现崩溃,所以我们可以定期的删除超期的冷数据。假设五年以上的冷数据就被当成是超期数据,删除超期数据之后,归档库的空间也就腾出来了。

二、系统消息的发送与收取

        刚才说到了,用MongoDB存储消息数据,但是一个大型Web系统,发送一条公告消息要往数据库里面写入大量的数据,即便MongoDB也支撑不下来瞬时写入百万、千万记录的情况,那该怎么办呢?我们可以把海量写入数据写入,变成细水长流,慢慢写入到MongoDB中。 

 

        比如说我们可以引入消息队列MQ,然后在Java后端系统上面,用异步多线程的方法,向消息队列MQ中发送消息,这样Web系统发布公告消息的时候就不占用数据库正常的CRUD操作。

 

        系统消息保存在消息队列中,我们只是用它来做削峰填谷,系统消息最终还是要存储在数据库上面。于是我们可以这样设计,在用户登陆系统的时候,用异步线程从消息队列MQ中,接收该用户的系统消息,然后把系统消息存储在数据库中,最后消息队列MQ中的该条消息自动删除。你看,这么设计之后,所有用户不可能同时登陆Web系统,所以我们就把往数据库中写入系统消息的任务,变成了错峰写入,这种设计非常巧妙是吧。

三、业务说明

        Emos系统中有很多模块都用到了消息模块,我们来看看具体都有哪些业务需要消息模块。 

1. 系统登录 

 

        用户登陆系统的时候,后端Emos系统要创建异步线程,接收消息队列MQ中的消息,然后把消息写到数据库里面。 

2. 首页定时轮询

        大家需要注意,新接收的消息并不等于未读消息。比如上面的截图1,首页显示新接收到1条消息,但是总共的未读消息总共有3条。在数据库中的消息记录里面,我会用 readFlag 和lastFlag 分表标记 未读消息 和 新接收消息 。

 

        Emos小程序的index页面设有定时器,每5分钟发送一次轮询,查询接收到多少条新消息。MessageTask利用异步线程接收MQ中的消息,然后保存到message_ref集合中,并且设置新消息的lastFlag字段为true。 

        Service把message_ref中的某人所有的消息记录的lastFlag字段设置成false,返回的修改记录条数就相当于接收到了多少条新消息,这个结果要返回给小程序的。 

3. 修改用户资料 

        我们修改用户资料之后,Emos系统会自动向该员工发送消息通知。但是消息通知并不直接写入到MongoDB,而是写到MQ消息队列,然后在首页轮询的时候提示用户有新的系统消息。

  

  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
引用\[1\]:原理很简单,就是通过自己拟定的代码命令,来操控语音识别模块的初始化等等进程,唯一需要注意的是,Arduino的IIC通讯缓存区只有32个字节,所以这边建议将命令词进行切割分块发送,最后发送一个自拟定的结束命令,通知模块我发送完了,你可以装载命令词了,具体方法查看例程3.1。例程2.3里面有切割字符串并载入到3320里面的例程。\[1\]引用\[2\]:如使用其它形式的命名,则无法使用选曲播放指令播放该文件,文件需要放在根目录下,即打开盘符即可。 接线 MP3语音播放模块ArduinoGGV5VTX0RX1 代码 #include "GD5800_Serial.h" GD5800_Serial mp345(0,1); void setup() { mp345.begin(9600); mp345.setVolume(10);//音量设置 mp345.playFileByIndexNumber(6); //播放曲目序号 } void loop() { mp345.play(); } 串口控制 。\[2\]引用\[3\]:本文章为记录本人的学习过程,最终目的是设计一款IIC通讯方式的语音识别模块,该模块的主要功能,就是识别程序中设定的指令词,并返回识别结果,指令词和对应的返回编号可在程序中任意修改,不需要去给语音识别模块烧录固件,支持命令词的动态编辑。\[3\] 问题: arduino mp3语音模块是如何工作的? 回答: Arduino MP3语音模块的工作原理是通过自己拟定的代码命令来操控语音识别模块的初始化等进程。在Arduino的IIC通讯缓存区有限的情况下,建议将命令词进行切割分块发送,并发送一个结束命令来通知模块发送完毕。具体的方法可以参考相关的例程。\[1\]此外,MP3语音模块可以通过串口控制来播放音乐文件,需要将文件放在根目录下,并使用特定的命令来播放指定的文件。\[2\]这种语音模块设计目的是识别程序中设定的指令词,并返回识别结果,指令词和对应的返回编号可以在程序中任意修改,而不需要给语音识别模块烧录固件,还支持命令词的动态编辑。\[3\] #### 引用[.reference_title] - *1* *3* [基于Arduino IDE开发的LD3320语音识别模块](https://blog.csdn.net/qq_40532525/article/details/124869706)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down1,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [MP3 Module 语音播放模块(Arduino和串口控制)](https://blog.csdn.net/qq_42250136/article/details/130975760)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down1,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

chengbo_eva

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值