消息队列好比一个存放消息的容器, 当我们使用时可以取出供自己使用. 消息队列是分布式系统中重要组件. 主要是通过异步处理提高系统性能和削峰, 降低系统耦合性.

队列Queue是一种先进先出的数据结构, 所以消息消费时是按顺序消费的, 但是偶尔也会顺序出错, 以及消息重复消费, 这是我们需要考虑的问题.

为什么使用消息队列:

1, 通过异步处理提高系统性能和削峰

mysql 做消息队列 消息队列与数据库_数据库

 

如果不使用消息队列, 那么请求数据将直接写入数据库, 在高并发的情况下数据库压力会巨增, 响应变慢.

如果使用消息队列, 用户的请求数据发送到消息队列后立即返回, 再由消息队列的消费者进程从消息队列中获取数据, 异步写入数据库, 由于消息队列服务器处理速度高于数据库, 因此响应速度得到改善.

因此我们知道消息队列具有很好的削峰作用, 即通过异步处理, 将短时间内高并发产生的事务存储在消息队列中, 从而削平高峰期并发事务.如电子商务的一些秒杀,促销活动.

在用户请求数据写入消息队列后就立即返回给用户了, 但是请求数据在后续的业务校验,数据写入数据库可能出错, 因此在使用消息队列异步处理后, 需要适当修改业务流程配合, 比如用户提交订单后, 订单数据写入消息队列, 不能立即返回订单提交成功, 需要在消息队列的订单消费者进程处理完消息后, 甚至出库, 再以电子邮件或者短信通知订单成功, 以免产生纠纷.

 

2, 降低系统耦合性

使用消息队列还可以降低系统耦合性, 如果模块之间不存在直接调用, 那么增加, 修改模块对其他模块的影响就会最小.这样系统的扩展性无疑会更好

mysql 做消息队列 消息队列与数据库_数据库_02

 

生产者(客户端)生产消息放入消息队列, 消费者(服务器)取出自己匹配的消息消费, 不需要知道是哪个生产者, 降低了系统的耦合性, 消息队列使用发布--订阅模式工作, 对于新增业务, 只要对该类消息感兴趣, 只需要订阅该消息即可.

另外为了避免消息队列服务器宕机造成消息丢失, 会将成功发送到消息队列的消息存储在消息生产者服务器上, 等消息真正被消费者服务器处理后才删除消息. 在消息队列服务器宕机后, 生产者服务器会选择分布式集群中的其他服务器发布消息.

 

消息队列带来的一些问题:

  •  系统可用性降低:  为什么可用性降低了?因为再加入MQ之前是不需要考虑消息丢失或者MQ挂掉, 但加入MQ后这些问题必须考虑
  • 系统复杂性提高:  我们要保证消息的顺序一致, 不被重复消费, 消息丢失等问题
  • 一致性问题:  消息队列可以实现异步, 消息队列带来的异步确实可以提高系统的性能, 但是, 万一消息的真正消费者并没有正确消费, 可能就会导致数据不一致.

 

本文参考:https://github.com/Snailclimb/JavaGuide/blob/master/docs/system-design/data-communication/message-queue.md