私は、お客様が使用しているライブラリを持っており、オブジェクトにuserid
,timeout
などのフィールドを渡しています。ここでこのDataRequest
オブジェクトをURLに使用して、RestTemplate
を使用してHTTP呼び出しを行い、私のサービスはDataResponse
オブジェクトを作成し、このDataResponse
オブジェクトを戻すJSON応答を返します。RestTemplateを使用してリクエストごとにRequestConfigurationを設定するにはどうすればよいですか?
以下はDataRequest
オブジェクトを渡してお客様が使用しているDataClient
クラスです。 getSyncData
メソッドであまりにも多くの時間がかかる場合、私はDataRequest
の顧客が渡したタイムアウト値をタイムアウトに使用しています。
public class DataClient implements Client {
private final RestTemplate restTemplate = new RestTemplate();
private final ExecutorService service = Executors.newFixedThreadPool(10);
// this constructor will be called only once through my factory
// so initializing here
public DataClient() {
try {
restTemplate.setRequestFactory(clientHttpRequestFactory());
} catch (Exception ex) {
// log exception
}
}
@Override
public DataResponse getSyncData(DataRequest key) {
DataResponse response = null;
Future<DataResponse> responseFuture = null;
try {
responseFuture = getAsyncData(key);
response = responseFuture.get(key.getTimeout(), key.getTimeoutUnit());
} catch (TimeoutException ex) {
response = new DataResponse(DataErrorEnum.CLIENT_TIMEOUT, DataStatusEnum.ERROR);
responseFuture.cancel(true);
// logging exception here
}
return response;
}
@Override
public Future<DataResponse> getAsyncData(DataRequest key) {
DataFetcherTask task = new DataFetcherTask(key, restTemplate);
Future<DataResponse> future = service.submit(task);
return future;
}
// how to set socket timeout value by using `key.getSocketTimeout()` instead of using hard coded 400
private ClientHttpRequestFactory clientHttpRequestFactory() {
HttpComponentsClientHttpRequestFactory requestFactory =
new HttpComponentsClientHttpRequestFactory();
RequestConfig requestConfig =
RequestConfig.custom().setConnectionRequestTimeout(400).setConnectTimeout(400)
.setSocketTimeout(400).setStaleConnectionCheckEnabled(false).build();
SocketConfig socketConfig =
SocketConfig.custom().setSoKeepAlive(true).setTcpNoDelay(true).build();
PoolingHttpClientConnectionManager poolingHttpClientConnectionManager =
new PoolingHttpClientConnectionManager();
poolingHttpClientConnectionManager.setMaxTotal(300);
poolingHttpClientConnectionManager.setDefaultMaxPerRoute(200);
CloseableHttpClient httpClientBuilder =
HttpClientBuilder.create().setConnectionManager(poolingHttpClientConnectionManager)
.setDefaultRequestConfig(requestConfig).setDefaultSocketConfig(socketConfig).build();
requestFactory.setHttpClient(httpClientBuilder);
return requestFactory;
}
}
DataFetcherTask
クラス:自分のコードベースに私の工場を使用することにより、以下のように私達の会社内
public class DataFetcherTask implements Callable<DataResponse> {
private final DataRequest key;
private final RestTemplate restTemplate;
public DataFetcherTask(DataRequest key, RestTemplate restTemplate) {
this.key = key;
this.restTemplate = restTemplate;
}
@Override
public DataResponse call() throws Exception {
// In a nutshell below is what I am doing here.
// 1. Make an url using DataRequest key.
// 2. And then execute the url RestTemplate.
// 3. Make a DataResponse object and return it.
}
}
お客様がこのように私のライブラリを使用します - 私はsync call as async + waiting
を実装しています
// if they are calling `getSyncData()` method
DataResponse response = DataClientFactory.getInstance().getSyncData(key);
// and if they want to call `getAsyncData()` method
Future<DataResponse> response = DataClientFactory.getInstance().getAsyncData(key);
そうでなければ何の制御もせずに私たちのサービスを砲撃することができます。
問題文: -
私は私のDataRequest
クラスにsocket timeout
と呼ばれる別のタイムアウト変数を追加するつもりですし、私が代わりにハードコードされた400値を使用しての私のclientHttpRequestFactory()
方法でその変数値(key.getSocketTimeout())
を使用します。それを行うための最も効率的な方法は何ですか?
今私はすべての私の仕事のオブジェクトの間でRestTemplate
を共有するためにコンストラクタでInversion of Control
とRestTemplate
を渡しています。私はclientHttpRequestFactory()
メソッドでkey.getSocketTimeout()
の値を使う方法を今混同しています。これは、RestTemplate
を効率的にここで使用する方法の設計上の問題であると私のclientHttpRequestFactory()
メソッドでkey.getSocketTimeout()
の値を使用できるようにするためです。
アイデアが私がやろうとしていることが明確になるようにコードを単純化しました。私はJava 7を使用しています。ThreadLocal
は私がここにいる唯一の選択肢です。
私はここで使用できるオプションは何ですか?何かご意見は? – user1950349
@ user1950349 AFAICSあなたの他のオプションは、ThreadLocalを使うよりも悪くなるでしょう。 –
私は参照してください。私のコードがどのように 'ThreadLocal'のように見えるかの例を提供できますか?いくつかの負荷テストを行い、パフォーマンスに影響するかどうかを確認できます。私は以前ThreadLocalで作業していませんでしたが、ドキュメントを読むともっと混乱するので、私のソリューションでどのように使うことができるのかよく分かりません。 – user1950349