Node.js连接器场景下消息顺序处理异常的问题咨询
WhatsApp与CCM消息交互的重复聊天问题
背景流程
我有一个Node.js连接器应用,用于实现WhatsApp和CCM之间的消息交互,流程如下:
- 连接器接收来自WhatsApp的消息
- 将消息转发至CCM
- CCM将消息发布至SNS主题
- 消息发布成功后,CCM向连接器返回
200 OK响应,标识异步通信成功 - CCM同时订阅同一SNS主题以接收已发布的消息(即CCM的一个端点发消息到SNS,另一个端点接收并处理)
- 接收消息后,CCM调用Amazon Connect Chat API发起聊天
遇到的问题
当连续快速发送2-3条消息时,CCM会为同一客户启动多个聊天。原因是CCM处理第一条消息需要时间(包含根据消息信息从数据库查找客户等操作),后续消息很快到达,导致重复创建聊天。
咨询问题
- 这种行为在发布-订阅系统中是否正常?
- 能否提供该问题的解决方案?
- CCM是否应等待第一条消息的确认后再处理后续消息?
问题1:这种行为在发布-订阅系统中是否正常?
是正常的。SNS这类发布-订阅系统本身是异步、松耦合的,消息发布后会立即推送给订阅者,不会等待之前的消息处理完成。如果CCM订阅端没有做并发控制或幂等处理,多条消息快速到达时就会出现并行处理的情况,进而导致重复创建聊天。这不是SNS的问题,而是业务逻辑层缺少必要的并发约束。
问题2:解决方案
针对这个问题,有几种可行的方案:
- 基于客户ID的分布式锁:CCM处理消息前,先根据客户唯一标识(比如WhatsApp用户ID)获取分布式锁(可通过Redis的SETNX、DynamoDB的条件写入实现)。只有获取到锁的消息才能执行创建聊天的逻辑,后续消息等待锁释放后,先检查是否已有活跃聊天,再决定是创建还是追加消息。
- 消息去重与幂等处理:给每条消息生成唯一ID,CCM处理前先检查该消息是否已被处理过(可存在数据库或缓存中)。同时在创建聊天的逻辑里,先查询该客户是否已有未结束的聊天会话,有则直接复用,不再新建。
- 队列化处理单客户消息:将同一客户的消息路由到同一个消息队列分区(比如SQS的FIFO队列,按客户ID作为分组键),确保同一客户的消息被串行处理,避免并发执行。
- 调整SNS订阅的并发设置:如果使用SNS+SQS的组合,可将SQS的并发消费者数量设为1,或按客户ID做消息分组,保证同一客户的消息串行处理。
问题3:CCM是否应等待第一条消息的确认后再处理后续消息?
这取决于业务需求和系统性能要求:
- 如果业务必须保证同一客户的消息严格串行处理,且能接受一定延迟,可以采用串行处理的方式(比如用FIFO队列),但这种方式会降低系统并发处理能力,不适合高流量场景。
- 更推荐的方式是不强制等待确认,而是通过锁或幂等逻辑避免重复操作。这样既保留系统的并发能力,又能防止重复创建聊天。等待确认的方式会引入同步依赖,增加系统复杂度和延迟,并非最优解。
内容的提问来源于stack exchange,提问作者Subhan Chaudhry
相关产品推荐
相关产品推荐

