繁体   English   中英

Spring 具有重试和速率限制的批量分区

[英]Spring Batch Partitioning with retry and rate limit

背景

我正在使用 Spring Batch 通过 HTTP API 从我们的客户站点获取数据。 进度包含两个主要步骤:

  1. 从 API 获取总文档,然后使用可配置的页面大小计算总页面。 每个页面都将使用自定义Paritioner分配给一个分区步骤。
  2. 分区步骤将发送请求以获取数据页面(文档列表),处理并写入我们的存储。

客户网站可能是“脆弱的” 他们可能有速率限制,或者他们的网站可能在一些繁重的请求后没有响应。

到目前为止我做了什么

我正在使用spring-retry重新运行由于速率限制或服务器错误而失败的请求。 例如:

// the partition step's item reader
@StepScope
public class CustomItemReader extends ItemReader<Object> {
  private List<Object> items;
  @Override
  public Object read() {
    if (Objects.isNull(items)) {
      this.items = ImportService.getPage(pageId);
    }
    if (Objects.nonNull(items) && !items.isEmpty()) {
      return items.remove(0);
    }
    return null;
  }
}

// config retry for fetching function
public class ImportService {
  @Retryable(
      value = RetryableException.class,
      maxAttempts = 3,
      backoff = @Backoff(
          delay = 1000
      )
  )
  public static List<Object> getPage(String pageId) throws RetryableException {
    return ...;
  }
}

重试配置包含Backoff策略,该策略具有增量延迟 (1000 ms)。 我使用这个Retryable来处理重试和速率限制。

问题

  1. Retryable会反复等待并重新执行 function,它一直持有线程。 当事情变得更大时,实例可能会崩溃。
  2. 因为每个客户都有自己的速率限制,使用Retryable with Backoff并不是控制速率的理想方式。 尽管我为每个客户站点配置core_pool_sizecore_pool_size=1对某些人来说还不够。

问题

  1. 是否有任何适当的方法来限制 Spring 批处理的执行率,尤其是使用分区? 例如:我想配置在 10 秒内发送 2 个请求,而这不会通过在 step listener 中使用sleep来实现。
  2. 我已经为一些爬虫使用scrapy ,它具有非常酷的重试和速率限制功能。 使用RetryMiddleware ,它会将失败的页面排入队列并在设置中有一个RETRY_LIMIT 使用AutoThrottle ,它可以根据服务器上的负载自动限制速度。 有什么方法可以在 Spring Batch 中实现这些功能? 或者我必须用scrapy重写我的项目?

非常感谢你!

Spring Batch 不提供此类功能。 但是您可以在该步骤期间在适当的地方使用任何速率限制库(即读取数据之前/之后,处理或写入数据之前/之后等)。

这应该会有所帮助: Spring 批量写入器限制

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM