持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第16天,点击查看活动详情
前言
- 之前公司使用rabbitmq作为消息中间件,但是经常发生消息丢失,之前我也专门发了一篇文章分析为什么会发生这种情况以及如何预防消息丢失。但是都是指标不治本,真正发生服务挂了的场景还是会发生消息丢失的,因为本质他就是传递消息,但是kafka不一样他是对消息进行持久化,之后通过偏移量来进行消息的分发的,所以一旦持久化了就不会发生消息丢失。
解释
-
任何消息中间件都会丢数据,不丢失数据只是特定场景,上面我也提到kafka消息不丢失是在持久化之后,kafka如果不丢失其实需要具备两个条件
-
就是上面提到的必须持久化了
-
另外一个就是kafka需要分布式,这样才能提高性能。必须保证有足够的broker数量来保证正常工作。N 个
broker中至少有 1 个存活。只要这个条件成立,kafka就能保证你的这条消息永远不会丢失。
策略
数据产生者
Producer端可能会丢失消息。目前Kafka Producer是异步发送消息的,也就是说如果你调用的是producer.send(msg)这个API,既然是异步的你就无法保证消息准确发送成功了,你只能保证的是你成功出发了发送的动作,这个时候需要你轮训查看消息的状态。kafka也不会要你不断轮训,只需要你提供回调接口这样只要发生失败了就会出发回调,这点和rabbitmq很想。
实际上,使用producer.send(msg, callback)接口就能避免这个问题,根据回调,一旦出现消息提交失败的情况,就可以有针对性地进行处理。如果是因为那些瞬时错误,Producer重试就可以了;如果是消息不合规造成的
消费者
kafka通过先消费-》更新offset,这个意思就是一堆信息排序好,你消费了给你一个序号,方便你能定位下次的消息
如果你开启多线程,呢么就难办了这里不分析了。 其实也简单你只需关闭自动提交,然后再你认为整个生命周期结束的时候在手动提交即可解决,这个和request的异步编程很像。所以说开源框架里的想法真的很好。