1、场景作用
削峰填谷,异步解耦。
2、如何保证消息不被重复消费呢?
这个问题可以换个思路,保证消息重复消费,其实是保证程序的幂等性。无论消息如何重复,程序运行的结果是一致的。比如消费消息后做数据库插入操作,为了防止消息重复消费,可以在插入前先查询一下有没有对应的数据。
3、怎么保证从消息队列里拿到的数据按顺序执行?
消费端在接收到消息后放入内存队列,然后对队列中的消息进行有序消费。
4、如何解决消息队列的延时以及过期失效问题?消息队列满了以后该怎么处理?有几百万消息持续积压几小时,说说怎么解决?
消息过期失效问题,如果消息一段时间不消费,导致过期失效了,消息就丢失了,只能重新查出丢失的消息,重新发送。 再来说消息积压的问题:(思路是快速消费掉积压的消息)
- 首先排查消费端问题,恢复消费端正常消费速度。
- 然后着手处理队列中的积压消息。
- 停掉现有的 consumer。
- 新建一个 topic ,设置之前 10 倍的 partation,之前 10 倍的队列。
- 写一个分发程序,将积压的消息均匀的轮询写入这些队列。
- 然后临时用 10 倍的机器部署 consumer,每一批 consumer 消费 1 个临时的队列。
- 消费完毕后,恢复原有架构。
消息队列满了:只能边接收边丢弃,然后重新补回丢失的消息,再做消费。
4、如何保证消息的可靠性传输(如何处理消息丢失的问题)?
kafka 为例:
- 消费者丢了数据: 每次消息消费后,由自动提交 offset 改为手动提交 offset 。
- kafka 丢了消息: 比较常见的一个场景,就是 kafka 某个 broker 宕机,然后重新选举 partition 的 leader 时。要是此时其他的 follower 刚好还有些数据没有同步,结果此时 leader 挂了,然后大家选举某个 follower 成为 leader 之后,不就少了一些数据。
- 给 topic 设置replication.factor参数:这个值必须大于 1,要求每个 partition 必须有至少两个副本。
- 在 kafka 服务端设置min.insync.replicas参数:这个值必须大于 1,这个是要求一个 leader 至少感知到有至少一个 follower 还跟自己保持联系,没掉队,这样才能确保 leader 挂了还有一个 follower。
- 在 producer 端设置acks=all:这个是要求每条数据,必须是写入所有 replica 之后,才能认为是写成功了。
- 在 producer 端设置retries=MAX(很大很大很大的一个值,无限次重试的意思):这个是要求一旦写入失败,就无限重试,卡在这里。
- 生产者丢了消息: 如果按照上述的思路设置了 ack=all,一定不会丢,要求是,你的 leader 接收到消息,所有的 follower 都同步到了消息之后,才认为本次写成功了。如果没满足这个条件,生产者会自动不断的重试,重试无限次。