このブログのスピードテストを向上させた件

Posted by jolantern on Thursday, November 3, 2016

サーバの負荷テストをかけた

それはこのブログを立ち上げて2週間後ぐらいの話。 ふと気になってこのサーバの負荷テストをかけてみた。たぶん大量のPOSTリクエストを投げてきたりしてサーバに負荷をかけてくれるんだと思う。

そうすると散々な結果が出た。6リクエスト/秒でサーバが500エラーを返す。さすがにそれはないだろ、VPSのプランのなかでは最弱だけど。と思ったけど現実そういう結果が出ている。仕方ないので他のテストもかけてみて、結果次第でチューニングを実施することにした。

サーバのスピードテスト

まぁWebサイトと言えばこの手のテストツールだろう、ということでスピードテストをかけた。このサイトで。 GTmetrix

結果はというと両方D判定。遅い。

私のブログがそんなたくさんの人に読んでもらえるのかという問題はおいておいて、これではGoogleにインデックスすらされないのではなかろうかという恐怖が有る。それは困るし、書いた以上誰かしらの目には止まりたいものだし、レスポンスの遅すぎるサイトは無いのと同じだろう。

 原因を調べる

このブログはnginxがホストしているWordpressだ。故にnginxの設定を見直せば多少解決するはずであるが、アプローチがわからなかった。

ずぶの素人ではないにしろ、高速化を考える設計レベルの思考は経験がなかった。

そこで寄らば大樹の影、巨人の方の上に立つということでGoogle先生のツールの恩恵にあやかることにした。下記ツール。

PageSpeed Insights

これを使うとモバイルとPCの両方を前提にしたスピードテストが出来る。ちなみに先にだしたD判定という数値だが片方はこのテストのスコアをもとに出してくれている。

そしてこのテストツールはテストするだけじゃなくて、改善案を提示してくれる。

通信を圧縮する

Googleのスピードテストで出た改善案の1つに、圧縮してみてはどうかというのがあった。よくよく見てみるとnginxの設定ファイルには圧縮するような設定はなにもされていない。

確かにこれでブログはホスト出来るし、大体のチュートリアルサイトはこんな感じの設定になっている。

server {
    listen       80;
    server_name  exsample.com;
    root         /var/www/wordpress;

    client_max_body_size 2M;

    index       index.php index.html index.htm;
    try_files $uri $uri/ /index.php?q=$uri&$args;

    location ~ \.php$ {
        fastcgi_pass            127.0.0.1:9000;
        fastcgi_index           index.php;
        fastcgi_param           SCRIPT_FILENAME  $document_root$fastcgi_script_name;
        include                 fastcgi_params;
    }
    location ~ /.well-known {
        allow all;
    }
}

みたいな。

素直に圧縮しよう。

圧縮方法は2つの手法が見つかった。普通にgzip圧縮。これは一番簡単で普通はやってるらしい感じだ。でももう1つ魅力的な選択肢があって、Googleの発表したアルゴリズムでの圧縮方法。

この圧縮アルゴリズムを使うには注意点が2つ。

1つは、対応しているブラウザはChromeのVer.49以降。今は52だしレガシーなブラウザなんて知らねえぜ、というなら気にする必要はない。

2つ目は、このアルゴリズムによる圧縮方法はSSL通信の元でしか有効にならない。

これが最初気づけなくて、セットアップの手順がのってる記事を鵜呑みにしてセットアップして、ハマった点の1つ。

キャッシュを使おう

たぶんWordpressの高速化となると最初に出てくるんじゃないだろうかという手法。

プラグインをいれて設定して、有効化すればいいから楽。 使ったのは下記のプラグイン。これだけでスピードテストのスコアはかなり上がった。Google先生のスピードテストは相変わらずだけど。SSL化を先にしないとダメとかそういうパターンだろうか。 WP Super Cache

実際のセットアップ手順

長々と前置きが長くなったが、簡単にセットアップ手順を記録しておく。

nginxのリビルド

