在做Java高并发的时候我们经常提到消息队列,缓存,分表分库,读写分离和高并发系统,消息队列我们常用RocketMQ。在分布式系统里面,我们使用消息队列就是为了解耦和削峰。
什么是消息队列?
我们可以把消息队列看作是一个存放消息的容器,当我们需要用到消息时候,直接从容器里面取出来,queue就是一个先进先出的数据结构,使用他的内部是按照顺序来消费的。
参与消息传递的上方,我们把他们叫做生产者和消费者,生产者负责发送消息,消费者负责处理消息。
消息队列有什么用?
通常来说,使用消息队列能为我们的系统带来下面三点好处:
- 通过异步处理提高系统性能(减少响应所需时间)
- 削峰/限流
- 降低系统耦合性。
关于提高系统性能:比如用户在提交订单之后,订单数据写入消息队列,不能立即返回用户订单提交成功,需要在消息队列的订单消费者进程真正处理完该订单之后,甚至出库后,再通过电子邮件或短信通知用户订单成功,以免交易纠纷。这就类似我们平时手机订火车票和电影票。
关于削峰和限流:实际就是先将短时间高并发产生的事务消息存储在消息队列中,然后后端服务再慢慢根据自己的能力去消费这些消息,这样就避免直接和后端交互,导致系统异常。比如在秒杀某商品时候,同一时间,几千上亿用户都在抢购,系统很容易崩溃,但是我们可以提高消息队列,减轻系统压力。来不及处理的消息存放在mq里面,由后台继续处理
关于降低耦合性,这个其实我一般很少遇到:消息队列使用发布-订阅模式工作,消息发送者(生产者)发布消息,一个或多个消息接受者(消费者)订阅消息。他们没有直接接触,而是通过mq交互。
消息队列的问题
使用了消息队列并不是就没有问题了,他也有很多的不足地方,比如系统可用性降低在加入mq之前,我们不会考虑mq挂掉或者消息丢失情况,但是加入mq,我们就需要考虑。并且因为之前生产者消费者直接联系,选择既然了mq,系统复杂度也变高了,我们需要考虑有没有重复消费情况,怎么保证传递的顺序性等问题。然后还有一致性的问题,页面mq可以通过异步提高系统性能,里面会有数据不一致的问题。