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方法用于決定是否對該connection進行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實現(xiàn)了KeepAliveStrategy接口,其keepAlive方法判根據(jù)HTTP 1.0/1.1協(xié)議的規(guī)定進行判斷,需要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沒有connection: close的header,且http協(xié)議默認keep alive或者header包含了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方法會通過KeepAliveStrategy的keepAlive來判斷是否需要keep alive,然后寫入到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時執(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這里維護了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(),否則通過pollPooledChannel從連接池中獲取
小結(jié)
AsyncHttpClient的KeepAliveStrategy定義了keepAlive方法用于決定是否對該connection進行keep alive;HttpHandler的handleHttpResponse方法會通過KeepAliveStrategy的keepAlive來判斷是否需要keep alive,然后寫入到NettyResponseFuture中;getOpenChannel先判斷NettyResponseFuture是否是reuse的,以及是否active,若是則直接返回future.channel(),否則通過pollPooledChannel從連接池中獲取。
以上就是AsyncHttpClient KeepAliveStrategy源碼流程解讀的詳細內(nèi)容,更多關(guān)于AsyncHttpClient KeepAliveStrategy的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
SpringBoot項目中分頁插件PageHelper無效的問題及解決方法
這篇文章主要介紹了解決SpringBoot項目中分頁插件PageHelper無效的問題,本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-06-06

