1.简介
RabbitMQ 中,消息丢失可以简单的分为两种:客户端丢失和服务端丢失。针对这两种消息丢失,RabbitMQ 都给出了相应的解决方案。
2.防止客户端丢失消息
如图,生产者 P 向队列中生产消息,C1 和 C2 消费队列中的消息,默认情况下,RabbitMQ 会平均的分发消费给 C1C2(Round-robin dispatching),假设一个任务的执行时间非常长,在执行过程中,客户端挂了(连接断开),那么,该客户端正在处理且未完成的消息,以及分配给它还没来得及执行的消息,都将丢失。因为默认情况下,RabbitMQ 分发完消息后,就会从内存中把消息删除掉。
3.消息确认(Message acknowledgment)
为了解决上述问题,RabbitMQ 引入了消息确认机制,当消息处理完成后,给 Server 端发送一个确认消息,来告诉服务端可以删除该消息了,如果连接断开的时候,Server 端没有收到消费者发出的确认信息,则会把消息转发给其他保持在线的消费者。
验证上述问题
首先,我们验证上述问题(客户端丢失消息)是否真的存在,对 Consumer 进行如下改造。
先生产两条消息
启动消费者,在消费者接收到消息,还没处理完成的时候,强制关掉
这时,观察控制台,发现两条消息都没有了,1 条是在执行中丢失的,还有 1 条,已经分配给这个 Consumer,还没来得及处理,也丢失了
这证明了上述问题是真的存在的,如果发生在生产环境,将产生难以预料的后果
引入消息确认机制
为了方便观察,我们用 CMD 来运行 Consumer,要通过 maven 打成可执行的 JAR 包,需要在 pom.xml 中增加如下配置
ConsumerfinalName>
maven-assembly-pluginartifactId>
falseappendAssemblyId>
jar-with-dependenciesdescriptorRef>
descriptorRefs>
com.liyang.ticktock.rabbitmq.AppmainClass>
manifest>
archive>
configuration>
make-assemblyid>
packagephase>
assemblygoal>
goals>
execution>
executions>
plugin>
org.apache.maven.pluginsgroupId>
maven-compiler-pluginartifactId>
欢迎来到这里!
我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。
注册 关于