• shan
    2023-09-16 来自河南
    生产者消息发送幂等方案 1. 通过消息唯一ID实现幂等 在发送消息的时候,比如使用snowflake雪花算法为每条消息生成一个唯一的消息ID,并且需要保证同一个消息ID发送到同一个分区中,Broker端根据消息ID判断之前是否接收过。 Broker需要保留接收过的所有消息ID集合,需要占用大量空间,可以从以下几个方面进行优化: (1)Broker以Topic维度保存消息ID,不需要保存集群的所有消息ID; (2)消息ID集合只保留未过期的消息,依赖于消息过期机制的设计; (3)通过布隆过滤器来判断; 2. 通过生产者ID和自增序号实现幂等 为每个生产者赋予一个唯一ID,生产者启动时生成一个从0开始的自增序号seqnum表示发出去的消息编号,通过生产者ID+seqnum二元组来唯一确定一条消息。 思路与第一种方案类似,只是把标识从消息ID改为了生产者ID + seqnum。 不过方案2有一个小技巧,它可以不保存生产者所有发送成功的seqnum集合,因为这个是自增的,只保留最新收到的seqnum,如果收到的消息的seqnum是下一条,就正常保存数据,否则就放进队列中先等待,等待下一条消息收到后,再来判断是否保存该数据。 目前主流的消息队列只有Kafka支持幂等发送,RocketMQ、RabbitMQ、Pulsar都不支持。 Kafka幂等发送的思路采用的方案2,它通过Producer ID、Topic、PartitionNum、seqnum四元组来唯一标识一条消息,不过为了高性能,并不能保证完全的幂等。
    展开
    
    
  • shan
    2023-09-16 来自河南
    RocketMQ顺序消息实现 消息一般分为全局有序和局部有序。 全局有序:为Topic设置一个消息队列,使用一个生产者单线程发送数据,消费者端也使用单线程进行消费,从而保证消息的全局有序,但是这种方式效率低,一般不使用。 局部有序:比如想保证某个订单的相关消息有序,那么就使用订单ID当做路由ID,在发送消息的时候,将这个订单相关的消息,通过路由ID将所有消息发送到同一个消息队列中,保证消息在某个消息队列中是有序的,消费者端通过MessageListenerOrderly处理有序消息,这就是RocketMQ的局部有序。 对于生产者保证消息局部有序,只需要将消息发送到同一个消息队列中即可。 对于消费者来说,是通过加锁来保证消息顺序消费的,一共有三把锁: 1. 在集群模式下一个消息队列同一时刻只能被同一个消费组下的某一个消费者进行,为了避免负载均衡等原因引起的变动,消费者会向Broker发送请求对消息队列MessageQueue进行加锁。 2. 消费拉取到消息之后,对拉取的消息进行处理的时候,由于可以开启多线程进行处理,所以处理前会对MessageQueue加锁,锁住要处理的消息队列,主要是处理多线程之间的竞争,保证消息的顺序性。 3. 在真正消费消息之前,还会再加一把消费锁,主要是为了避免在消费消息时,由于负载均衡等原因,MessageQueue对应的ProcessQueue被删除。 最近刚好写了一篇总结:https://www.cnblogs.com/shanml/p/17706095.html
    展开
    
    
  • LWD
    2023-09-14 来自广东
    单个生产者单个分区也不一定保证发送有序。因为链接可能多个,举个例子,发送消息1到这个链接通道,然后连接超时实际已经到服务端了,此时重新创建连接在发送一个,这时候服务端可能先消费后一个的。。。。
    
    
  • zhuxiaoxiao
    2023-09-12 来自浙江
    顺序消息消费是怎么保证顺序的
    
    
  • Geek_5d0074
    2023-08-24 来自江西
    RocketMQ怎么保证幂等呢?
    
    