MQ 消息队列
Message Queue
应用场景(优点)
- 主要解决
异步
消息
由于在高并发环境下,由于来不及同步处理,请求往往会发生堵塞,比如说,大量的insert,update之类的请求同时到达 mysql,直接导致无数的行锁表锁,甚至最后请求会堆积过多,从而触发too many connections错误。通过使用MQ
,我们可以异步
处理请求,从而缓解系统的压力。 - 应用解耦
- 流量消峰等问题
- 日志处理 (kafka)
缺点
- 系统可用性降低
本来其他系统只要运行好好的,那你的系统就是正常的。现在你非要加个消息队列进去,那消息队列挂了,你的系统就挂了。因此,系统可用性降低 - 系统复杂性增加
要多考虑很多方面的问题,比如一致性问题、如何保证
消息不被重复消费
,如何保证消息可靠传输
。因此,需要考虑
的东西更多,系统复杂性增大。
- 为什么会造成
重复消费
?
因为网络传输
等等故障
,确认信息没有
传送到消息队列
,导致消息队列不知道
自己已经消费过该消息了,再次
将该消息分发给其他的消费者。 - 解决重复消费的方案:
- 比如,你拿到这个消息做数据库的
insert
操作。那就容易了,给这个消息做一个唯一主键
,那么就算出现重复消费的情况,就会导致主键冲突,避免数据库出现脏数据。 - 再比如,你拿到这个消息做
redis
的set的操作,那就容易了,不用解决,因为你无论set
几次结果都是一样的,set
操作本来就算幂等
操作。 - 如果上面两种情况还不行,上大招。准备一个
第三方介质
,来做消费记录。以redis
为例,给消息分配一个全局id
,只要消费过该消息,将<id,message>以K-V形式写入redis。那消费者开始消费前,先去redis中查询有没消费记录
即可。
- 比如,你拿到这个消息做数据库的
举例:MDB
MDB通过消息方式为调用者提供服务
MDB组件实际使用过程中,其客户并不拥有MDB组件的远程引用,而是直接将调用消息发送到特定消息队列,因而客户的调用不强调MDB组件的运行。
参考