为什么要用消息队列?会带来什么问题?

首先脑袋里就得蹦出来三个词:异步、解耦、削峰

异步

先看一下这张流程表,一开始系统比较简单,就一个支付,后来为了搞促销,加活动,不断的加新功能,导致系统越来越臃肿。那怎么解决?只有异步了!


222.png

`T$T5TQ0U6OW2_@AA8BRA$R.png

为什么不能用线程池来解决?
每次添加系统都需要修改业务代码,每次加一个你要调用一个接口然后还要重新发布系统,系统大的时候,启动一次可不是几分钟的事情,另外还有耦合严重的问题,这也是说的线程池解耦的功能。

解耦

加入消息队列之后,支付成功的消息告诉别的系统,他们收到了去处理就好了,根本不关心其他业务怎么实现的,赞!

削峰

平时流量很低,但是你要做秒杀活动00 :00的时候流量疯狂怼进来,你的服务器,Redis,MySQL各自的承受能力都不一样,可以通过消息队列,虽然你每秒进来1W个请求排队,我消息队列每秒只吐出去5000个请求交给redis和mysql,最后肯定能消费完,减少了数据库的压力。

MQ带来的问题?

1.那如果有一个系统消费失败了,其他系统都消费成功呢?

}2)ZMOUC94M7Q9CD5S)0VBI.png

比如图中所示,那肯定要请求重试,这个时候别的系统已经执行完这个接口了,那咋办嘛——幂等接口。把接口设计成幂等的,其他系统计算再调用一次这个接口,结果还是一样的。

这个啊,就要看我的另外两篇文章了:
分布式事务
幂等接口的设计

2.怎么保证消费的顺序?
先来看一下这种情况
我们在数据库同时对一个Id的数据进行了增、改、删三个操作,但是你消息发过去消费的时候变成了改,删、增,这样数据就不对了。

22222.png

在RocketMQ中,帮我们实现了一个MQ中的队列,没错,就是消息队列中还有一个队列,
生产者消费者一般需要保证顺序消息的话,可能就是一个业务场景下的,比如订单的创建、支付、发货、收货,而这一般也是一个订单号的。既然是一个订单号就好说了。
一个topic下有多个队列,为了保证发送有序,RocketMQ提供了MessageQueueSelector队列选择机制,他有三种实现:


555.png

我们可使用Hash取模法,让同一个订单发送到同一个队列中,再使用同步发送,只有同个订单的创建消息发送成功,再发送支付消息。这样,我们保证了发送有序。
注意哦注意!虽然我们发给消费者的顺序可以这么保证,那消费者的消费顺序需要自己的业务来保证了。
一个队列有序出去,消费者是多线程的,你消息是有序的给他的,你能保证他是有序的处理的嘛?还是一个消费成功了再发下一个稳妥。

MQ挂了怎么办?也就是如何保证MQ的高可用?
现在的MQ一般都是集群布置,而且是多个Master多个Slave,防止单点故障,其中又分同步双写异步复制,就是指从Master复制到Slave的时候是同步写,还是先写Master再写Slave,同步效率慢一些。

你可能感兴趣的:(为什么要用消息队列?会带来什么问题?)