1、可靠性
可靠性指什么? 就消息中间件来说。指已经生产的消息在各种异常情况下保持不丢失的特性就叫可靠性。可靠性靠什么手段来实现的?常见的手段就是“冗余”。也就是日志或者多副本。
日志刷盘的策略以及副本数的多少。决定了可靠性有多高。但是,可靠性和可用性在一定程度上是冲突的。可靠性高了,那么可用性或者吞吐量相应的就要降低。
2、顺序性
顺序性指什么?就消息中间件来说。顺序性是指生产者生产消息到队列时,可以保持发送时的顺序,消费者消费时,可以按生产者发送的顺序进行消费。这个就叫顺序性。
但是,有些时候。并不能保证消息的顺序性的。比如异步发送、或者出错重试时。都会产生顺序性问题。
因此,在需要保证消息顺序性的场景下。我们只能选择同步发送加确认的机制来生产消息。而同步发送是会牺牲吞吐量的。
3、重复问题
重复问题指什么? 这里有两方面,第一,生产者重复生产消息。第二,消费者重复消费消息。那么如何保证不发生重复问题呢?
重复问题,本质上应该是幂等问题。因此,解决方案也和解决幂等问题类似。对每一条消息自动生成一个唯一的序列号。服务端接收消息时,判断是否重复即可。更简单的,可以生成一个单调递增的序列号。服务端按顺序接收即可。
对于消费者而言。如何保证消息不重复消费。这里是有两种场景的。消息处理是有状态还是无状态的。无状态的话,重复消费对结果是不影响的。
有状态,那么处理后是有结果落地的,比如业务处理结果落地mysql或者redis。在落地的时候,我们可以根据该消息生成一个唯一的序列号。一起落地即可。
4、如何实现exactly one ?
什么是exactly one ? exactly one 指精确地一次。是消息传输语义的一种。消息传输语义有三种,分别是至少一次、至多一次、精确一次。
精确一次是比较难的。对生产或者消费的性能和吞吐量也有很大的影响。精确一次,本质上也就是要解决可靠性和重复性的问题。
至少一次,会产生重复问题。至多一次,会产生丢失问题。精确一次,即需要解决丢失和重复的问题。