1. 削峰
对于大流量的瞬时使用场景如抢购,秒杀等业务。针对这些特定场景进行开发,有便于开发出可平滑过度的系统,不会出现请求假死,服务崩溃的场景。
2. 使用 MQ 实现消息通讯
使用 MQ 可以作为消息通讯的实现手段,利用它可以实现点对点的通讯或者多对多的聊天室功能。
3. 使用 MQ 实现日志系统
4. 实际场景举例
假设12306系统是这样的,我们买票成功后,需要做以下几件事:调用库存系统扣减车票库存,调用短信系统给用户发送短信,调用邮件系统给用户发邮件,调用第三方客户端通知买票成功。那么如果这几个服务一直能正常服务,产品经理不在有新的需求变更,那也可称得上现世安稳,岁月静好。可是万一有一天出现这么两种情况可怎么办呢?
4.1 产品经理提需求,好多人关注了我们12306微信客户端,我们需要买票成功后在通知微信小程序。那么我们又需要修改订单系统的代码。一次还好,如果隔一段时间发生一件这样的事,那谁能忍受?
4.2 某一天,短信系统挂了,然后客户成功买到一张票,然后呢是短信也没收到,邮件也没收到,库存也没扣,这还得了。你短信系统坏了,我邮件系统好好的,凭什么影响我,让客户收不到邮件,这就不合理。
所以呢,还是各个系统之间的耦合太高了,我们应该解耦。不是有人说互联网的任何问题都可以通过一个中间件来解决吗,那么我们看MQ如何帮我们解决这件棘手的事情。
那么我们发现其实短信系统、邮件系统等都只依赖订单系统产生的一条数据那就是订单,因此我们在订单系统产生数据后,将订单这条数据发送给MQ,就返回成功,然后让短信、邮件等系统都订阅MQ,一旦发现MQ有消息,他们主动拉取消息,然后解析,进行业务处理。这样一来,就算你短信系统挂了,丝毫不会影响其他系统,而且如果后来想加一个新的系统,你也不用改订单系统的代码了,你只要订阅我们的MQ提供的消息就行了。
5. 消息队列RabbitMq和Feign区别
学习RabbitMq和feign之后产生了疑惑,感觉都差不多啊,不都是进行信息的通信吗。其实不然,首先Fegin接口是微服务与微服务之间的调用,还是依赖于提供者的返回值来进行处理,并没有将业务进行解耦。所以Fegin是同步方式而MQ为异步方法,怎么使用取决于业务复杂度。如果只是简单的查询,直接调用Fegin也没有关系,但如果涉及相应的处理,并且复杂度比较高,或者后期变动情况比较大,还是推荐使用异步,减少后期维护的麻烦,减轻重复工作的可能
6. MQ缺点
6.1消息防止丢失处理
6.1.1 持久化
消息队列在很多场景下都是需要有持久下机制了。否则如果队列中挤压了大量消息,此时mq服务器重启,那么这些消息就都消失了,因为这些消息都只存在于内存,而RabbitMQ为了解决这个问腿,也提供了持久化机制
持久化分为三种
- 交换机持久化
- 队列持久化
- 消息持久化
6.1.2 消息确认机制
自动ACK: 消费者配置中如果是自动ack机制,MQ将消息发送给消费者后直接就将消息给删除了,这个的前提条件是消费者程序没有出现异常,如果消费者接收消息后处理时出现异常,那么MQ将会尝试重发消息给消费者直至达到了消费者服务中配置的最大重试次数后将会直接抛出异常不再重试。
手动ACK:消费者设置了手动ACK机制后,可以显式的提交/拒绝消息(这一步骤叫做发送ACK),如果消息被消费后正常被提交了ack,那么此消息可以说是流程走完了,然后MQ将此消息从队列中删除。而如果消息被消费后被拒绝了,消费者可选择让MQ重发此消息或者让MQ直接移除此消息。后面可以使用死信队列来进行接收这些被消费者拒绝的消息,再进行后续的业务处理。
消息确认又分为发送方确认与消费方确认
- Confirm消息确认机制 - 正常机制
消息确认,是指生产者发送消息给broker,然后broker会给生产者一个应答;
生产者接收应答,用来确定该消息是否正常发送到broker,这种方式也是消息可靠性投递的核心保障- Return Listener用于处理一些不可路由的消息;
消息生产者,通过指定一个Exchange和Routingkey,把消息送达到某一个队列中去,然后消费者监听队列,进行消费处理操作;
但某些情况下,如果我们在发送消息的时候,当前的exchange不存在或者指定的路由key路由不到,这个时候如果我们需要监听这种不可达的消息,就需要Return Listener!- 以上两种并不会保证百分百消息不丢失,因为还有一个情况就是消费端消费失败后的处理
当然,这里也比较简单,如果开启了以上两种后,消费端只需要进行手动的操作即可,成功ACK。失败Nack。
6.1.3 以上操作会有有可能未确认或者消息瞬时比较多,有可能造成消息积压的问题,那么我们该如何处理消息积压呢。
方案1:简单修复
修复consumer的问题,让他恢复消费速度,然后等待几个小时消费完毕
方案2:复杂修复
临时紧急扩容了,具体操作步骤和思路如下:
1)先修复consumer的问题,确保其恢复消费速度
2)新建一个topic,partition是原来的10倍,临时建立好原先10倍或者20倍的queue数量
3)然后写一个临时的分发数据的consumer程序,这个程序部署上去消费积压的数据,消费之后不做耗时的处理,直接均匀轮询写入临时建立好的10倍数量的queue
4)接着临时征用10倍的机器来部署consumer,每一批consumer消费一个临时queue的数据
5)这种做法相当于是临时将queue资源和consumer资源扩大10倍,以正常的10倍速度来消费数据
6)等快速消费完积压数据之后,得恢复原先部署架构,重新用原先的consumer机器来消费消息
当人以上修复都是处理需要保留的数据,如果不保留直接删除即可。
7. MQ总结
优势:
应用解耦:提高系统容错性和可维护性
异步提速:提升响应速度,优化用户体验
削峰填谷:高并发的时候,可以有效保证系统的稳定性
弊端:
复杂度提高,我们需要解决消息丢失、积压、幂等等各种情况
一旦MQ宕机,对业务有影响