写项目的时候,设计数据库时,有这样一个疑问:公告的消息到底时全局唯一还是为每个用户都创建一条公告消息呢?
如果全局唯一倒是好说,我们设置创建一个消息表来存储系统消息,只用往数据表中插入一条消息记录,可是这样的话,每个人都收到同一条公告消息,系统无法记录用户是否阅读了某条消息,哪些消息是未读消息,这样虽然节省空间,但是用户体验不好;
但是我们如果给每个用户都发一条公告消息,比如说王者荣耀游戏,要同时给所有玩家发一条公告通知发放50铭文,好家伙,王者荣耀用户那么多,意味着要在消息表中插入千万条消息记录,每条记录是发给某位用户的公告消息。瞬间数据库的负载达到顶峰,数据库被大量的写入操作占用,服务器可能就炸了。
那咋整啊?
我们可以把海量写入数据,变成细水长流,慢慢写入到数据库中去。
这个就涉及到了消息队列。
消息队列MQ
消息队列可以简单理解为:把要传输的数据放在队列中。
当我们需要使用消息的时候可以取出消息供自己使用。消息队列是分布式系统中重要的组件,使用消息队列主要是为了通过异步处理提高系统性能和削峰、降低系统耦合性。
具体细节推荐这个博文:消息队列
在不使用消息队列服务器的时候,用户的请求数据直接写入数据库,在高并发的情况下数据库压力剧增,使得响应速度变慢。但是在使用消息队列之后,用户的请求数据发送给消息队列之后立即 返回,再由消息队列的消费者进程从消息队列中获取数据,异步写入数据库。由于消息队列服务器处理速度快于数据库(消息队列也比数据库有更好的伸缩性),因此响应速度得到大幅改善。
消息队列作用:
1. 消息队列具有很好的削峰作用的功能
即通过异步处理,将短时间高并发产生的事务消息存储在消息队列中,从而削平高峰期的并发事务。 举例:在电子商务一些秒杀、促销活动中,合理使用消息队列可以有效抵御促销活动刚开始大量订单涌入对系统的冲击。
2. 消息队列可以降低系统耦合性
比如,我们修改用户资料之后,系统会自动向该用户发送消息通知。但是消息通知并不直接写入到数据库,而是写到MQ消息队列,然后在首页轮询的时候提示用户有新的系统消息。
使用消息队列带来的一些问题
- 系统可用性降低: 系统可用性在某种程度上降低,为什么这样说呢?在加入MQ之前,你不用考虑消息丢失或者说MQ挂掉等等的情况,但是,引入MQ之后你就需要去考虑了!
- 系统复杂性提高: 加入MQ之后,你需要保证消息没有被重复消费、处理消息丢失的情况、保证消息传递的顺序性等等问题!
- 一致性问题
- 不能时单机的,我们项目中使用消息队列,都是得集群/分布式的。要做集群/分布式就必然希望该消息队列能够提供现成的支持,而不是自己写代码手动去实现。
JMS 简介
JMS(JAVA Message Service,java消息服务)是java的消息服务,JMS的客户端之间可以通过JMS服务进行异步的消息传输。JMS(JAVA Message Service,Java消息服务)API是一个消息服务的标准或者说是规范,允许应用程序组件基于JavaEE平台创建、发送、接收和读取消息。它使分布式通信耦合度更低,消息服务更加可靠以及异步性。
JMS两种消息模型
①点到点(P2P)模型
② 发布/订阅(Pub/Sub)模型
JMS消息模型这篇写的不错
面试角度
关于自己项目使用的角度解释这个消息队列中间件。
知乎这篇回答也不错