出现“活锁”的情况,是它持续的发送心跳,但是没有处理。为了预防消费者在
这种情况下一直持有分区,我们使用 max.poll.interval.ms 活跃检测机制。 在此
基础上,如果你调用的 poll 的频率大于最大间隔,则客户端将主动地离开组,以
便其他消费者接管该分区。 发生这种情况时,你会看到 offset 提交失败(调用
commitSync()引发的 CommitFailedException)。这是一种安全机制,保障
只有活动成员能够提交 offset。所以要留在组中,你必须持续调用 poll。
消费者提供两个配置设置来控制 poll 循环:
max.poll.interval.ms:增大 poll 的间隔,可以为消费者提供更多的时间去处理返
回的消息(调用 poll(long)返回的消息,通常返回的消息都是一批)。缺点是此值
越大将会延迟组重新平衡。
max.poll.records:此设置限制每次调用 poll 返回的消息数,这样可以更容易的
预测每次 poll 间隔要处理的最大值。通过调整此值,可以减少 poll 间隔,减少重
新平衡分组的
对于消息处理时间不可预测地的情况,这些选项是不够的。 处理这种情况的推荐
方法是将消息处理移到另一个线程中,让消费者继续调用 poll。 但是必须注意确
保已提交的 offset 不超过实际位置。另外,你必须禁用自动提交,并只有在线程
完成处理后才为记录手动提交偏移量(取决于你)。 还要注意,你需要 pause 暂
停分区,不会从 poll 接收到新消息,让线程处理完之前返回的消息(如果你的处
理能力比拉取消息的慢,那创建新线程将导致你机器内存溢出)。