kohei_blog.py

都内で働くエンジニアのブログです( ✌︎'ω')✌︎ 技術記事から時事ネタまで

nginXでretry処理を行う

f:id:kohei_iwamura:20180204104709j:plainnginXでproxyしたサーバーからのレスポンスがstatus_code:5xxだった場合

retryさせる設定を組み込みました。

nginX自体ではretryのオプションはないので、設定を応用して

結果retryさせている設定を入れる必要があります。


前提として

(nginx.conf)

location /image/ {
    proxy_pass http://bucket_name.s3-website-ap-northeast-1.amazonaws.com/image/;
 }

nginXへrequesturlが https://image/../.. のようなリクエストがきた時、

S3とproxyしてimageファイルを取得する設定を入れてあります。

https://image/profile/taro/hoge.png
→ s3://bucket_name/image/profile/taro/hoge.png のファイルを取得する

nginX設定の改修

status_code 500が返された場合、nginXでretryを行うようにする

nginx.confの設定

  • 変更前
location /image/ {
    proxy_pass http://bucket_name.s3-website-ap-northeast-1.amazonaws.com/image/;
 }
  • 変更後
upstream bucket_name {
    server s3-website-ap-northeast-1.amazonaws.com;
    server s3-website-ap-northeast-1.amazonaws.com;
    server s3-website-ap-northeast-1.amazonaws.com;
}

    location /image/ {
        proxy_pass http://bucket_name/image/;
        proxy_next_upstream http_500;
    }
}

設定内容詳細

upstream

  • サーバーのグループを定義している
  • nginXをHTTPロードバランサのように使用でき、グループ内のサーバーにアクセスされる

proxy_next_upstream

  • 指定のレスポンスが返された場合、upstream内で設定されている次のサーバーへproxyする
    • 今回はhttp_500と設定することにより、status_code:500で返された場合に実行される

● ポイント

同じサーバーをupstreamに並べることにより、実質retryさせている状況を作る

  • 実質、status_code:500で返された場合、3回retryを実行するようにしている

その他

upstreamにはオプション設定がいくつかあります。

今回は、retryの設定に関わるオプションを紹介します。

オプション default 説明
max_fails 1 fail_timeout の間、指定した回数の失敗が発生すると fail_timeout の間サーバーを無効にする (リクエストを割り振らない)
fail_timeout 10 指定秒数の間、接続の失敗やタイムアウトしたサーバーは一時的に無効状態にされる
backup backup でないサーバーが全て無効になった場合にのみ有効になる

今回取り入れた設定

upstream bucket_name {
    server s3-website-ap-northeast-1.amazonaws.com max_fail=0;
    server s3-website-ap-northeast-1.amazonaws.com max_fail=0;
    server s3-website-ap-northeast-1.amazonaws.com max_fail=0;
}

上記の設定を取り入れない場合の問題点

  • 1度でもエラーが返るとproxyが切断され、サーバーが無効となってしまう
    • 複数回のリクエストがnginXに送られた場合でも、fail_timeoutにより10秒間proxyが無効となっているので、status_code:502が返されます。

上記の設定を取り入れた利点

  • max_fail=0とすることで、サーバーからエラーが返ってきてもproxyを切断しないようにし、サーバーを無効状態にしないようにしました。