说明
- Kafka没有实现延时队列、死信队列、也没有重试机制。但是Spring-Kafka 封装了消费重试和死信队列。
- 这个是伪需求,只是一道面试题,不要太较真。
- 文章介绍了两个方案,有什么出错的地方,麻烦大佬们指出来,再次先谢谢啦。
Kafka 如何实现延时队列
- Kafka 如何实现延时队列 - 首先,先讲一个常见的业务场景吧,我们对这个场景进行扩展。比如,一个订单场景,一个用户下单后,如果超过30分钟后还没付款,那么我们就要取消这个订单,这时候就可以用延时队列了。- 方案一: - 订单服务,用户下单就会生成一个新订单,然后把订单发送给kafka,因为kafka不支持延时队列,所以,我们自己做一个延迟服务,把kafka的订单消息发送给延时服务。- 这个延时服务,过了30分钟后就要把这个订单消息发送kafka,然后订单服务消费这个延迟消息,再做业务处理(判断用户是否付款,如果没有付款就取消订单)。- 至于这个延时服务,我们可以用Java的延时队列来做。- 需要注意的是,我们需要保证延时服务的相对的可靠性,需要做: - 延迟消息的消费者手动提交offset- 延迟消息的消费者要做幂等性处理(根据业务需要)- 延时服务做 集群- 问题:如果延时服务挂了,那么将会丢掉消息,即使做集群,也会丢失。比如,消息A发送给节点A,节点A挂了,消息A的数据就丢了。后续流量都打到节点B,也就是集群只是保证后续消息的可靠性。- 思考:如果一定要用这种方案,如何优化呢? - 前端上做文章,比如,前端也搞个计时器,如果超过30分钟,那么订单页面就不要显示。(虽然前端防君子不防小人,但是99.99%的用户都是君子,前端还是有用的)- 人工补偿,运维定时去扫描订单表,如果订单有些因为上诉问题带来未及时关闭的问题,那么运维可以手动关闭。- 方案二: - 不要延时服务,订单服务发送一个消息,发送一个消息给kafka,这个消息要添加时间信息:30分钟的时间戳。为了保证顺序性,指定一个key,这样能保证所有消息在同一个partition(同一partition有序)。- 然后订单服务,开启一个线程,一直轮询kafka,如果系统当前时间大于第一个消息的时间戳,那么就可以消费了。- 问题: - 带来消息的积压,压力来到kafka这边。- 而且要轮询,消费者也要牺牲一点轮询的性能。- 降低吞吐量,因为指定了key,只使用了一个partition(为了保证消息在kafka内部的有序)。- 好处:解决了方案一的问题。
本文转载自: https://blog.csdn.net/HuangJiaxinZ/article/details/126957232
版权归原作者 HuangJiaxinZ 所有, 如有侵权,请联系我们删除。
版权归原作者 HuangJiaxinZ 所有, 如有侵权,请联系我们删除。