一、写在前面上篇文章《同学,消息中间件在你们生产项目里如何落地使用的?》,我们用一个简单易懂的电商场景给大家引入说明了一个消息中间件的使用场景 。
同时,我们还基于RabbitMQ的HelloWorld级别的代码,给出了订单服务和仓储服务如何基于MQ中间件收发消息的示例 。
二、业务场景回顾这篇文章,我们来稍微深入探讨一些MQ中间件使用中的基础技术问题 。
首先回顾一下上篇文章做出来的一个架构图,看看订单服务和消息服务是如何基于MQ来收发消息的 。
我们稍微把这个图细化一点,简单来说就是多个订单服务实例给queue推送消息,多个仓储服务每个消费一部分消息 。如下图所示:
文章插图
三、意外宕机,问题凸现假如你线上对MQ技术的使用就到此为止了,那么基本可以跟offer说拜拜了 。。。
因为如果是我的话,作为一个面试官就没法继续往下问了 。你这个MQ的使用以及理解的深度仅此而已的话,那基本就是刚刚对MQ技术入门的程度 。
如果面试官要继续问,完全可以问下面的问题:
- 那你说说如果仓储服务作为消费者服务,刚收到了一个订单消息,但是在完成消息的处理之前,也就是还没对订单完成仓储调度发货,结果这个仓储服务突然就宕机了,这个时候会发生什么事情?
【线上服务器宕机时,如何保证数据100%不丢失】所以说,大家还是要对这个技术了解的稍微深入一点点,否则随便被问几个问题就完蛋了 。
大伙儿先来看看下面的图,感受一下车祸现场 。
文章插图
RabbitMQ这个中间件默认的一个行为,就是只要仓储服务收到一个订单消息,RabbitMQ就会立马把这条订单消息给标记为删除,这个行为叫做自动ack,也就是投递完成一条消息就自动确认这个消息处理完毕了 。
但是接着如果此时仓储服务收到了一个订单消息,但是还没来得及对仓库系统完成商品的调度发货,结果直接就宕机了 。
此时,明显这个订单消息就丢失了啊,因为RabbitMQ那里已经没有了 。。。
这会导致什么样的尴尬体验呢?就是一个用户支付了8999元,对一个iphone8下了订单,结果呢,死等活等了好几天,就是不见网站上显示他的iphone8在发货 。
搞了半天,原因就是他的那个iphone8的订单在仓储服务那里,还没来得及调度发货直接就宕机了,导致这个订单消息就一直丢失了,始终没有给这个用户通知仓库系统进行发货 。
这个问题,是不是很尴尬?所以说,技术问题是会严重影响企业的核心业务流程的!
各位小伙伴,还记得上一讲咱们的仓储服务消费消息的代码中,有一行关键的代码:
文章插图
只要修改为false之后,RabbitMQ就不会盲目的投递消息到仓储服务,立马就删除消息了,说白了就是关闭autoAck的行为,不要自作主张的认为消息处理成功了 。
接着,我们需要改造一下处理订单消息的代码,如下代码所示 。
这段代码,说白了,就是在对订单完成了调度发货之后,在finally代码块中手动执行了ack操作,说我自己已经完成了耗时几十秒的业务逻辑的处理,现在可以手动ack通知RabbitMQ,这个消息处理完毕了 。
文章插图
此时整个架构运行流程大致看起来跟下面的图那样子 。
文章插图
架构流程改成上面那样后,就意味着只有完成了仓储调度发货的代码业务逻辑,确保仓库系统收到通知之后,仓储服务才会在代码中手动发送ack消息给RabbitMQ 。
此时,RabbitMQ收到了这个ack消息,才会标记对应的订单消息被删除了 。
如果说在仓储服务收到了订单消息,但是还没来得及完成仓储调度发货的业务逻辑,那也就绝对不会执行这条订单消息的ack操作,然后RabbitMQ也就不会收到这条订单消息的ack通知 。
一旦RabbitMQ发现代表消费者的某个仓储服务实例突然宕机了,而这个仓储服务收到的一些订单消息还没来得及处理,没给自己发送那些消息的ack通知 。
此时,RabbitMQ会自动对这条订单消息重发推送给其他在运行中的仓储服务实例,让其他的仓储服务实例去处理这条订单消息 。
推荐阅读
- 记一次服务器被植入挖矿木马cpu飙升200%解决过程
- 基于windows server 2008 R2 搭建FTP文件服务器
- 远程登录服务器,有什么比较好用的工具?
- 在家如何访问公司服务器
- ping值忽高忽低,你的服务器可能出了这些问题
- 服务器与虚拟主机最大的区别是什么?
- Linux如何查看服务器开放的端口号
- 了解Tomcat服务器架构这四张图就够了
- 在Linux服务器间传输文件的小技巧
- Linux下的CPU使用率与服务器负载的关系与区别