使用Backoff策略提高HttpClient連接管理的效率
序
本文主要研究一下HttpClient的ConnectionBackoffStrategy
ConnectionBackoffStrategy
org/apache/http/client/ConnectionBackoffStrategy.java
/** * When managing a dynamic number of connections for a given route, this * strategy assesses whether a given request execution outcome should * result in a backoff signal or not, based on either examining the * {@code Throwable} that resulted or by examining the resulting * response (e.g. for its status code). * * @since 4.2 * */ public interface ConnectionBackoffStrategy { /** * Determines whether seeing the given {@code Throwable} as * a result of request execution should result in a backoff * signal. * @param t the {@code Throwable} that happened * @return {@code true} if a backoff signal should be * given */ boolean shouldBackoff(Throwable t); /** * Determines whether receiving the given {@link HttpResponse} as * a result of request execution should result in a backoff * signal. Implementations MUST restrict themselves to examining * the response header and MUST NOT consume any of the response * body, if any. * @param resp the {@code HttpResponse} that was received * @return {@code true} if a backoff signal should be * given */ boolean shouldBackoff(HttpResponse resp); }
ConnectionBackoffStrategy定義了shouldBackoff方法,它根據(jù)異?;蛘遰esponse來進行判斷
NullBackoffStrategy
org/apache/http/impl/client/NullBackoffStrategy.java
public class NullBackoffStrategy implements ConnectionBackoffStrategy { @Override public boolean shouldBackoff(final Throwable t) { return false; } @Override public boolean shouldBackoff(final HttpResponse resp) { return false; } }
NullBackoffStrategy實現(xiàn)了ConnectionBackoffStrategy,shouldBackoff方法返回false
DefaultBackoffStrategy
org/apache/http/impl/client/DefaultBackoffStrategy.java
public class DefaultBackoffStrategy implements ConnectionBackoffStrategy { @Override public boolean shouldBackoff(final Throwable t) { return t instanceof SocketTimeoutException || t instanceof ConnectException; } @Override public boolean shouldBackoff(final HttpResponse resp) { return resp.getStatusLine().getStatusCode() == 429 || resp.getStatusLine().getStatusCode() == HttpStatus.SC_SERVICE_UNAVAILABLE; } }
DefaultBackoffStrategy在SocketTimeoutException或者ConnectException的時候返回true,或者在response code為429或者503的時候返回true
BackoffStrategyExec
org/apache/http/impl/execchain/BackoffStrategyExec.java
@Contract(threading = ThreadingBehavior.IMMUTABLE_CONDITIONAL) public class BackoffStrategyExec implements ClientExecChain { private final ClientExecChain requestExecutor; private final ConnectionBackoffStrategy connectionBackoffStrategy; private final BackoffManager backoffManager; public BackoffStrategyExec( final ClientExecChain requestExecutor, final ConnectionBackoffStrategy connectionBackoffStrategy, final BackoffManager backoffManager) { super(); Args.notNull(requestExecutor, "HTTP client request executor"); Args.notNull(connectionBackoffStrategy, "Connection backoff strategy"); Args.notNull(backoffManager, "Backoff manager"); this.requestExecutor = requestExecutor; this.connectionBackoffStrategy = connectionBackoffStrategy; this.backoffManager = backoffManager; } @Override public CloseableHttpResponse execute( final HttpRoute route, final HttpRequestWrapper request, final HttpClientContext context, final HttpExecutionAware execAware) throws IOException, HttpException { Args.notNull(route, "HTTP route"); Args.notNull(request, "HTTP request"); Args.notNull(context, "HTTP context"); CloseableHttpResponse out = null; try { out = this.requestExecutor.execute(route, request, context, execAware); } catch (final Exception ex) { if (out != null) { out.close(); } if (this.connectionBackoffStrategy.shouldBackoff(ex)) { this.backoffManager.backOff(route); } if (ex instanceof RuntimeException) { throw (RuntimeException) ex; } if (ex instanceof HttpException) { throw (HttpException) ex; } if (ex instanceof IOException) { throw (IOException) ex; } throw new UndeclaredThrowableException(ex); } if (this.connectionBackoffStrategy.shouldBackoff(out)) { this.backoffManager.backOff(route); } else { this.backoffManager.probe(route); } return out; } }
BackoffStrategyExec實現(xiàn)了ClientExecChain接口,其execute執(zhí)行requestExecutor.execute,捕獲到異常的時候通過connectionBackoffStrategy.shouldBackoff(ex)來決定是否需要backOff,是的話執(zhí)行backoffManager.backOff(route);
若沒有異常則通過connectionBackoffStrategy.shouldBackoff(out)根據(jù)response來判斷是否需要backOff,是的化執(zhí)行backoffManager.backOff(route)
小結
HttpClient的DefaultBackoffStrategy在SocketTimeoutException或者ConnectException的時候返回true,或者在response code為429或者503的時候返回true;BackoffStrategyExec則通過connectionBackoffStrategy與backoffManager來配合執(zhí)行backOff。這個backOff的目的就是動態(tài)調(diào)整每個route的connection大小(MaxPerRoute
)。
以上就是使用Backoff策略提高HttpClient連接管理的效率的詳細內(nèi)容,更多關于HttpClient Backoff連接管理的資料請關注腳本之家其它相關文章!
- 解讀httpclient的validateAfterInactivity連接池狀態(tài)檢測
- httpclient的disableConnectionState方法工作流程
- 探索HttpClient中的close方法及其對連接的影響
- HttpClient的RedirectStrategy重定向處理核心機制
- HttpClient的DnsResolver自定義DNS解析另一種選擇深入研究
- HttpClient HttpRoutePlanner接口確定請求目標路由
- 提升網(wǎng)絡請求穩(wěn)定性HttpClient的重試機制深入理解
- httpclient getPoolEntryBlocking連接池方法源碼解讀
相關文章
在Mybatis @Select注解中實現(xiàn)拼寫動態(tài)sql
這篇文章主要介紹了在Mybatis @Select注解中實現(xiàn)拼寫動態(tài)sql,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-11-11SpringCloud Feign如何在遠程調(diào)用中傳輸文件
這篇文章主要介紹了SpringCloud Feign如何在遠程調(diào)用中傳輸文件,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下2020-09-09