その手の平は尻もつかめるさ

ギジュツ的な事をメーンで書く予定です

相手のサーバにHTTP(S)で接続できるかどうかを確認するときにリトライしながらやりたいんですけどって時

例えばCIでテストのためのストレージのコンテナを上げる際,そのストレージが上がりきるまで待たなければテストには使えないわけですが「上がりきるまで何秒待てばよいのか」というのは一概に決められるものではありません.
そうした際,実際にストレージに対してHTTP(S)のリクエストを投げてみて,繋がったら「上がりきった」とみなして処理を次に進めるというようなことがよく書かれます.そういった要件を満たす為には接続に失敗したらリトライをしつつ一定回数試行するという処理を書かなくてはなりません.
つまりはそういう話です.

wgetの場合

  • retry-connrefused
  • tries
  • waitretry

を利用すると出来る.
retry-connrefused が無いと connection refusedに対応できずにリトライが不可能となるので,今回のような要件を満足するためには付ける必要があります.

e.g.

$ wget --tries 10 --waitretry 10 --retry-connrefused localhost:5000

この例だと

  • 最大10回リトライ
  • 1回失敗するごとに1秒ずつリトライ間隔が伸びていきながらリトライ (つまりn回失敗したあとのwaitはn秒)

というような動きをします. tries には最大リトライ回数を指定します.
waitretry は失敗するごとに1秒ずつリトライ間隔を伸ばしてゆく際の上限値となります (例えば,値が1だと常に1秒間隔をあけるようになる.0だと一切待たない).
場合によっては timeout を設定する必要があるでしょう.

なおこのコマンドはTravis CIのドキュメントにも書かれている由緒正しいコマンドから拝借しました.

curlの場合

  • retry-connrefused
  • retry
  • retry-delay
  • retry-max-time

を利用するとできる.
retry-connrefused が必要な理由はwgetのそれと同様です.なお,retry-connrefused2016-12-21にリリースされたバージョン7.52.0から入ったわりと新しい機能なので古いcurlだと使えません.新しいものにアップデートしましょう.

e.g.

$ curl --retry 10 --retry-delay 1 --retry-connrefused localhost:5000

この例では最大10回リトライしつつ (retry で指定),リトライ間隔は常に1秒 (retry-delay で指定) というふうになります.

retry 単体で利用すると失敗する度にretry間隔が倍々になり (つまり失敗回数をnとすると2^(n-1)秒待つ),
retryretry-delay を組み合わせると固定長秒数のretry間隔を設定できます.
また retryretry-max-time を組み合わせると,retry間隔は倍々で増えてゆき,そのリトライ間隔が retry-max-time を超えるとギブアップする (retry で指定された回数に満たなくても) という挙動をします.

どちらを使ったら良いのか

お好みで.双方微妙にリトライ間隔の取扱いが異なるので用途にマッチしたほうを使えば良いと思います.
とは言えcurlは環境によって古い (そしてアップグレードできない) ということがあるのでwgetを使っておけば安心なんでしょうか.