コーポレートサイトのNginxの設定をチューニングも兼ねていじった

January 7, 2015 by Yudai Suzuki

年末にリニューアルしたコーポレートサイトのNginxの設定をチューニングも兼ねていじった。

年末ハッカソンしてコーポレートサイトをAWS + Nginx + Unicorn + Sinatra構成でリニューアルした

構成

  • Amazon EC2 t2.small 1台
    • Amazon Linux
    • ELB無し
    • Public Subnetのみ
    • EC2インスタンスにEIP割り当てて、DNSのAレコード設定してるだけ
  • Nginx 1.7.7
  • Ruby 2.2.0
    • Sinatra
      • 基本的に分割したhtmlをpartialでマージしてindex.htmlを返してるだけ
    • Unicorn
      • worker 4

最終的なnginx.confとビルド時のコマンド

https://gist.github.com/onigra/ff92467d1107a5b868e1

やったこと

httpサーバの設定を本格的にいじったのが初めてなので、インフラ専門の人から見て特に目新しいことはしてないと思う。

  • チューニング
    • worker_processesをautoにする
    • worker_rlimit_nofileとworker_connectionsの数値をいじる
    • use epoll
    • 静的コンテンツをgzipで返す設定
    • proxy cacheを使う
    • 静的コンテンツはNginxに返させる
  • セキュリティ
    • server_tokens off
    • DDos対策
  • 趣味
    • GeoIPの情報をログに出す

チューニング

厳密な検証はしてないけど、プロキシキャッシュを有効にしたこと以外は大して差が出なかった印象。 まあこれはサイトの特性もあるだろうけど。

一応、Vagrantに対してApache Benchを叩いた結果をGistに残してある。

https://gist.github.com/onigra/85cd9b282dc7b2db5405

productionはこっち

https://gist.github.com/onigra/32548e563877c1c5b00c

外部サイトの診断結果

まあ、t2.small1台なら十分だと思うんですがいかがでしょうか。

DDos対策

Nginxのデフォルトモジュールでngx_http_limit_conn_modulengx_http_limit_req_moduleっていうのがあったので、それを使う。

http {

    ...

    # 同時接続数制限を行う際のメモリ領域を10MB確保
    limit_conn_zone $binary_remote_addr zone=limit_conn_zone1:10m;

    # 1秒あたり50リクエストを超えるペースだと503を返す
    limit_req_zone $binary_remote_addr zone=limit_rec_zone1:10m rate=50r/s;

    server {

        ...

        location / {
            # 1つのIPからの同時接続数が100を超えると503が返る
            limit_conn limit_conn_zone1 100;

            # 1秒あたり50リクエストを超えた場合、100リクエスト超えるまで待ってから503を返す
            limit_req zone=limit_rec_zone1 burst=100;
        }
    }
}

ログに国籍と都市情報を出す

なんとなく面白そうなのと、後で解析する時に遊べそうかなと思ってngx_http_geoip_moduleを入れた。 ビルドの際にGeoIP-develが必要。

confのgeoip_countryGeoIP.datgeoip_cityGeoLiteCity.datのパスを書くと、GeoIP関連の変数が使えるようになる。

ちゃんと調べてないんだけど、CentOS6.5だとGeoIP系のファイルが最初から入ってたか、GeoIP-develが入れたのか揃ってたけど、AmazonLinuxはGeoLiteCity.datが無かったので取ってくるようにしてる。

http {

    ...

    geoip_country /usr/share/GeoIP/GeoIP.dat;
    geoip_city /usr/share/GeoIP/GeoLiteCity.dat;

    log_format ltsv "geoip_country_name:$geoip_city_country_name\t"
                    "geoip_country_code3:$geoip_city_country_code3\t"
                    "geoip_city:$geoip_city";

    access_log /var/log/nginx/access.log ltsv;

    ...
}

あとできそうなこと

  • 静的コンテンツを予めまとめてminifyしてgzipしておく

ダルい。

  • SPDY対応

これはそのうちやると思う。なってるとカッコいいし。冗長化も含めてこの構成がよさそう。

まとめ

© 2017 | Onigra | Powerd by Hucore theme & Hugo