首页 > 解决方案 > 异步 Http 客户端 + Netty

问题描述

我在对异步 http 客户端(版本 - 2.4.3)进行基准测试时遇到问题,并在运行下面粘贴的代码时遇到以下异常。仅供参考,我是 Netty 和 async-http-client 的新手,所以请原谅我,以防我的理解有差距。

exception - io.netty.channel.ConnectTimeoutException: connection timed out:

以下是我的假设 -

以下是我的问题-

1] 虽然我使用 ThrottleRequestFilter 为什么我应该看到连接超时。我的假设是,一旦处理程序处理了响应,则连接应该可以重用,因为我设置了 keepalive,除非我缺少某些东西。

2] 执行 AsyncHandler 代码的默认线程池的大小是多少。

以下是我的测试运行

Total Requests - N = 1000
Max Con = 1000
Max Con/Host = 1000
pcit = 60000
ka = true

以下是指标 -

======================================
Total num of Reqs:  1000
Concurrency :   1000
Total Time in secs: 1.0
HTTP 200 OK:    789
HTTP 200 NOT OK:    211
Total Completed :   1000
rps : 789.0
======================================

public class HttpBm {

final Metrics metrics;
long startTime = System.nanoTime();

public HttpBm(Metrics metrics) {
    this.metrics = metrics;
}

private void run(int n, int mc, int mcph, int pcit, boolean ka, String url) {

    AsyncHttpClient asyncHttpClient = Dsl.asyncHttpClient(Dsl.config()
            .addRequestFilter(new ThrottleRequestFilter(mcph))
            .setMaxConnections(mc)
            .setMaxConnectionsPerHost(mcph)
            .setKeepAlive(ka)
            .setConnectTimeout(1000)
            .setConnectionTtl(500));

    for (int r=0;r<n;r++) {

        final ListenableFuture<Response> whenResponse = asyncHttpClient.prepareGet(url).execute(new AsyncHandler<Response>() {

            private Integer status;

            public State onStatusReceived(HttpResponseStatus responseStatus) throws Exception {
                if (200 == responseStatus.getStatusCode())
                    metrics.incrHttp200OK();
                else
                    metrics.incrHttpNon200OK();
                return State.ABORT;
            }

            public State onHeadersReceived(HttpHeaders headers) throws Exception {
                return State.ABORT;
            }

            public State onBodyPartReceived(HttpResponseBodyPart bodyPart) throws Exception {
                return State.ABORT;
            }

            public void onThrowable(Throwable t) {
                metrics.incrHttpNon200OK();
                t.printStackTrace();
            }

            public Response onCompleted() throws Exception {
                return null;
            }
        });
    }

    long endTime = System.nanoTime();
    boolean done = true;

    while (done) {

        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        done = metrics.print(startTime, endTime);
    }

}

public static void main(String[] args) {

    int n = 1000;
    int mc = 1000;
    int mcph = 1000;
    int pcit = 60000;
    String url = "http://somehost:8080/index.html";

    if (args != null) {
        n = Integer.parseInt(args[0]);
        mc = Integer.parseInt(args[1]);
        mcph = Integer.parseInt(args[2]);
        pcit = Integer.parseInt(args[3]);
        url = args[4];
    }

    System.out.println();
    System.out.println("==================================");
    System.out.println("Url = " + url);
    System.out.println("Total Requests - N = " + n);
    System.out.println("Max Con = " + mc);
    System.out.println("Max Con/Host = " + mcph);
    System.out.println("pcit = " + pcit);
    System.out.println("ka = true");

    System.out.println("==================================");

    HttpBm httpBm = new HttpBm(new Metrics(n, mc));

    httpBm.run(n , mc, mcph, pcit, true, url);
}

}

import java.util.concurrent.atomic.AtomicInteger;

public class Metrics {

private int n;
private int c;

private AtomicInteger Http200OK = new AtomicInteger();
private AtomicInteger HttpNon200OK = new AtomicInteger();

public Metrics(int n, int c) {
    this.n = n;
    this.c = c;
}

public void incrHttp200OK() {
    Http200OK.incrementAndGet();
}

public void incrHttpNon200OK() {
    HttpNon200OK.incrementAndGet();
}

public boolean isComplete() {
    return Http200OK.get() + HttpNon200OK.get() >= n;
}

public boolean print(long startTime, long finishTime) {

    final float totalTimeSec = (finishTime - startTime) / 1000000000;
    final float rps = this.Http200OK.get() / totalTimeSec;

    System.out.println("======================================");
    System.out.println("Total num of Reqs:\t" + n);
    System.out.println("Concurrency :\t" + c);
    System.out.println("Total Time in secs:\t" +  totalTimeSec);
    System.out.println("HTTP 200 OK:\t" +  Http200OK.get());
    System.out.println("HTTP 200 NOT OK:\t" + HttpNon200OK.get());
    System.out.println("Total Completed :\t" + (Http200OK.get() + HttpNon200OK.get()));
    System.out.println("rps : " + rps);
    System.out.println("======================================");

    return isComplete();
}

}

标签: javanettyasynchttpclient

解决方案


推荐阅读