kafka producer异步发送在失败回调里close,会失去前面retry的request的正确回调结果

我们使用producer异步发送,在失败的callback里close(0)来中止任何后序发送中的数据,在正常情况时效果非常好,但有个异常情况无法解决:

我们的in.flight为1,当一个request因为网络抖动长时间写不成功时,会得到如下WARN日志然后request进行重试:

Got error produce response with correlation id 19889 on topic-partition test1_local-0, retrying (5 attempts left). Error: NETWORK_EXCEPTION

但这个重试的request会耽误后序的batch,导致后序的batch抛出异常:

TimeoutException: Expiring 309 record(s) for test3_local-3: 30001 ms has passed since batch creation plus linger time

发送失败的这个后序batch在我们的callback里显式调用了close(0),问题来了,close(0)之后,前面retrying的request实际上都能retry成功写入broker,但在callback里显示失败:

IllegalStateException: Producer is closed forcefully.

由于我们的数据发送的序号是根据回调的成功来递增的,重新建立producer之后,会选择从最后一个成功回调的数据序号继续发送,导致retry的数据全部重复了一遍。

请问博主,解决这个异常的场景的思路在哪里呢?






发表于: 9月前   最后更新时间: 9月前   游览量:2995
上一条: kafka connector一直报错java.lang.IllegalArgumentException: Number of groups must be positive.这是啥错
下一条: kafka发送消息慢

评论…


  • 问题解决了,问题在于我们用同一个producer发送很多topic-partition,发送中的partition不会做超时检查,但指向同一个broker而且因为前面request导致等待未发送的partition的batch会被检查超时。我在这里回答,给其他人提供相同问题的解决办法,producer尽量减少发送的topic-partition,即使同一个topic如果partition多于broker数,也会容易出相同问题。
    • 大哥,请问一下“同一个producer发送很多topic-partition”这句话是什么意思?是说topic的partition数少设一点,不要超过broker个数就可以了吗?
      producer.config对应的配置文件和consumer.config对应的配置文件还有什么其他配置项是需要注意的吗?谢谢
        • “同一个producer发送很多topic-partition”这句话是说,要尽量少的共享使用同一个producer对象并发的发送多个partition,比如多线程使用同一个producer对象进行同步发送,或者单线程使用同一个producer对象进行异步发送。
            • 遇到一样的问题,谢谢提醒。
              还有一个问题,kafka估计有一个返回的验证机制,发送完后立即关闭进程。会导致错误。
              这个社区有群么?
              • 评论…
                • in this conversation