oa项目-系统通知实现

1,采用的是mongdB存储,普通的mysql难以支撑

2,mongdB搞冷热分离,但是考虑到大型web项目也难以支撑一条公告发送百万数据,采用消息队列细睡长流慢慢的写入mongdb

3,使用异步线程的方式往消息队列发送消息

4,系统的消息存储的消息队里上,只是用他过渡,消息最终还是存储到数据上,这样就可以用户登录的时候异步从队列取出消息,然后存储到数据库,最后在把队列删除。

业务:

系统登录:

用户登录的时候可以异步从队列收取消息

轮询接受消息:

系统5分钟轮询查询一次消息,异步从队列中获取消息,把lastFlag设置为true代表新接受的消息,当查询数据库中有多少条消息的把lastFlag改成false,修改了多少就代表新接受了多少消息。

修改用户资料:

修改过后,修改通知消息从队列取出,首页轮询查询出系统提示

 

什么时候使用异步和同步?

只要跟前端没关系的消息收发,用异步的都可以,比如系统之间的消息收发,用异步就很恰当。但是跟前端有关,因为HTTP协议是短连接,所以这次刷新页面就应该明确知道接收了多少条消息。如果用异步,HTTP连接都断开了,后端才刷到消息,怎么能推送给前端页面?所以必须要用同步的。消息没收完,就别切断HTTP连接。

总结:因为http是短链接,如果使用异步的话,还等等待接受消息,消息没有收取完成就会切断。

项目中使用的异步线程,同步mq

这里有两种异步方式:MQ的异步和线程执行的异步。MQ的异步更像是挂载后台阻塞运行,没收到消息也不退出,一直在后端运行。这种方式肯定不妥,所以我们选择的是MQ同步执行,收完消息就退出。线程池方面,我们选择的是异步线程执行MQ的同步接收消息。如果用MQ的异步方式,一直阻塞下去,线程池的线程永远不放回到线程池,线程池很快就被耗光

总结:

这里简单的总结就是使用异步线程池,去执行mq同步接受的消息,这样执行完之后就会放回去,不会导致线程池的线程耗光。

RabbitMQ的API分成阻塞和非阻塞

 

Message集合uuid设计

比如5分钟来了一堆消息。其中一个消息没有在这5分钟消费者还有没有消费,但是又来了一个轮询会接受两个一样的消息所以使用uuid来辨别重复。

 

 

 

业务实现:

分页查询查询显示,这个使用连表查询,显示到页面。这里主要Aggregation构建集合连接。调用mongoTemplate.aggregate(),查询出连接的所有消息,之后遍历每一个消息,拼接map中显示页面。

根据id查询:

mongoTemplate.findById()

根据id查询,在修改:

mongoTemplate.updateFirst()

根据id删除:

mongoTemplate.remove

保存

 mongoTemplate.save

刷新用户的消息: 比如用户登录的时候发送了一条系统通知,保存到了mongdb对象中,调用mq收取消息保存到mongdb中,发送消息主体,附属message集合主键,发送消息。

轮询的时候异步线程线程,同步mq收取mq队列中的消息,获取队列中的消息的时候,收取的时候保存到message_ref集合中,并把收取消息改为true,此时也在同时进行查询数量就是把true改为false,最后返回查询的数量。

 

总结:

  1. 发送通知到mq队列

  2. 定时轮询接受消息,并查询新接受消息的数量(根据lastFlag属性标记来查询数量)

  3. 其他都是一些增删改查

posted @ 2022-11-21 22:38  一帘清雨  阅读(124)  评论(0)    收藏  举报