带有Apache连接器的Jersey客户端进行池化(性能)

时间:2019-02-11 20:42:39

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

我们有一个jersey客户端,具有基本配置:

public class HttpClient {

    private transient final WebTarget target;

    public HttpClient(final String host, final int port, final String path, final int requestTimeout) {
        final URI uri = UriBuilder.fromUri("http://" + host).port(port).build();
        final Client client = ClientBuilder.newClient();

        client.property(ClientProperties.READ_TIMEOUT, requestTimeout);
        target = client.target(uri).path(path);
    }

    public byte[] makeRequest(final byte[] request) throws HsmException {
        try {
            return target.request()
                    .accept(MediaType.APPLICATION_OCTET_STREAM)
                    .post(Entity.entity(request, MediaType.APPLICATION_OCTET_STREAM), byte[].class);
        }
        catch (Exception e) {
            // Box JAX-RS exceptions as they get weirdly handled by the outer Jersey layer.
            throw new Exception("Could not make request: " + e.getMessage(), e);
        }
    }

}

现在,有了该客户,我们每秒能够处理约900个请求。因此,为了获得更好的结果,我考虑过使用带有jersey连接器的Apache Http客户端来实现池化,如下所示:

public class HttpClient {
    private transient final WebTarget target;

    public HttpClient(final String host, final int port, final String path, final int requestTimeout) {
        final ClientConfig clientConfig = new ClientConfig();
        clientConfig.property(ClientProperties.READ_TIMEOUT, requestTimeout);
        clientConfig.property(ClientProperties.CONNECT_TIMEOUT, 500);

        final PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager();
        connectionManager.setMaxTotal(150);
        connectionManager.setDefaultMaxPerRoute(40);
        connectionManager.setMaxPerRoute(new HttpRoute(new HttpHost(host)), 80);

        clientConfig.property(ApacheClientProperties.CONNECTION_MANAGER, connectionManager);

        final ApacheConnectorProvider connector = new ApacheConnectorProvider();
        clientConfig.connectorProvider(connector);

        final URI uri = UriBuilder.fromUri("http://" + host).port(port).build();
        final Client client = ClientBuilder.newClient(clientConfig);
        target = client.target(uri).path(path);
    }

    @Override
    public byte[] makeRequest(final byte[] request) throws HsmException {
        try {
            return target.request()
                    .accept(MediaType.APPLICATION_OCTET_STREAM)
                    .post(Entity.entity(command, MediaType.APPLICATION_OCTET_STREAM), byte[].class);
        }
        catch (Exception e) {
            // Box JAX-RS exceptions as they get weirdly handled by the outer Jersey layer.
            throw new Exception("Could not make request:" + e.getMessage(), e);
        }
    }
}

结果完全相同,每秒大约有900个请求。

我不受CPU,内存,磁盘等的限制。我找不到瓶颈。设置连接管理器时,我测试了多个值,但结果完全相同。

我想念什么吗?我还有其他参数吗?我使用的是错误方法吗?

1 个答案:

答案 0 :(得分:0)

您可以尝试使用httpasyncclient进行HTTP连接池。

httpclient将线程阻塞I / O用于连接池,这意味着负责发送HTTP请求的线程也负责处理HTTP响应。同时,线程仍然在套接字上处于阻塞状态。

相比之下,httpasyncclient是基于Java NIO(非阻塞)I / O模型的完全异步HTTP客户端处理程序,允许库用户从非阻塞HTTP连接流式传输消息内容。