この手順を試そうと思っている人は、まずnginxのバージョンとビルドした時のオプションを確認した方がいい。

<br></br>$ sudo nginx -V

こうするとバージョンと、ビルド時に付与されたオプションが見える。

恥ずかしながら筆者の環境だとnginxのバージョンが古すぎて、1.6.xとかだった。かなしい。

そして調べてみるとnginxは1.11.3から動的モジュールに対応してるらしい。つまり新しいモジュールを利用するがためにリビルドしなくていいということらしいのだ。 だったらそこまであげよう。ついでにモジュールいれよう。

nginx-buildのインストール

nginxのビルドを楽にしてくれるツールがnginx-build。まんまである。

OSXならbrewで入れられるが筆者の環境はCentOS7なので、下記サイトからtarをおとして解凍、実行権を付与してパスの通っているところにおいた。

<br></br>$ wget https://github.com/cubicdaiya/nginx-build/releases/download/v0.9.9/nginx-build-linux-amd64-0.9.9.tar.gz
$ tar xvf nginx-build-linux-amd64-0.9.9.tar.gz

$ chmod +x nginx-build

$ mv nginx-build /path/to/pathnotootterudokoka

ビルド用の設定とビルド

nginx-buildは、nginxのmakeとconfigureスクリプトの実行を自動でやってくれる。先述したモジュールはconfigureスクリプトを叩くときに追加する必要がある。動的モジュールに対応しているとはいえできればあとから追加なんて面倒な真似はしたくないよねってことでスクリプトを書く。

$ cat nginx_configure.sh
./configure \
 --user=nginx \
 --group=nginx \
 --sbin-path=/usr/sbin/nginx \
 --conf-path=/etc/nginx/nginx.conf \
 --with-http_gzip_static_module \
 --with-http_gunzip_module \
 --with-http_stub_status_module \
 --with-http_realip_module \
 --add-module=/usr/local/src/ngx_brotli

/usr/local/src/ngx_brotli に例のGoogle先生圧縮モジュールのソースがおいてある前提。解凍したやつをまんま /usr/local/src/ においただけ。

SSL化

nginxにSSLの設定をいれてあげればよい。ただし、今回は外部に公開しているブログだから、自己証明書はつかいたくない。というわけで、Let’s Encryptにお世話になることにした。比較的最近出たサービスで、無償でSSL証明書を発行してくれる。ただし60日ごとに更新が必要で、スクリプトによる自動更新を推奨しているらしい。 ここが非常に参考になった。ここの通りにやっただけである。 光の速さのWEBサーバー(nginx)をlet’s encryptでSSL化及びHTTP/2化。ついでにセキュリティ評価をA+にする。

結果

多少マシになた。なんかこのカスタムをした直後より悪くなってるので、また見直すべきなのだろうな。

スコア

そしてこれが最終的なnginxの設定。

server {

    listen       443 ssl;

    ssl_certificate /path/to/chain.pem;
    ssl_certificate_key /path/to/privkey.pem;
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    ssl_prefer_server_ciphers on;
    ssl_ciphers &#39;EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH&#39;;


    brotli on;
    gzip on;
    gzip_min_length 0;
    gzip_buffers 4 8k;
    gzip_types text/plain text/xml application/javascript application/x-javascript text/css;
    gzip_disable "msie6";
    gzip_vary on;
    gzip_static on;
    gzip_proxied any;

    # サーバー名
    server_name  server.coom;

    root         /path/to/root;

    client_max_body_size 50M;
    # index file タイプの優先順を設定します。
    index       index.php index.html index.htm;

    # ログファイル名
    access_log   /path/to/access.log;
    error_log    /path/to/error.log;

    try_files $uri $uri/ /index.php?q=$uri&$args;

    # PHP FPM
    location ~ \.php$ {
        fastcgi_pass            127.0.0.1:9000;
        fastcgi_index           index.php;
        fastcgi_param           SCRIPT_FILENAME  $document_root$fastcgi_script_name;
        include                 fastcgi_params;
    }
    location ~ /.well-known {
        allow all;
    }
}