允许50个线程并发调用主机的Http Client

问题描述 投票:0回答:1

基于调用可以被50个线程同时访问的外部服务的需求,我在下面设计了一个简单的POC

public class ExternalServiceHelper {
    private static RequestConfig requestConfig = RequestConfig.custom()
            .setConnectTimeout(60 * 1000)
            .setConnectionRequestTimeout(60 * 1000)
            .setSocketTimeout(60 * 1000).build();

    private static CloseableHttpClient closeableHttpClient = HttpClients.custom().
        setDefaultRequestConfig(requestConfig).
        useSystemProperties().
        setMaxConnTotal(50).
        setMaxConnPerRoute(30).
        build();

    public  String sendToExternalService(HttpPost httppost) throws IOException {
        CloseableHttpResponse response =null;
        response=closeableHttpClient.execute(httppost);
        String reponse = EntityUtils.toString(response.getEntity());
        System.out.println(reponse);
        httppost.releaseConnection();
        response.close();
        closeableHttpClient.close();
        return response;
    }
}

方法 sendToExternalService 最多可以从 Rest Api 服务层调用 50 个并发线程。即

/api - 50 个用户可能同时调用 api,我需要使用 sendToExternalService 从服务层调用外部服务。我从服务层创建一个新的 ExternalServiceHelper 实例,然后使用不同的 HttpPost 请求调用 sendToExternalService。

有没有更好的方法,在这里我保持 CloseableHttpClient 静态,所以只有一个副本并从池中恢复 CloseableHttpClient,因为我使用构建器设置了 MaxConnPerRoute 和 MaxConnTotal。

这会不会有任何同步问题,例如线程 1 得到不同线程的响应?

非常感谢任何建议或优化。谢谢

java multithreading apache-httpclient-4.x
1个回答
0
投票

保持

CloseableHttpClient
静态不会确认只有一份
CloseableHttpClient
的副本以重复使用。在这里,对于
ExternalServiceHelper
的每个对象创建,您都在创建
CloseableHttpClient
。要为每个
ExternalServiceHelper
创建一个客户端,您需要使用Singleton Design Pattern

您应该使用断路器来减少对停机服务的调用。

在您当前的代码库中,不,没有这种情况可以得到对另一个请求的响应。

但是如果您将代码更改为我建议的代码,那么您将需要在

closeableHttpClient
引用上进行同步,因为单个引用将被多个线程使用。

希望,它有帮助。

© www.soinside.com 2019 - 2024. All rights reserved.