我有一个RestService在三个数据中心的45台不同的机器上运行(每个数据中心有15台)。我有一个客户端库,使用RestTemplate
来调用这些机器,具体取决于调用的来源。如果呼叫来自DC1,那么我的图书馆将在DC1中呼叫我的休息服务,对其他人也是如此。
我的客户端库在三个数据中心的不同计算机上运行(不在同一台45台计算机上)。
我正在使用RestTemplate
HttpComponentsClientHttpRequestFactory
,如下所示:
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);
现在我的问题是:
如何决定我应该在setMaxTotal
对象中为setDefaultMaxPerRoute
和PoolingHttpClientConnectionManager
选择什么?截至目前,我的setMaxTotal
和700 setDefaultMaxPerRoute
为800?这是一个合理的数字还是我应该用别的东西?
我的客户端库将在多线程项目中使用非常繁重的负载。
答案 0 :(得分:6)
没有可以应用于所有方案的公式或配方。通常使用阻塞i / o,每个路由设置的最大值应与争用连接的工作线程数大致相同。
因此,拥有15个工作线程和700个连接限制对我来说没什么意义。
答案 1 :(得分:2)
显然,对于这种情况,没有明确而有价值的公式。池化和吞吐量与响应时间之间的关系不够简单。我想到的一个特殊情况是,在某个值之后,响应时间会随着池大小的增加而开始增加。
通常使用阻塞i / o,每个路由设置的最大值应与争用连接的工作线程数大致相同。
答案 2 :(得分:0)
让我们尝试提出一个计算池大小的公式。
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:这是一个非常简单的公式,但是池化和吞吐量与响应时间之间的关系并不简单。我想到的一个特殊情况是,在某个值之后,响应时间会随着池大小的增加而开始增加。