一、系统中为什么需要用到消息队列,使用消息队列有什么优点?
使用消息队列的优点很多,这里就说比较重要的三个优点:解耦、异步、削峰填谷。
①、解耦:
首先引入一个场景:系统a作位一个接口请求方,现在需要向b、c、d三个系统发送请求,这个时候呢a系统不需要发送请求给d系统了,而需要发送请求给e系统,那么在a系统里面就需要修改代码,每一次发送的请求方改变的话,都需要改代码,具有一定的耦合性。如下图:
那么我们引入消息队列之后呢,a系统把需要发送的请求数据放到队列里即可,不需要关心哪个系统需要a系统的请求数据,如下图所示:
②、异步:
在引入一个场景:用户请求a系统,然后a系统还需同步调用b、c、d系统的接口,我们假设一下再a系统处理自身业务逻辑请求了一个sql的时间是200ms,然后调用b系统等待b系统处理几个sql的时间是300ms,在调用c系统处理业务逻辑200ms,在调用d系统处理业务逻辑200ms,那么一次请求至少等待1秒才会响应。比较耗时,如下图所示:
那么我们再引入消息队列之后,用户调用a系统花费了200ms,然后a系统发送三条消息到消息队列里面去,总耗时是5ms左右,然后b、c、d系统去消费就行了,总共只花费200ms左右,如下图所示:
③、削峰填谷
当大量的用户(100万)通过浏览器再中午高峰期,同时进行大量的操作,会给数据库造成极大的压力,可能导致mysql宕机,如图所示:
但是中午高峰期过了的话,下午可能也就1万左右的用户在操作了,每秒50个请求左右,对系统没有任何压力,如果高峰期时将5000个请求写到mq里面的话,系统a最多每秒执行2000个请求,不要超过每秒做大请求数就行,经过了2个小时的中午高峰期,再慢慢消费队列里面的消息,这个是可以接受的。如下图所示:
二、使用消息队列有什么缺点
上面说了引入消息队列的一些场景和优点,那么使用消息队列有什么缺点呢?
系统的可用性降低:比如第一个例子,本来好好的调用三个接口,这个时候接入一个消息队列,凑巧消息队列挂掉了,系统不是直接不能用了,崩溃掉了。
系统的复杂性:加入一个消息队列,若是消息丢失怎么办,消息被重复消费了,消息没有按找既定的顺序消费,都会导致系统出问题。
一致性问题:a系统处理完了直接返回成功了,那么用户就以为成功了,实际上,bc消费成功了,d消费失败了,数据就不一致了。
所以使用消息队列会使系统的复杂程度增加一个级别,但是需要用的时候还是得用,做好综合考量。