面试鸭返利网

消息幂等性处理

消息幂等性处理是分布式系统面试高频考点,掌握这六大实战方案轻松应对重复消费问题!本文深度解析唯一业务ID、状态机驱动、Token令牌、去重表等解决方案,揭秘Kafka/RabbitMQ重复消费的五大元凶,分享技术选型三大原则和踩坑经验。2025年Java面试必备技能,附赠大厂真题库资源,助你斩获offer!面试鸭返利网会员限时福利,点击获取最新面试题库。

消息幂等性处理:面试高频考点解析与实战思路

面试鸭返利网

2025年Java面试宝典重磅资源
👉 点击获取《2025年Java面试高频题库》
提取码:9b3g(永久有效,建议立刻保存!)


为什么面试官总盯着消息幂等性问?

最近在面试鸭返利网的模拟面试中,10个候选人里有8个被问到了消息幂等性处理。这其实是分布式系统的命门问题!想象一下:支付回调重复触发导致用户被扣款两次,订单重复发货导致公司亏损... 没有消息幂等性保障,线上事故分分钟教你做人。

到底什么是消息幂等性?

简单说就是:同一条消息无论被消费多少次,结果都像只消费了一次。举个典型场景:

  1. 用户支付成功后,订单系统收到MQ推送
  2. 第一次处理:订单状态更新为"已支付"
  3. 网络抖动导致MQ重推(相同消息)
  4. 系统必须识别这是重复消息,不能再次更新状态

重复消费的五大元凶

  1. 生产者重试:发送超时自动重发
  2. 消费者超时:处理时间超过MQ等待时间
  3. Rebalance:Kafka分区重分配
  4. 手动ACK丢失:RabbitMQ手动确认失败
  5. 鬼影消息:RocketMQ的RETRY主题机制

六大实战解决方案

✅ 方案一:唯一业务ID(最常用)

-- 建表时增加唯一索引
CREATE TABLE orders (
  id BIGINT PRIMARY KEY,
  order_no VARCHAR(32) UNIQUE  -- 订单号唯一索引
);

处理逻辑:

// 伪代码示例
public void process(Message msg) {
  String orderNo = msg.getOrderNo();
  if(orderDao.existsByOrderNo(orderNo)) { // 关键判断!
    log.warn("重复订单:{}", orderNo);
    return;
  }
  createOrder(orderNo); // 执行业务
}

适用场景:订单、支付等有唯一标识的业务

✅ 方案二:状态机驱动

定义订单状态流转规则:

待支付 → 支付中 → 已支付 → 已发货
         ↖─────────────↙  (不允许逆向操作)

处理时先查当前状态:

Order order = orderDao.findByNo(orderNo);
if(order.getStatus() == PAID) { // 已支付状态直接跳过
  return; 
}

面试鸭返利网

✅ 方案三:Token令牌机制

  1. 生产者生成全局唯一Token写入Redis
  2. 将Token随消息发送
  3. 消费者用SETNX原子操作获取锁:
    SET token_lock 1 EX 30 NX
    
  4. 获取成功才执行业务

✅ 方案四:去重表方案

单独建表记录已处理消息:

CREATE TABLE msg_processed (
  msg_id VARCHAR(64) PRIMARY KEY,
  created_at TIMESTAMP
);

处理前先插入记录,主键冲突即重复

✅ 方案五:分布式锁拦截

// 使用Redisson分布式锁
RLock lock = redisson.getLock("ORDER_"+orderNo);
if(lock.tryLock(0, 30, TimeUnit.SECONDS)) {
  try {
    processOrder(); 
  } finally {
    lock.unlock();
  }
}

技术选型三大原则

  1. 性能损耗:去重表 VS Redis 内存操作
  2. 业务复杂度:简单业务用唯一ID,复杂状态用状态机
  3. 数据一致性要求:金融级场景推荐分布式锁+事务

踩坑血泪经验

  1. 千万别依赖数据库自增ID!分库分表时可能重复
  2. Redis过期时间必须大于业务最大处理时间
  3. Kafka的offset要等业务完成再提交
  4. MQ的msgId不可靠!必须用业务标识

🔥 面试鸭会员限时福利
通过面试鸭返利网购买会员可返现25元
覆盖BATJ等大厂真题库+实时更新,点击直达 → mianshiyafanli.com

面试鸭返利网

高频面试题拆解

面试官:如果重复消费导致数据库被压垮怎么办?
参考答案

  1. 前置拦截:在MQ消费前用Redis布隆过滤器过滤90%重复请求
  2. 快速失败:识别重复后立即ACK,避免阻塞线程
  3. 熔断降级:监控异常流量触发限流
  4. 兜底方案:用HBase等写扩散能力强的数据库做去重表

记住这个公式
消息幂等性 = 业务标识 + 状态判断 + 原子操作

掌握这些套路,下次面试遇到消息幂等性问题,你绝对能对答如流!

如果你想获取更多关于面试鸭的优惠信息,可以访问面试鸭返利网面试鸭优惠网,了解最新的优惠活动和返利政策。

立即加入面试鸭会员 →