背景
最近碰到一个比较奇怪的问题,某个fanout exchange通过trace日志可以看到消息已经published,但是无论是admin页面还是针对queue的trace都看不到,并且更离谱的是部分消息是正常的。也就是说有些消息进到exchange就莫名其妙被丢弃了。
在确认消息荷载没什么异常后,通过抓包对比发现,能投进exchange的消息都在publish后进行了tx.commit,而另一部分没有。显而易见,该channel实际上开启了事务机制。
由于最终没有commit,所以exchange的trace日志看得到publish记录,实际上却没有提交到exchange。
事务机制
这里简单引申下,rabbitmq的事务机制可以确保消息的可靠到达,常见使用场景:
1.将发送消息和其他事件绑定,例如数据库读写失败时,可通过回滚取消消息发送
2.批量发送多条关联消息,通过事务确保全部发送成功或失败
事务是针对channel的设置,包括以下几个方法:
channel.txSelect()启动;
channel.txCommint()提交;
channel.txRollback()回滚;
publisher confirm
而作为确保消息到达服务器的可靠性实现,publisher confirm更加常见。
同样是针对channel,具体分为三种模式:
1.单条确认模式,发布后阻塞式地等待服务端confirm
2.批量发送,批量阻塞确认
3.通过设置回调函数,异步确认
除非有特殊要求,Publisher Confirm机制已经适用于大多数应用场景,它提供了较好的性能和可靠性,而不需要像事务机制那样带来较大的性能开销。