【问题标题】:java httpclient 4.x performance guide to resolve issue解决问题的 java httpclient 4.x 性能指南
【发布时间】:2015-05-31 20:39:56
【问题描述】:

有一篇很好的文章http://hc.apache.org/httpclient-3.x/performance.html 与 http 性能、池等相关。 找不到最新的 4.x 版本。有人看到了吗?我在繁重的负载下遇到了性能问题,并希望解决它们。 我正在使用 4.1 版本。 这是探查器的输出:

26% org.apache.http.impl.client.CloseableHttpClient.execute(multiple parameter matches) :26,107,40
26% org.apache.http.impl.client.CloseableHttpClient.execute(org.apache.http.client.methods.HttpUriRequest, org.apache.http.protocol.HttpContext) :82,46
26% org.apache.http.impl.client.AbstractHttpClient.doExecute(org.apache.http.HttpHost, org.apache.http.HttpRequest, org.apache.http.protocol.HttpContext) :882,818
26% org.apache.http.impl.client.AbstractHttpClient.createHttpContext() :301
26% org.apache.http.impl.client.AbstractHttpClient.getConnectionManager() :484
26% org.apache.http.impl.client.AbstractHttpClient.createClientConnectionManager() :321
26% org.apache.http.impl.conn.SchemeRegistryFactory.createDefault() :52
26% org.apache.http.conn.ssl.SSLSocketFactory.getSocketFactory() :168
26% org.apache.http.conn.ssl.SSLContexts.createDefault() :58
26% javax.net.ssl.SSLContext.init(javax.net.ssl.KeyManager[], javax.net.ssl.TrustManager[], java.security.SecureRandom) :283
26% sun.security.ssl.SSLContextImpl.engineInit(javax.net.ssl.KeyManager[], javax.net.ssl.TrustManager[], java.security.SecureRandom) :83,92
26% javax.net.ssl.TrustManagerFactory.init(java.security.KeyStore) :250
26% sun.security.ssl.TrustManagerFactoryImpl.engineInit(java.security.KeyStore) :51
26% sun.security.ssl.TrustManagerFactoryImpl.getCacertsKeyStore(java.lang.String) :221
26% java.security.KeyStore.load(java.io.InputStream, char[]) :1214
26% sun.security.provider.JavaKeyStore$JKS.engineLoad(java.io.InputStream, char[]) :55
26% sun.security.provider.JavaKeyStore.engineLoad(java.io.InputStream, char[]) :723,747
26% java.security.cert.CertificateFactory.generateCertificate(java.io.InputStream) :339
26% sun.security.provider.X509Factory.engineGenerateCertificate(java.io.InputStream) :93
26% sun.security.provider.X509Factory.getFromCache(sun.security.util.Cache, byte[]) :203

我有 4 种方法使用 httpclient 通过 HTTP 发送一些数据,每种方法都消耗 25% 的总时间。其余处理需要毫秒。看来我使用 httpclient 的方式有误。

编辑: 查看 oleg 答案 + 阅读 https://hc.apache.org/httpcomponents-client-ga/tutorial/html/connmgmt.html 回答所有相关问题

主要部分有: 构建池管理器的好方法

PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager();
// Increase max total connection to 200
cm.setMaxTotal(200);
// Increase default max connection per route to 20
cm.setDefaultMaxPerRoute(20);
// Increase max connections for localhost:80 to 50
HttpHost localhost = new HttpHost("locahost", 80);
cm.setMaxPerRoute(new HttpRoute(localhost), 50);

CloseableHttpClient httpClient = HttpClients.custom()
        .setConnectionManager(cm)
        .build();

一种同时使用HttpClient的方法

//While HttpClient instances are thread safe and can be shared
//between multiple threads of execution, it is highly recommended that 
//each thread maintains its own dedicated instance of HttpContext .


static class GetThread extends Thread {

    private final CloseableHttpClient httpClient;
    private final HttpContext context;
    private final HttpGet httpget;

    public GetThread(CloseableHttpClient httpClient, HttpGet httpget) {
        this.httpClient = httpClient;
        this.context = HttpClientContext.create();
        this.httpget = httpget;
    }

    @Override
    public void run() {
        try {
            CloseableHttpResponse response = httpClient.execute(
                    httpget, context);
            try {
                HttpEntity entity = response.getEntity();
            } finally {
                response.close();
            }
        } catch (ClientProtocolException ex) {
            // Handle protocol errors
        } catch (IOException ex) {
            // Handle I/O errors
        }
    }

}

【问题讨论】:

    标签: java performance apache-httpclient-4.x


    【解决方案1】:

    主要建议仍然与 3.1 相同

    请务必重复使用 HttpClient 实例! HttpClient 实例非常昂贵。通过丢弃它,不仅丢弃了实例本身,还丢弃了 SSL 上下文、连接管理器以及所有可能由连接管理器保持活动的持久连接。

    【讨论】:

    • 谢谢,听起来很简单。我有点困惑。我必须只关闭响应对象吗?够了吗?
    • 当不再需要 HttpClient 实例时应该关闭它。在使用实例时,应关闭响应对象以确保将连接正确释放回池
    • 有没有连接池的例子?或者这个池是隐式完成的?那么并发呢?跨线程共享单个 HttpClient 实例是否节省?
    • 所以我可以在 HttpSevlet.init 方法中实例化单个 HttpClient 实例,然后同时使用它?
    • 我发现在每次调用时释放连接可以防止连接泄漏。 httpget.releaseConnection() ..
    猜你喜欢
    • 2013-09-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-25
    • 2022-10-01
    • 2020-01-16
    相关资源
    最近更新 更多