代码之家  ›  专栏  ›  技术社区  ›  dzieciou

为什么Apache HTTP客户端中重试之间没有延迟?

  •  1
  • dzieciou  · 技术社区  · 8 年前

    IOException )它可能尝试重新连接。但是,它不会等到下次重试。这似乎与直觉相反,例如,当目标服务器正在恢复或启动时,可能需要一些时间来准备新的请求。

    这是来自 DefaultRequestDirector :

    for (;;) {
        context.setAttribute(ExecutionContext.HTTP_REQUEST, wrapper);
        // Increment connect count
        connectCount++;
        try {
            if (!managedConn.isOpen()) {
                managedConn.open(route, context, params);
            } else {
                managedConn.setSocketTimeout(HttpConnectionParams.getSoTimeout(params));
            }
            establishRoute(route, context);
            break;
        } catch (final IOException ex) {
            try {
                managedConn.close();
            } catch (final IOException ignore) {
            }
            if (retryHandler.retryRequest(ex, connectCount, context)) {
                ...
            } else {
                throw ex;
            }
        }
    }
    
    1 回复  |  直到 8 年前
        1
  •  1
  •   Ioannis Sermetziadis    8 年前

    DefaultRequestDirector 确实有这种故意忽略的硬编码逻辑 IOException

    您需要覆盖 DefaultHttpRequestRetryHandler 这也忽略了 ConnectionException ,但以一种更可配置的方式,通过定义一个不可重试类的列表(不幸的是,这个构造函数受到保护,因此需要创建一个子类来公开该构造函数)。

        CustomHttpRequestRetryHandler myRetryHandler = new CustomHttpRequestRetryHandler(3, false, 
            Collections.<Class<? extends IOException>>emptyList());
        CloseableHttpClient client = HttpClients.custom()
            .setRetryHandler(myRetryHandler)
            .build();
    
        private static class CustomHttpRequestRetryHandler extends DefaultHttpRequestRetryHandler {
            public CustomHttpRequestRetryHandler(int retryCount, boolean requestSentRetryEnabled, Collection<Class<? extends IOException>> clazzes) {
                super(retryCount, requestSentRetryEnabled, clazzes);
            }
        }