上云无忧 > 文档中心 > 腾讯云消息队列 Pulsar 版实战教程 - 消息幂等性
消息队列 Pulsar 版
腾讯云消息队列 Pulsar 版实战教程 - 消息幂等性

文档简介:
应用的幂等是在分布式系统设计时必须要考虑的一个关键点。如果对幂等没有额外的考虑,那么在业务出现处理失败的情况时,可能出现重复消费相同的消息,从而导致出现不符合业务预期的情况。为了避免上述异常,消息队列的消费者在接收到消息后,有必要根据业务上的唯一 Key 对消息做幂等处理。
*此产品及展示信息均由腾讯云官方提供。免费试用 咨询热线:400-826-7010,为您提供专业的售前咨询,让您快速了解云产品,助您轻松上云! 微信咨询
  免费试用、价格特惠
应用的幂等是在分布式系统设计时必须要考虑的一个关键点。如果对幂等没有额外的考虑,那么在业务出现处理失败的情况时,可能出现重复消费相同的消息,从而导致出现不符合业务预期的情况。为了避免上述异常,消息队列的消费者在接收到消息后,有必要根据业务上的唯一 Key 对消息做幂等处理。

什么是消息幂等

定义

当业务多次消费到同一条消息的结果与消费一次的结果是相同的,同时多次消费同一条消息并未对业务系统产生任何负面影响,那么这个消费者的处理过程就是幂等的。

场景示例

举个例子,在银行支付系统的场景下,当消费端消费到扣款消息后,系统将对订单执行扣款操作,扣款金额为1元。如果因由于网络不稳定等一些原因导致扣款消息再次被消费到,如果最终的业务结果是只扣款一次,扣费1元,且用户的扣款记录中对应的订单只有一条扣款流水,并没有多次被多次扣费,那么这次扣款操作是符合要求的,整个消费过程实现了消费幂等。

适用场景

发送消息引起消息重复场景

生产者在发送一条消息后,服务端接收成功并完成持久化,如果此时出现了网络闪断或者客户端重启等异常导致服务端对客户端应答失败,此时生产者由于没有收到服务端的确认消息,从而尝试再次发送消息,这时会导致后续消费者会收到两条内容相同但 Message ID 不同的消息。

消费消息引起消息重复场景

消费端消费到了消息并完成业务处理,当消费端给服务端返回 ACK 的时候,此时网络发生异常。当消费端再次来消费消息时,会再次消费到已被处理过的消息,消费者收到了两条内容相同并且 Message ID 也相同的消息。

处理方案

根据以上两种场景可以看出消息重复会出现以下两种情况:
可能出现不同的 Message ID 对应的消息内容相同。
可能是相同的 Message ID 同时消息内容相同。
所以不建议以 Message ID 作为处理依据,建议以业务的唯一标识作为幂等处理的依据。例如支付场景可以将订单号,作为幂等处理的依据。消费到消息后,取出业务中的订单号,业务根据订单号进行判断是否被处理。

代码示例

		
public static class Order {
public String orderId;
public String orderData;
}
生产端
		
Producer<Order> producer = client.newProducer(Schema.AVRO(Order.class)).create();
producer.newMessage().value(new Order("orderid-12345678", "orderData")).send();
消费端
		
Consumer<Order> consumer = client.newConsumer(Schema.AVRO(Order.class)).subscribe();
Order order = consumer.receive().getValue();
String key = order.orderId;
获取到业务的唯一标识 orderId 后,对其进行去重操作。

常见的去重方式

利用数据库进行去重

业务上的幂等操作可以添加一个过滤的数据库,例如设置一个去重表,也可以在数据库中通过唯一索引来去重。
举一个例子,现在要根据订单流转的消息在数据库中写一张订单 Log 表,可以把订单 ID 和修改时间戳做一个唯一索引进行约束。
当消费端消费消息出现相同内容的消息,会多次去订单 Log 表中进行写入,由于添加了唯一索引,除了第一条之外,后面的都会失败,这就从业务上保证了幂等,即使消费多次,也不会影响最终的数据结果。

设置全局唯一消息 ID 或者任务 ID

调用链 ID 也可以应用在这里。在消息生产的时候向每条消息中添加一个唯一 ID,消息被消费后,在缓存中设置一个 Key 为对应的唯一 ID,代表数据已经被消费,当消费端去消费时,就可以根据这条记录,来判断是否已经处理过。

相似文档
  • 背景描述: 由于 Pulsar 限制消息最大为5MB,消息体过大将会导致消息发送失败。这时需要客户端将大消息进行压缩,以支持20MB大小的消息体发送。
  • 什么是消息队列 Pulsar 版? 消息队列 Pulsar 版(TDMQ for Pulsar,简称 TDMQ Pulsar 版)是一款基于 Apache Pulsar 自研的消息中间件,具备极好的云原生和 Serverless 特性,兼容 Pulsar 的各个组件与概念,具备计算存储分离,灵活扩缩容的底层优势。
  • 如何申请使用 TDMQ Pulsar 版? 首次进入 TDMQ Pulsar 版控制台 即可开通使用。
  • 为使用腾讯云消息队列 TDMQ 服务(以下简称“本服务”),您应当阅读并遵守《消息队列 TDMQ 服务等级协议》(以下简称“本协议” 或“SLA”),以及《腾讯云服务协议》。本协议包含本服务的术语和定义、服务可用性/服务成功率等级指标、赔偿方案、免责条款等相关内容。请您务必审慎阅读、充分理解各条款内容,限制、免责条款或者其他涉及您重大权益的条款可能会以加粗、加下划线等形式提示您重点注意。
  • 消息队列 CMQ 版(TDMQ for CMQ,简称 TDMQ CMQ 版)是一种分布式消息队列服务,它具有可靠的、基于消息的异步通信机制,能够将分布式部署的不同应用(或同一应用的不同组件)中的信息传递,存储在可靠有效的消息队列中,防止消息丢失。TDMQ CMQ 版支持多进程同时读写,收发消息互不干扰,无需各应用或组件始终处于运行状态。
官方微信
联系客服
400-826-7010
7x24小时客服热线
分享
  • QQ好友
  • QQ空间
  • 微信
  • 微博
返回顶部