resttemplate默认超时时间_深入理解Kafka客户端之超时批次的处理

本文深入探讨Kafka客户端超时批次的处理,包括Sender线程如何检查并处理超时的InFlightBatches,以及resttemplate默认超时时间的设定。分析源码揭示了超时判断、批次状态管理和资源释放的细节。
摘要由CSDN通过智能技术生成

一、场景分析

     前面提到,消息封装成批次对象ProducerBatch后,会放到RecordAccumulator对应的Deque队列,等待Sender线程去发送。但是封装好的批次会有一个时间限制,如果超过这个时间限制还未发送成功,那么就会将该批次标记为超时批次,从而执行相应的处理。那么客户端如何处理这种超时的批次呢?为什么超时批次会导致数据重复?这篇进行详细的分析。 二、图示说明

    首先更正一下《深入理解Kafka客户端之服务端响应及超时请求的处理》中的流程图,图中少画了一个数据结构:InFlightBatches,这个结构保存的是正在发送的批次。当Sender线程将缓存中的批次拿出来封装成请求的同时,会将这个批次放到InFlightBatches结构中,即标记这些批次正在发送,当发送成功,会将这个批次从InFlightBatches中移除,同样,如果批次超时,也会将该批次移除。

    超时批次的处理主要在右下角Sender线程这块:

51378978651675ff598721ee9e84a67a.png

三、过程源码分析

    还是从Sender的runOnce方法看起,主要看下面的代码:

long pollTimeout = sendProducerData(currentTimeMs);
private long sendProducerData(long now) {
        ...    //TODO 步骤六:对超时批次对处理(由于没有建立网络连接,第一次这里的代码也不执行)这里的超时指生成的批次超过120s未发送或者发送了未返回响应    //获取inflightBatches集合中已经超时的批次,    // inflightBatches记录的是从缓存中取出来的批次,上面进行合并时,将批次从Deque中取出来    List expiredInflightBatches = getExpiredInflightBatches(now);    //获取缓存中已经过期的批次,这里指还未发送就已经超时的批次    List expiredBatches = this.accumulator.expiredBatches(now);    //获取总的过期的批次    expiredBatches.addAll(expiredInflightBatches);    if (!expiredBatches.isEmpty())        log.trace("Expired {} batches in accumulator", expiredBatches.size());    //遍历处理过期的批次    for (ProducerBatch expiredBatch : expiredBatches) {
            String errorMessage = "Expiring " + expiredBatch.recordCount + " record(s) for " + expiredBatch.topicPartition            + ":" + (now - expiredBatch.createdMs) + " ms has passed since batch creation";        //TODO 处理超时的批次        failBatch(expiredBatch, -1, NO_TIMESTAMP, new TimeoutException(errorMessage), false);        if (transactionManager != null && expiredBatch.inRetry()) {
                // This ensures that no new batches are drained until the current in flight batches are fully resolved.            transactionManager.markSequenceUnresolved(expiredBatch.topicPartition);        }    }    ...}
1. 在sendProducerData方法中,首先获取inFlightBatches中超时的批次:
List<ProducerBatch> expiredInflightBatches = getExpiredInflightBatches(now);
private ListgetExpiredInflightBatches(long now) {
        List expiredBatches = new ArrayList<>();    for (Iterator>> batchIt = inFlightBatches.entrySet().iterator(); batchIt.hasNext();) {
            Map.Entry> entry = batchIt.next();        //获取每个分区对应的List集合        List partitionInFlightBatches = entry.getValue();        //说明指定的分
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值