Skip to content

2.バックエンド 3.nginxの設定

nemupm edited this page Oct 30, 2015 · 3 revisions

/etc/nginx/nginx.conf

worker_processes  1;

events {
  worker_connections  10000;
  accept_mutex_delay 100ms;
}

http {
  upstream app {
    server unix:/dev/shm/app.sock;
    #server 127.0.0.1:8080;
  }
  tcp_nopush on;
  tcp_nodelay on;
  sendfile on;
  keepalive_timeout 65;
  send_timeout 60;
  etag off;
  keepalive_requests 3000;

  server {
    location / {
      proxy_pass http://app;
    }
    location ~ ^/(stylesheets|images)/ {
      open_file_cache max=100;
      root /home/isucon/webapp/public;
    }
  }
  ## for kataribe
  #access_log  off;
  log_format with_time '$remote_addr - $remote_user [$time_local] '
                     '"$request" $status $body_bytes_sent '
                     '"$http_referer" "$http_user_agent" $request_time';
  access_log /var/log/nginx/access.log with_time
}
  • worker_processes 1;

    • CPUのコア数と同じにすればかなり速くなるらしい。1個しか割り当てられてない状況では増やすとスレッド間通信のオーバーヘッドが逆に増えるので1で。
  • accept_mutex_delay 100ms;

    • acceptシリアライズ化のためのmutexが確保出来なかった際に、retryするまでの待機時間だそうです。デフォルトは500msec。
  • tcp_nopush on;

    • レスポンスヘッダとファイルの内容をまとめて送るようになるので送信するパケット数を最小化できます。
  • tcp_nodelay on;

    • 小さなパケットを待つことなく、そのまま送信するオプションです。待ちがないので早くなりますが、パケット数と送信量が増えます。場合によってはoffでも良さそう。(参考
  • sendfile on;

    • sendfileディレクティブはコンテンツのファイルの読み込みとクライアントへのレスポンスの送信にsendfile() APIを使うかを設定します。sendfile()を使うとカーネル空間内でファイルの読み込みと送信が完了するため、効率良くファイルの内容をクライアントに送信できます。デフォルトの設定値はoffです。
  • etag off;

    • 下手にonにするよりoffにしたほうが良さそう(参考
  • server unix:/dev/shm/app.sock;

    • unix domain socketでgoappと通信するように変更している。
    • /dev/shm/app.sockのpermissionの問題で502 bad gatewayになることがあるので注意

SSI(ServerSideIncludes)

以下のように、proxyしたいところはproxyに、 nginxで返したいところはssi on;にして、rootにテンプレートがあるディレクトリを設定する。
なお、変数をerr_messageとerr2つ使っているが、出来れば変数は少ない方が良いと思われる。
kazeburoさんのソースコードでは、$cookie_isucon_session ~ "^(.+)%2C(.+)%2C(.+)$"のように正規表現で分けていた(%2Cはコンマのこと)。
ちなみに、nginxのifは曲者なので要注意

    location /mypage {
      proxy_pass http://app;
    }
    location /login {
      proxy_pass http://app;
    }
    location /report {
      proxy_pass http://app;
    }
    location / {
      set $err 0;
      if ( $cookie_notice ){
        set $err 1;
        set $err_message "You must be logged in";
      }
      if ( $cookie_notice = 1){
        set $err_message "You're banned.";
      }
      if ( $cookie_notice = 2){
        set $err_message "This account is locked.";
      }
      if ( $cookie_notice = 3){
        set $err_message "Wrong username or password";
      }
      ssi on;
      root /home/isucon/webapp/go/templates-nginx; 
    }

以下はテンプレートの書き方。

<!--# if expr="$err = 1" -->
    <div id="notice-message" class="alert alert-danger" role="alert">
        <!--# echo var="err_message" -->
    </div>
<!--# endif -->

cache-control

やる機会あんのか