Nginx とunicornとRails を使った環境でのタイムアウト挙動確認


目的

  • めっさ重い処理をRails で書いたらめっさ怒られた
  • めっさ重い処理 って感覚的には分かるけどサーバーの設定等からちゃんと めっさ重い処理 とはなんなのかを定義したい
  • あわよくばRails にテストを追加したい

環境

Rails 4.2
Nginx 1.6.2
unicorn 4.8.3

設定

  • unicorn.rb
〜略〜
num_unicorn_workers = ENV['UNICORN_WORKERS'].to_i
worker_processes((num_unicorn_workers > 0 ? num_unicorn_workers : nil) || (ENV['RAILS_ENV'] == 'production' ? 4 : 2))
timeout           30
〜略〜
  • /etc/nignx/conf.d/gessy0129.conf
〜略〜
proxy_connect_timeout 300; # unicorn 接続を待つことが出来る時間
proxy_send_timeout    300; # unicorn へのリクエスト送信を待つことが出来る時間
proxy_read_timeout    300; # unicorn からの応答を待つことが出来る時間
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_pass http://gessy0129;
〜略〜

動作確認

Rails での重い処理を書く

  • 502 Bad Gateway

unicorn のタイムアウト > nginx のタイムアウト

  • proxy_read_timeout 以外を 3にする
    • 200 OK
  • proxy_read_timeout を 3にする
    • 504 Gateway Timeout
  • unicorn を落とす
    • 502 Bad Gateway

Rails側でテストを書くなら・・

  • nignx.conf のproxy_read_timeout に設定した秒数以内にレスポンスが返せるか?
  • unicorn.rb に設定した秒数以内にレスポンスが返せるか?

適当なテスト概要

  1. File.existsして、
  2. File読み込んで、
  3. timeout とかproxy_read_timeout の値を取得して、
  4. rspec で意図的にタイムアウト起こし、
  5. エラーページが表示されるのを確認する

このテストの懸念

  • Jenkins でどうやるんだ・・
  • 真面目にtimeout を待っていたらその部分のテストがめっちゃ遅くなって効率悪くなるので適当に値を編集してあげないと