nyakuroのブログ

音楽ユニット"sugarmosaic"のコンポーザーの@nyakuroのブログ。作詞・作編曲 / Web Engineering / 写真・映像などについて書きます。

【弱小サイトに最適】サーバーの構成をNginx + Apacheの構成、Nginxでリバースプロキシして大量のアクセスに対応する

こんにちは。nyakuroです。
夏コミに落選してしまいました。初めての落選です。
絶賛スケジュールなどを切り直したりしている最中です。

落選して少し時間ができたので(;_;)、
sugarmosaicのサーバーの設定変更をしていました。
今回はその覚書です。

もともとApacheのみで動いていたのですが、今回の対応でNginx + Apacheの構成になりました。

こんな人に最適です

  • さくらのVPSなど、専用サーバー1ホストでサイトを運営している人
  • 画像や音楽ファイルなどの静的ファイルを大量に読み込んでるけど、全く最適化してないため、リクエスト数がものすごいことになっているサイト
  • 静的ファイルを別ドメインに分離していないサイト
  • バックエンドのフレームワークApache依存になっていて、簡単にNginxに移行できない人

何をしたか

  • 画像や音声ファイル、CSS、JSなどの静的ファイル → Nginxが担当
  • その他のファイル → Apacheが担当

PHPフレームワークApacheに依存したものでも、基本的には影響を与えることなく移行ができます。
ただ、.jpgなどに認証を書けていて、その認証処理をスクリプト側でやっているようなサイトは注意が必要ですが。。

sugarmosaicの現状

sugarmosaic.com

sugarmosaicは、画像や音楽ファイルなどを大量に使っているのですが、全部同じドメイン上に載せていて、同じホストにアクセスが集中しています。
しかも、CSSスプライトなどを使った最適化は一切行っていません。
おさぼりです。
f:id:cat_b:20160612141245p:plain

41 requests!
特に非同期の遅延処理とかは行っていないので、1回サイトにアクセスするだけで、ホストへのアクセスが集中する状況です。
たぶん数人が同時にアクセスするだけで、同時接続数が跳ね上がってもたつく状態だと思います。

なので、大量の同時接続をさばくのに適したnginxに画像とか動画とか、CSS, JSなどのレスポンスを任せてしまおうというのが今回のゴールでした。

対応内容

特に特別なことはしていないので、参考にしたサイトを以下に並べます。

rubyは使ってないので最初の部分はスキップして、「apache.confの設定」から下の項目を順にやっていけばいいと思います。 dev.classmethod.jp

リバースプロキシキャッシュとして使いたい場合は、以下のページも参考にできると思います。 設定ファイルのコメントも親切で理解に役立ちます。 bren.jp

上記を見つつ、最終的な設定は以下にしました。

$ cat /etc/nginx/conf.d/reverse-proxy.conf

upstream web-apache{
  ip_hash;
  server 127.0.0.1:8080;
}
server {
  listen        80;
  server_name   sugarmosaic.com;

  # 静的ファイルはnginx
  location  ~* .*\.(jpg|gif|png|css|js|html|mp3|){
    root    <ドキュメントルートを書く>;
    index   index.html index.htm;
    expires 30d;
    break;
  }

  location / {
    proxy_set_header  X-Real-IP       $remote_addr;
    proxy_set_header  X-Forwarded-For $remote_addr;
    proxy_set_header  Host            $http_host;
    proxy_pass http://web-apache/;
  }
}

対応結果

以下のコマンドで検証しました。

$ ab -c 10 -n 100 http://sugarmosaic.com/

10個のクライアントから、合計100同時接続した場合の想定です。

【before】 Apache only

This is ApacheBench, Version 2.3 <$Revision: 1663405 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking sugarmosaic.com (be patient).....done

Server Software:        Apache/2.4.18
Server Hostname:        sugarmosaic.com
Server Port:            80

Document Path:          /
Document Length:        4963 bytes

Concurrency Level:      10
Time taken for tests:   10.455 seconds
Complete requests:      100
Failed requests:        0
Total transferred:      532800 bytes
HTML transferred:       496300 bytes
Requests per second:    9.56 [#/sec] (mean)
Time per request:       1045.492 [ms] (mean)
Time per request:       104.549 [ms] (mean, across all concurrent requests)
Transfer rate:          49.77 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        8  293 1079.7     13    7680
Processing:    16   20   4.1     20      43
Waiting:       14   19   3.6     18      42
Total:         25  313 1080.1     33    7704

Percentage of the requests served within a certain time (ms)
  50%     33
  66%     38
  75%    186
  80%    242
  90%    422
  95%    934
  98%   5282
  99%   7704
 100%   7704 (longest request)

Requests per second: 9.56 [#/sec] (mean)

全然リクエストを捌けてないですね。。
これだと、どこかに貼られてアクセス集中したらイチコロかもしれません。

ちなみに、実際にもうちょっと同時接続数を増やしてコマンドを叩くと応答が返ってこなくなりました。。アブナイ

【after】 Nginx + Apache

This is ApacheBench, Version 2.3 <$Revision: 1663405 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking sugarmosaic.com (be patient).....done

Server Software:        nginx/1.10.1
Server Hostname:        sugarmosaic.com
Server Port:            80

Document Path:          /
Document Length:        4934 bytes

Concurrency Level:      10
Time taken for tests:   0.681 seconds
Complete requests:      100
Failed requests:        0
Total transferred:      528900 bytes
HTML transferred:       493400 bytes
Requests per second:    146.79 [#/sec] (mean)
Time per request:       68.125 [ms] (mean)
Time per request:       6.813 [ms] (mean, across all concurrent requests)
Transfer rate:          758.17 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    0   0.1      0       0
Processing:    34   65  17.5     63     109
Waiting:       34   65  17.5     63     109
Total:         34   65  17.5     63     110

Percentage of the requests served within a certain time (ms)
  50%     63
  66%     73
  75%     79
  80%     83
  90%     94
  95%     97
  98%    101
  99%    110
 100%    110 (longest request)

Requests per second: 146.79 [#/sec] (mean)

わー単純計算で15倍以上のリクエストを捌けてる!
全然違いますね。

考察

今回、Nginxの導入でかなりの成果を出すことが出来ました。
ただ、NginxとApacheが共存している状態は正直面倒な状況です。
節約のためにGitLabも同じホストに載せてしまおうかと思っていましたが、なかなかハードルが高い状態になっています。
メンテナンス性が悪い!

将来的にはPHPなどのサーバーサイドスクリプトもNginxに任せられるようにしていけたらと思っています。