java

关注公众号 jb51net

关闭
首页 > 软件编程 > java > AsyncHttpClient KeepAliveStrategy

AsyncHttpClient KeepAliveStrategy源码流程解读

作者:codecraft

这篇文章主要为大家介绍了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实现了KeepAliveStrategy接口,其keepAlive方法判根据HTTP 1.0/1.1协议的规定进行判断,需要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协议默认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时执行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从连接池中获取

小结

AsyncHttpClient的KeepAliveStrategy定义了keepAlive方法用于决定是否对该connection进行keep alive;HttpHandler的handleHttpResponse方法会通过KeepAliveStrategy的keepAlive来判断是否需要keep alive,然后写入到NettyResponseFuture中;getOpenChannel先判断NettyResponseFuture是否是reuse的,以及是否active,若是则直接返回future.channel(),否则通过pollPooledChannel从连接池中获取。

以上就是AsyncHttpClient KeepAliveStrategy源码流程解读的详细内容,更多关于AsyncHttpClient KeepAliveStrategy的资料请关注脚本之家其它相关文章!

您可能感兴趣的文章:
阅读全文