apache HttpClient の backoff について
この記事の目的
コードリーディング後の理解用メモ
対象
概要
apache http client には 動的にコネクション数を調整できる機能がある。用途としてはリクエスト先のサーバが高負荷になった場合などにコネクション数を減らして負荷を一時的に減らせるようにするような目的で使えそう。
正確な記述などはすっとばして理解の範囲で記載
関連クラスやメンバ
- org.apache.http.impl.client.HttpClientBuilder
- backoffManager
- connectionBackoffStrategy
- org.apache.http.impl.execchain.BackoffStrategyExec
- org.apache.http.client.ConnectionBackoffStrategy
- org.apache.http.client.BackoffManager
- org.apache.http.impl.client.AIMDBackoffManager
- org.apache.http.impl.client.DefaultBackoffStrategy
簡単な使い方
もっとも簡単なコード
PoolingHttpClientConnectionManager manager = new PoolingHttpClientConnectionManager(); CloseableHttpClient client = HttpClientBuilder.create() .setBackoffManager(new AIMDBackoffManager(manager)) .setConnectionBackoffStrategy(new DefaultBackoffStrategy()) .build()
コネクション数制御。 HttpClientBuilder で設定したコネクション数設定は初期値として使われる。もちろん BackoffManager で調整されていくので運用中の数字とはことなる場合がある。
PoolingHttpClientConnectionManager manager = new PoolingHttpClientConnectionManager(); AIMDBackoffManager backoffManager = new AIMDBackoffManager(manager); backoffManager.setPerHostConnectionCap(10); CloseableHttpClient client = HttpClientBuilder.create() .setBackoffManager(backoffManager) .setConnectionBackoffStrategy(new DefaultBackoffStrategy()) .build();
メモ
- HttpClientBuilder で BackoffStrategyExec を作る
- BackoffStrategyExec が ConnectionBackoffStrategy や BackoffManager を利用する
- コネクション数の増え方や減らし方は BackoffManager で実装する
- Backoff する条件は ConnectionBackoffStrategy で実装する
- Exec は Strategy の shouldBackoff() を見てどうするかきめる
- true -> Manager の backoff() を実行
- false -> Manager の probe() を実行
HttpClient 内の実装について
AIMDBackoffManager について
- AIMD = Additional increase, multiplicative decrease (加算増加乗算減少)
- デフォルトでは最大2コネクション
- 初期設定でプールの方の設定を大きくしていても次の更新でこの数字になる
- 正確にはホストごとの最大コネクション数
- 増加や減少を抑える時間(クールダウン)はデフォルト 5 秒
- 最後の増加と減少から 5 秒ごとにプールの最大接続数が 1 ふえる
- 最後の減少から 5 秒ごとにプールの最大接続数が半分になる
- BackoffStrategyExec が shouldBackoff() の true/false で呼び出し変えてるだけなので最大で消費してなくても最大値は増えてく
DefaultBackoffStrategy について
- SocketTimeoutException や ConnectException のような例外が発生した場合に backoff すべきと返す
- http status が 503 の場合に backoff すべきと返す
- 注意としては ServiceUnavailableRetryExec などを利用したときに backoff せずにリトライが優先される場合がある
- HttpClientBuilder#build() の実装でそういう順番でチェインしている 参考
- 注意としては ServiceUnavailableRetryExec などを利用したときに backoff せずにリトライが優先される場合がある