apache HttpClient の backoff について

この記事の目的

コードリーディング後の理解用メモ

対象

概要

apache http client には 動的にコネクション数を調整できる機能がある。用途としてはリクエスト先のサーバが高負荷になった場合などにコネクション数を減らして負荷を一時的に減らせるようにするような目的で使えそう。

正確な記述などはすっとばして理解の範囲で記載

f:id:nise_nabe:20170103141336p:plain

関連クラスやメンバ

  • 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() の実装でそういう順番でチェインしている 参考

参考文献

Additive increase/multiplicative decrease - Wikipedia