http连接池如何在泽西岛工作?

How does http connection pooling work in work in Jersey?

这是我的代码。

import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.glassfish.jersey.client.ClientConfig;
import org.glassfish.jersey.client.ClientProperties;
import org.glassfish.jersey.client.JerseyClient;
import org.glassfish.jersey.client.JerseyClientBuilder;

public class Jersey2HttpClient {

    private static class InstanceHolder {
        private static final JerseyClient INSTANCE = createClient();

        private static JerseyClient createClient() {
            ClientConfig clientConfig = new ClientConfig();
            clientConfig.property(ClientProperties.READ_TIMEOUT, 20000);
            clientConfig.property(ClientProperties.CONNECT_TIMEOUT, 20000);
            PoolingHttpClientConnectionManager connectionManager =
                new PoolingHttpClientConnectionManager();
            connectionManager.setMaxTotal(200);
            connectionManager.setDefaultMaxPerRoute(50);
            clientConfig.property(ApacheClientProperties.CONNECTION_MANAGER, connectionManager);
            clientConfig.connectorProvider(new ApacheConnectorProvider());

            JerseyClient client = JerseyClientBuilder.createClient(clientConfig);
            client.register(RequestLogger.requestLoggingFilter);
            return client;
        }
    }

    public static JerseyClient getInstance() {
        return InstanceHolder.INSTANCE;
    }
}

我有以下问题。

  1. 如果在创建 'connection pooling objects' 时,每次都会将同一个客户端返回(通过 getInstance())到调用线程?似乎同一个对象(客户端)用于连接。

  2. 执行以下代码时究竟发生了什么。

    JerseyClient 客户端 = JerseyClientBuilder.createClient(clientConfig);

换句话说,为什么创建客户端是一项昂贵的操作?我什至还没有提到 url 或请求。

抱歉我对这方面的知识薄弱。

Client 个实例是重量级的

Client instances might be an expensive operation because Client 的初始化是管理与服务器的底层通信基础结构的重量级对象。

您应该只创建少量 Client instances and reuse them when possible. The documentation 状态如下:

Clients are heavy-weight objects that manage the client-side communication infrastructure. Initialization as well as disposal of a Client instance may be a rather expensive operation. It is therefore advised to construct only a small number of Client instances in the application. Client instances must be properly closed before being disposed to avoid leaking resources.

使用 ApacheConnectorProvider

默认情况下,泽西岛的传输层由HttpURLConnection. This support is implemented in Jersey via HttpUrlConnectorProvider提供。如果需要,您可以更换默认连接器。

Jersey 通过 ApacheConnectorProvider 与 Apache HTTP 客户端集成。要使用它,请确保您具有以下依赖项:

<dependency>
    <groupId>org.glassfish.jersey.connectors</groupId>
    <artifactId>jersey-apache-connector</artifactId>
    <version>2.23.2</version>
</dependency>

在您的代码中,您已经实例化了一个 PoolingHttpClientConnectionManager 但您没有在任何地方使用它。将以下行添加到您的代码中:

clientConfig.property(ApacheClientProperties.CONNECTION_MANAGER, connectionManager);
clientConfig.connectorProvider(new ApacheConnectorProvider());

有关更多详细信息,请参阅 Jersey documentation about connectors