消息队列问题

重复消费(幂等性)

1. token

流程

  1. 执行业务前,先获取 token ,服务器把 token 保存到 redis
  2. 客户端调用业务接口请求时, 携带 token (一般放在请求头部)
  3. 服务器判断 token是否存在 redis 中, 若存在则表示第一次请求, 然后删除 token, 继续执行业务
  4. 如果判断 token 不在 redis 则表示重复操作,直接返回

需要原子性保证

tolen 的获取、比较、删除,都需要原子性,避免并发问题

2. 唯一约束

数据库唯一约束

  • 插入索引时,按照唯一索引插入,防止重复
  • 不能是自增主键,需要生成全局唯一主键
  • 分布式数据库时,需要路由规则保证每次请求在同一数据库和表中

redis set 防重

  • 计算数据MD5信息放入 redis set,处理前先查询是否存在

数据丢失

rabbitMQ

生产者数据丢失

confirm机制:每次写的消息都会分配一个唯一的 id,然后如果写入了 RabbitMQ 中,RabbitMQ 会回传一个 ack 消息。如果 RabbitMQ 没能处理这个消息,会回调 nack

RabbitMQ数据丢失

持久化:开启queue 的元数据 与 消息

消费端数据丢失

关闭 RabbitMQ 的自动 ack

kafka数据丢失

配置:

  • 每个 partition 必须有至少 2 个副本
  • Leader 至少有一个 follower
  • 要求每条数据,必须是写入所有 replica 之后,才能认为是写成功了
  • 要求一旦写入失败,就无限重试

消费顺序

rabbitMQ:一个queue对应一个消费者

Kafka: