ActiveMQ支持同步、异步两种发送模式将消息发送到消息中间件上。
同步发送过程中,发送者发送一条消息会阻塞直到消息中间件反馈一个确认消息,表示消息已经被消息中间件处理。这个机制提供了消息的安全性保障,但是由于是阻塞的操作,会影响到客户端消息发送的性能。异步发送的过程中,发送者不需要等待broker提供反馈,所以性能相对较高。但是可能会出现消息丢失的情况。所以使用异步发送的前提是在某些情况下允许出现数据丢失的情况。
默认情况下,非持久化消息是异步发送的,持久化消息并且是在非事务模式下是同步发送的。但是在开启事务的情况下,消息都是异步发送。由于异步发送的效率会比同步发送性能更高,所以在发送持久化消息的时候,尽量去开启事务会话。
1.消息由于网络问题重复消费
(1)让每个消息携带一个全局的唯一ID(雪花算法、UUID等等),即可保证消息的幂等性,具体消费过程为:
- 消费者获取到消息后先根据id去查询redis/db是否存在该消息
- 如果不存在,则正常消费,消费完毕后写入redis/db
- 如果存在,则证明消息被消费过,直接丢弃。
(2)通过数据库的唯一键实现消息的幂等性
可以在设计消息结构的时候设置一个对应数据库唯一键的列字段,业务成功后将此字段作为唯一键保存入数据库。当同样的ID做保存的时候就会出现违反数据库唯一约束异常,这里的主键可以是单独的,也可以是组合的列。这种方式可以在任何支持“INSERT IF NOT EXIST”的存储系统中适用。