欢迎关注个人公众号:石杉的架构笔记(ID:shishan100)
周一至周五早8点半!精品技术文章准时送上!
“上一篇讲消息中间件的文章《扎心!线上服务宕机时,如何保证数据100%不丢失?》,初步给大家介绍了一个在生产环境中可能遇到的问题,就是你的消费者服务可能会宕机,一旦宕机,你就需要考虑是否会导致没处理完的消息丢失。这篇文章,再给不太熟悉MQ技术的同学,介绍另外一个生产环境中可能会遇到的问题。
目前为止,你的RabbitMQ部署在线上服务器了,对吧?然后订单服务和仓储服务都可以基于RabbitMQ来收发消息,同时仓储服务宕机,不会导致消息丢失。
好,我们来看下目前为止的架构图。
那如果此时出现一个问题,就是说订单服务投递了订单消息到RabbitMQ里去,RabbitMQ暂时放在了自己的内存中,还没来得及投递给下游的仓储服务呢,此时RabbitMQ突然宕机了,会怎么样?
答案其实很简单,默认情况下,按照我们目前的代码和配置,这个数据就会丢失了。
所以在这里而言,就牵扯到了RabbitMQ的一个较为重要的概念:消息的持久化,用英文来说就是durable机制。
然后这里又有一个引申的概念,如果按照我们之前的代码和配置,默认情况下,RabbitMQ一旦宕机就再次重启,就会丢失我们之前创建的queue。所以首先得先让queue是持久化的。
使用下面的代码,就可以把我们的“warehouse_schedule_delivery”这个queue,也就是仓储调度发货的queue,设置为持久化的。
这样,即使RabbitMQ宕机后重启,也会恢复之前创建好的这个queue。
channel.queueDeclare(
"warehouse_schedule_delivery",
true,
false,
false,
null);
复制代码
大家看到上面那行定义和创建queue的代码么?核心在于第二个参数,第二个参数是true。
他的意思就是说,这个创建的queue是durable的,也就是支持持久化的。
RabbitMQ会把这queue的相关信息持久化的存储到磁盘上去,这样RabbitMQ重启后,就可以恢复持久化的queue。
OK,现在你的queue的信息可以持久化了,RabbitMQ宕机重启后会自动恢复queue。但是,你的queue里的message数据呢?
queue里都是订单服务发送过去的订单消息数据,如果RabbitMQ还没来得及投递queue里的订单消息到仓储服务,结果RabbitMQ就宕机了。
那此时RabbitMQ重启之后,他可以恢复queue的信息,但是queue的message数据是没法恢复了。
所以此时还有一个重要的点,就是在你的订单服务发送消息到RabbitMQ的时候,需要定义这条消息也是durable,即持久化的。
channel.basicPublish(
"",
"warehouse_schedule_delivery",
MessageProperties.PERSISTENT_TEXT_PLAIN,
message.getBytes());
复制代码
通过上面的方式来发送消息,就可以让发送出去的消息是持久化的。
一旦标记了消息是持久化之后,就会让RabbitMQ把消息持久化写入到磁盘上去,此时如果RabbitMQ还没投递数据到仓储服务,结果就突然宕机了。那么再次重启的时候,就会把磁盘上持久化的消息给加载出来。
整个过程,如下图所示:
但是这里要注意一点,RabbitMQ的消息持久化,是不承诺100%的消息不丢失的。
因为有可能RabbitMQ接收到了消息,但是还没来得及持久化到磁盘,他自己就宕机了,这个时候消息还是会丢失的。
如果要完全100%保证写入RabbitMQ的数据必须落地磁盘,不会丢失,需要依靠其他的机制。
下次有机会再继续给不太熟悉MQ技术的同学,来讲解这里的东西。
END
如有收获,请帮忙转发,您的鼓励是作者最大的动力,谢谢!
一大波微服务、分布式、高并发、高可用的原创系列文章正在路上
欢迎扫描下方二维码,持续关注:
石杉的架构笔记(id:shishan100)
十余年BAT架构经验倾囊相授
推荐阅读:2、【双11狂欢的背后】微服务注册中心如何承载大型系统的千万级访问?
3、【性能优化之道】每秒上万并发下的Spring Cloud参数优化实战
6、大规模集群下Hadoop NameNode如何承载每秒上千次的高并发访问
7、【性能优化的秘密】Hadoop如何将TB级大文件的上传性能优化上百倍
8、拜托,面试请不要再问我TCC分布式事务的实现原理坑爹呀!
9、【坑爹呀!】最终一致性分布式事务如何保障实际生产中99.99%高可用?
11、【眼前一亮!】看Hadoop底层算法如何优雅的将大规模集群性能提升10倍以上?
16、亿级流量系统架构之如何设计全链路99.99%高可用架构
18、大白话聊聊Java并发面试问题之volatile到底是什么?
19、大白话聊聊Java并发面试问题之Java 8如何优化CAS性能?
20、大白话聊聊Java并发面试问题之谈谈你对AQS的理解?
21、大白话聊聊Java并发面试问题之公平锁与非公平锁是啥?
22、大白话聊聊Java并发面试问题之微服务注册中心的读写锁优化
23、互联网公司的面试官是如何360°无死角考察候选人的?(上篇)
24、互联网公司面试官是如何360°无死角考察候选人的?(下篇)
25、Java进阶面试系列之一:哥们,你们的系统架构中为什么要引入消息中间件?
26、【Java进阶面试系列之二】:哥们,那你说说系统架构引入消息中间件有什么缺点?
27、【行走的Offer收割机】记一位朋友斩获BAT技术专家Offer的面试经历
28、【Java进阶面试系列之三】哥们,消息中间件在你们项目里是如何落地的?
29、【Java进阶面试系列之四】扎心!线上服务宕机时,如何保证数据100%不丢失?
作者:石杉的架构笔记
链接:https://juejin.im/post/5c1c8f5a6fb9a049fe351f36
来源:掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。