【问题标题】:How to decide optimal settings for setMaxTotal and setDefaultMaxPerRoute?如何确定 setMaxTotal 和 setDefaultMaxPerRoute 的最佳设置?
【发布时间】:2015-06-22 20:54:39
【问题描述】:

我有一个 RestService 在三个数据中心的 45 台不同的机器上运行(每个数据中心 15 台)。我有一个客户端库,它使用RestTemplate 来调用这些机器,具体取决于调用的来源。如果调用来自 DC1,那么我的图书馆将调用我在 DC1 中运行的休息服务,其他服务也类似。

我的客户端库在三个数据中心的不同机器上运行(不是在相同的 45 台机器上)。

我正在使用RestTemplateHttpComponentsClientHttpRequestFactory,如下所示:

public class DataProcess {

    private RestTemplate restTemplate = new RestTemplate();
    private ExecutorService service = Executors.newFixedThreadPool(15);

    // singleton class so only one instance
    public DataProcess() {
        restTemplate.setRequestFactory(clientHttpRequestFactory());
    }

    public DataResponse getData(DataKey key) {
        // do some stuff here which will internally call our RestService
        // by using DataKey object and using RestTemplate which I am making below
    }   

    private ClientHttpRequestFactory clientHttpRequestFactory() {
        HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory();
        RequestConfig requestConfig = RequestConfig.custom().setConnectionRequestTimeout(1000).setConnectTimeout(1000)
                .setSocketTimeout(1000).setStaleConnectionCheckEnabled(false).build();
        SocketConfig socketConfig = SocketConfig.custom().setSoKeepAlive(true).setTcpNoDelay(true).build();

        PoolingHttpClientConnectionManager poolingHttpClientConnectionManager = new PoolingHttpClientConnectionManager();
        poolingHttpClientConnectionManager.setMaxTotal(800);
        poolingHttpClientConnectionManager.setDefaultMaxPerRoute(700);

        CloseableHttpClient httpClientBuilder = HttpClientBuilder.create()
                .setConnectionManager(poolingHttpClientConnectionManager).setDefaultRequestConfig(requestConfig)
                .setDefaultSocketConfig(socketConfig).build();

        requestFactory.setHttpClient(httpClientBuilder);
        return requestFactory;
    }

}

这是人们通过传递dataKey 对象调用我们的库的方式:

DataResponse response = DataClientFactory.getInstance().getData(dataKey);

现在我的问题是:

如何决定我应该为PoolingHttpClientConnectionManager 对象中的setMaxTotalsetDefaultMaxPerRoute 选择什么?截至目前,我将使用 800 setMaxTotal 和 700 setDefaultMaxPerRoute?这是一个合理的数字还是我应该选择别的?

我的客户端库将在多线程项目的负载非常重的情况下使用。

【问题讨论】:

  • 这 45 台机器上是否运行相同的 RestService 应用程序?
  • 是的,RestService 正在这 45 台机器上运行。但是客户端库将在一些不同的机器上运行,然后该库将在每个数据中心调用这些 RestService 机器。假设如果呼叫来自 DC1,那么客户端库将调用 DC1 中的 RestService 机器。
  • 你能明确解释一下if call is coming from DC1, then client library will call RestService machine in DC1 是如何发生的吗?我看不到 PoolingHttpClientConnectionManager 将如何处理所有这 45 台机器之间的负载平衡。
  • PoolingHttpClientConnectionManager 没有处理那部分。给定 DataKey 对象中的 UserId,如果呼叫来自 DC1 或 DC2 或 DC3,我的库将找出在同一数据中心调用哪台机器的这些详细信息。我正在使用 PoolingHttpClientConnectionManager 以获得更好的性能。
  • 啊,谢谢你的澄清:)

标签: java spring connection-pooling apache-httpclient-4.x resttemplate


【解决方案1】:

没有适用于所有场景的公式或配方。通常,对于阻塞 i/o,每个路由设置的最大值应该与争用连接的工作线程数大致相同。

因此,拥有 15 个工作线程和 700 个连接限制对我来说毫无意义。

【讨论】:

  • 感谢您的帮助。您能否添加一些解释,为什么我不应该有 700 个连接限制?这将有助于我更好地理解。那么我应该为这两个属性使用什么设置?
  • 你有多少个工作线程? 15. 在最佳情况下,这些工作人员可以同时使用多少个连接?对。 15 岁以上
  • 好的,你认为我们甚至需要PoolingHttpClientConnectionManager RestTemplate 吗?可能我们需要我拥有的其他东西,但我猜可能不是PoolingHttpClientConnectionManager
  • 当然可以。通常应该重用连接
  • 好的,知道了。最后一件事我应该在SocketConfig 上明确设置setSoKeepAlive(true)setExpectContinueEnabled(true)RequestConfig 上吗?
【解决方案2】:

显然,这种情况没有一个明确且有价值的公式。池大小与吞吐量和响应时间之间的关系不够简单。想到的一个特殊情况是,在某个值之后,响应时间开始随着池大小的增加而增加。

通常,对于阻塞 i/o,每个路由设置的最大值应与争用连接的工作线程数大致相同。

【讨论】:

    【解决方案3】:

    让我们试着想出一个计算池大小的公式。

    R: average response time of a http call in millisecond
    Q: required throughput in requests per second
    

    为了实现 Q,您将需要大约 t = Q*R/1000 个线程来处理您的请求。为了使所有这些线程不竞争 http 连接,您应该在任何时间点在池中至少有 t 个连接。

    示例: 我有一个 Web 服务器,它获取结果并将其作为响应返回。

    Q = 700 rps
    X = 50 ms
    t = 35
    

    因此,每个 http 路由至少需要 35 个连接,而您的总连接数将是 35 * 否。路线 (3)。

    PS:这是一个非常简单的公式,但是(池大小与吞吐量和响应时间之间的关系)并不简单。想到的一个特殊情况是,在某个值之后,响应时间开始随着池大小的增加而增加。

    【讨论】:

    • 为什么是-1?一些解释会很棒
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-02-19
    • 2016-12-31
    • 2019-02-24
    • 2020-09-27
    • 1970-01-01
    • 2011-09-12
    • 1970-01-01
    相关资源
    最近更新 更多