AsyncHttpClient KeepAliveStrategy源碼流程解讀
序
本文主要研究一下AsyncHttpClient的KeepAliveStrategy
KeepAliveStrategy
org/asynchttpclient/channel/KeepAliveStrategy.java
public interface KeepAliveStrategy { /** * Determines whether the connection should be kept alive after this HTTP message exchange. * * @param ahcRequest the Request, as built by AHC * @param nettyRequest the HTTP request sent to Netty * @param nettyResponse the HTTP response received from Netty * @return true if the connection should be kept alive, false if it should be closed. */ boolean keepAlive(Request ahcRequest, HttpRequest nettyRequest, HttpResponse nettyResponse); }
KeepAliveStrategy接口定義了keepAlive方法用于決定是否對(duì)該connection進(jìn)行keep alive
DefaultKeepAliveStrategy
org/asynchttpclient/channel/DefaultKeepAliveStrategy.java
/** * Connection strategy implementing standard HTTP 1.0/1.1 behavior. */ public class DefaultKeepAliveStrategy implements KeepAliveStrategy { /** * Implemented in accordance with RFC 7230 section 6.1 https://tools.ietf.org/html/rfc7230#section-6.1 */ @Override public boolean keepAlive(Request ahcRequest, HttpRequest request, HttpResponse response) { return HttpUtil.isKeepAlive(response) && HttpUtil.isKeepAlive(request) // support non standard Proxy-Connection && !response.headers().contains("Proxy-Connection", CLOSE, true); } }
DefaultKeepAliveStrategy實(shí)現(xiàn)了KeepAliveStrategy接口,其keepAlive方法判根據(jù)HTTP 1.0/1.1協(xié)議的規(guī)定進(jìn)行判斷,需要request、response都是keep alive,且response header不包含Proxy-Connection: close才返回true
HttpUtil
io/netty/handler/codec/http/HttpUtil.java
/** * Returns {@code true} if and only if the connection can remain open and * thus 'kept alive'. This methods respects the value of the. * * {@code "Connection"} header first and then the return value of * {@link HttpVersion#isKeepAliveDefault()}. */ public static boolean isKeepAlive(HttpMessage message) { return !message.headers().containsValue(HttpHeaderNames.CONNECTION, HttpHeaderValues.CLOSE, true) && (message.protocolVersion().isKeepAliveDefault() || message.headers().containsValue(HttpHeaderNames.CONNECTION, HttpHeaderValues.KEEP_ALIVE, true)); }
isKeepAlive方法在HttpMessage沒(méi)有connection: close的header,且http協(xié)議默認(rèn)keep alive或者h(yuǎn)eader包含了connection: keep-alive才返回true
handleHttpResponse
org/asynchttpclient/netty/handler/HttpHandler.java
private void handleHttpResponse(final HttpResponse response, final Channel channel, final NettyResponseFuture<?> future, AsyncHandler<?> handler) throws Exception { HttpRequest httpRequest = future.getNettyRequest().getHttpRequest(); logger.debug("\n\nRequest {}\n\nResponse {}\n", httpRequest, response); future.setKeepAlive(config.getKeepAliveStrategy().keepAlive(future.getTargetRequest(), httpRequest, response)); NettyResponseStatus status = new NettyResponseStatus(future.getUri(), response, channel); HttpHeaders responseHeaders = response.headers(); if (!interceptors.exitAfterIntercept(channel, future, handler, response, status, responseHeaders)) { boolean abort = abortAfterHandlingStatus(handler, status) || // abortAfterHandlingHeaders(handler, responseHeaders) || // abortAfterHandlingReactiveStreams(channel, future, handler); if (abort) { finishUpdate(future, channel, true); } } }
HttpHandler的handleHttpResponse方法會(huì)通過(guò)KeepAliveStrategy的keepAlive來(lái)判斷是否需要keep alive,然后寫(xiě)入到NettyResponseFuture中
exitAfterHandlingConnect
org/asynchttpclient/netty/handler/intercept/ConnectSuccessInterceptor.java
public boolean exitAfterHandlingConnect(Channel channel, NettyResponseFuture<?> future, Request request, ProxyServer proxyServer) { if (future.isKeepAlive()) future.attachChannel(channel, true); Uri requestUri = request.getUri(); LOGGER.debug("Connecting to proxy {} for scheme {}", proxyServer, requestUri.getScheme()); channelManager.updatePipelineForHttpTunneling(channel.pipeline(), requestUri); future.setReuseChannel(true); future.setConnectAllowed(false); requestSender.drainChannelAndExecuteNextRequest(channel, future, new RequestBuilder(future.getTargetRequest()).build()); return true; }
exitAfterHandlingConnect方法在NettyResponseFuture的keep alive為true時(shí)執(zhí)行future.attachChannel(channel, true)
attachChannel
org/asynchttpclient/netty/NettyResponseFuture.java
public void attachChannel(Channel channel, boolean reuseChannel) { // future could have been cancelled first if (isDone()) { Channels.silentlyCloseChannel(channel); } this.channel = channel; this.reuseChannel = reuseChannel; } public boolean isReuseChannel() { return reuseChannel; }
attachChannel這里維護(hù)了reuseChannel屬性
getOpenChannel
org/asynchttpclient/netty/request/NettyRequestSender.java
private Channel getOpenChannel(NettyResponseFuture<?> future, Request request, ProxyServer proxyServer, AsyncHandler<?> asyncHandler) { if (future != null && future.isReuseChannel() && Channels.isChannelActive(future.channel())) { return future.channel(); } else { return pollPooledChannel(request, proxyServer, asyncHandler); } } private Channel pollPooledChannel(Request request, ProxyServer proxy, AsyncHandler<?> asyncHandler) { try { asyncHandler.onConnectionPoolAttempt(); } catch (Exception e) { LOGGER.error("onConnectionPoolAttempt crashed", e); } Uri uri = request.getUri(); String virtualHost = request.getVirtualHost(); final Channel channel = channelManager.poll(uri, virtualHost, proxy, request.getChannelPoolPartitioning()); if (channel != null) { LOGGER.debug("Using pooled Channel '{}' for '{}' to '{}'", channel, request.getMethod(), uri); } return channel; }
getOpenChannel先判斷NettyResponseFuture是否是reuse的,以及是否active,若是則直接返回future.channel(),否則通過(guò)pollPooledChannel從連接池中獲取
小結(jié)
AsyncHttpClient的KeepAliveStrategy定義了keepAlive方法用于決定是否對(duì)該connection進(jìn)行keep alive;HttpHandler的handleHttpResponse方法會(huì)通過(guò)KeepAliveStrategy的keepAlive來(lái)判斷是否需要keep alive,然后寫(xiě)入到NettyResponseFuture中;getOpenChannel先判斷NettyResponseFuture是否是reuse的,以及是否active,若是則直接返回future.channel(),否則通過(guò)pollPooledChannel從連接池中獲取。
以上就是AsyncHttpClient KeepAliveStrategy源碼流程解讀的詳細(xì)內(nèi)容,更多關(guān)于AsyncHttpClient KeepAliveStrategy的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
- AsyncHttpClient的TimeoutTimerTask連接池異步超時(shí)
- AsyncHttpClient?RequestFilter請(qǐng)求篩選源碼解讀
- AsyncHttpClient IOExceptionFilter異常過(guò)濾器
- AsyncHttpClient exception異常源碼流程解析
- AsyncHttpClient?ChannelPool線程池頻道池源碼流程解析
- AsyncHttpClient的ConnectionSemaphore方法源碼流程解讀
- AsyncHttpClient的默認(rèn)配置源碼流程解讀
- AsyncHttpClient?ClientStats源碼流程解讀
相關(guān)文章
Java獲取視頻時(shí)長(zhǎng)及截取幀截圖詳解
這篇文章主要介紹了Java獲取視頻時(shí)長(zhǎng)及截取幀截圖詳解,以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。,需要的朋友可以參考下2019-06-06mybatis項(xiàng)目兼容mybatis-plus問(wèn)題
這篇文章主要介紹了mybatis項(xiàng)目兼容mybatis-plus問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-02-02關(guān)于spring中事務(wù)的傳播機(jī)制
這篇文章主要介紹了關(guān)于spring中事務(wù)的傳播機(jī)制,所謂事務(wù)傳播機(jī)制,也就是在事務(wù)在多個(gè)方法的調(diào)用中是如何傳遞的,是重新創(chuàng)建事務(wù)還是使用父方法的事務(wù),需要的朋友可以參考下2023-05-05Java實(shí)現(xiàn)簡(jiǎn)單訂餐系統(tǒng)
這篇文章主要為大家詳細(xì)介紹了Java實(shí)現(xiàn)簡(jiǎn)單訂餐系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-01-01SpringBoot項(xiàng)目中分頁(yè)插件PageHelper無(wú)效的問(wèn)題及解決方法
這篇文章主要介紹了解決SpringBoot項(xiàng)目中分頁(yè)插件PageHelper無(wú)效的問(wèn)題,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-06-06Java后端學(xué)習(xí)精華之TCP通信傳輸協(xié)議詳解
TCP/IP是一種面向連接的、可靠的、基于字節(jié)流的傳輸層通信協(xié)議,它會(huì)保證數(shù)據(jù)不丟包、不亂序。TCP全名是Transmission Control Protocol,它是位于網(wǎng)絡(luò)OSI模型中的第四層2021-09-09