以下に示すように、複数のスレッドによって呼び出されるコードで Callable を使用しています。今のところ、何かRestClientException
がスローされるたびhostname
に、blockList に追加しています。
public class Task implements Callable<DataResponse> {
private DataKey key;
private RestTemplate restTemplate;
public Task(DataKey key, RestTemplate restTemplate) {
this.key = key;
this.restTemplate = restTemplate;
}
@Override
public DataResponse call() {
ResponseEntity<String> response = null;
// construct what are the hostnames I can call basis on user id
List<String> hostnames = some_code_here;
for (String hostname : hostnames) {
// If host name is null or host name is in block list, skip sending request to this host
if (DataUtils.isEmpty(hostname) || DataMapping.isBlocked(hostname)) {
continue;
}
try {
String url = createURL(hostname);
response = restTemplate.exchange(url, HttpMethod.GET, key.getEntity(), String.class);
// some code here to return the response if successful
} catch (HttpClientErrorException ex) {
// log exception
return new DataResponse(errorMessage, error, DataStatusEnum.ERROR);
} catch (HttpServerErrorException ex) {
// log exception
return new DataResponse(errorMessage, error, DataStatusEnum.ERROR);
} catch (RestClientException ex) {
// I don't want to add it to block list instantly.
// If same hostname as failed five times consecutively, then only add it
DataMapping.blockHost(hostname);
}
}
return new DataResponse(DataErrorEnum.SERVER_UNAVAILABLE, DataStatusEnum.ERROR);
}
}
以下は私がDataMapping
クラスで持っているものです:
private static final AtomicReference<ConcurrentHashMap<String, String>> blockedHosts =
new AtomicReference<ConcurrentHashMap<String, String>>(new ConcurrentHashMap<String, String>());
public static boolean isBlocked(String hostName) {
return blockedHosts.get().containsKey(hostName);
}
public static void blockHost(String hostName) {
blockedHosts.get().put(hostName, hostName);
}
問題文:-
メソッドでわかるように、スローされるとすぐcall
にブロックしていますが、これは正しくない可能性があります。特定のものが5 回連続してスローされたかどうかを確認する必要があります。次に、この行を呼び出してこれを blockList に追加するだけです。それ以外の場合は、blockList に追加しないでください。hostname
RestClientException
hostname
RestClientException
hostname
DataMapping.blockHost(hostname);
これを行うための最も効率的で最良の方法は何ですか? 最大で、合計で 70 ~ 100 台の固有のマシンを用意します。
hostname
この場合、call メソッドは複数のスレッドから呼び出されるため、それぞれが をスローした場合に備えて、それぞれのカウントを適切に維持する必要がありますRestClientException
。
編集:
DataMapping
クラスにも以下のメソッドがあります。
ホスト名が実際にブロックされているかどうかに関係なく、サービスが実際のデータを提供するため、セット全体を置き換える 2 分ごとに実行されるバックグラウンド スレッドがあります。atomic reference
そして、セット全体を交換するときは、 for が必要だと思います。
2分後にどのマシンがブロックされているかを知る必要があるため、コードにブロック機能をローカルに追加しています。
// this is being updated from my background thread which runs every 2 minutes
public static void replaceBlockedHosts(List<String> hostNames) {
ConcurrentHashMap<String, String> newBlockedHosts = new ConcurrentHashMap<>();
for (String hostName : hostNames) {
newBlockedHosts.put(hostName, hostName);
}
blockedHosts.set(newBlockedHosts);
}