発生した問題
HTTP通信処理で、レスポンスステータスが503の場合、意図せずリトライされる。
通信にはRestClient + Apache HttpClient 5を使用しており、リトライ設定は特にしていなかった。
また、リトライはIstioで制御していたため想定外のリトライが発生していた。
原因
Apache HttpClient 5の仕様でレスポンスステータスが503、429の場合デフォルトでリトライされるようになっていた
リトライのデフォルト設定をしている箇所
DefaultHttpRequestRetryStrategy.java
public DefaultHttpRequestRetryStrategy() {
this(1, TimeValue.ofSeconds(1L)); // リトライ回数1回を設定
}
public DefaultHttpRequestRetryStrategy(
final int maxRetries,
final TimeValue defaultRetryInterval) {
this(maxRetries, defaultRetryInterval,
Arrays.asList( // リトライ対象外のException
InterruptedIOException.class,
UnknownHostException.class,
ConnectException.class,
ConnectionClosedException.class,
NoRouteToHostException.class,
SSLException.class),
Arrays.asList( // リトライ対象のHttpStatus
HttpStatus.SC_TOO_MANY_REQUESTS,
HttpStatus.SC_SERVICE_UNAVAILABLE));
}
リトライ判定している箇所
DefaultHttpRequestRetryStrategy.java
public boolean retryRequest(
final HttpResponse response,
final int execCount,
final HttpContext context) {
Args.notNull(response, "response");
// HttpStatusが503, 429で現在の実行回数がリトライ上限を超えていなければリトライ
return execCount <= this.maxRetries && retriableCodes.contains(response.getCode());
}
対応
HttpClientBuilderでbuildする際に、automaticRetriesDisabledを設定することでリトライを無効にできました。