28日目:nginx+FastCGIでRCCのサイトを高速化!

あっと言うまに2019年も終わりですね、RCCの副執行委員長のてんちょです。
今年はWebサイトのリニューアルを担当したり、ロゴコンペを開催したりと、いわゆるプロデューサー的立ち位置です。
是非「プロデューサー」(某ゲームみたい)と呼んでいただけると嬉しいです。

Webサイトリニューアルした

さて、本題に入るんですが、上でも言ったようにRCCのWebサイトをリニューアルしました。

せっかく機会をいただいたので、会誌にも書いたんですが、デザインをこだわったり、アイキャッチを増やしたりと見栄え良く進めました。

Webから読めるので、是非呼んでね。

コンテンツが増えるとサイトが重くなる

おかげさまで、今年のアドベントカレンダーでは画像をアップロードしてくれる人が増えたりして、個人的には非常に嬉しいです。
サイトにアクセスしてくださる方も多くなっているようです。

しかし、テーマを変えた都合や、デザインを変更した都合で、PHPのレンダリングが若干遅くなってしまいました。

と、いうことで、今回はnginxとFastCGIを利用してRCCのサイトを軽量化したいと思います。

※もちろん前提として画像を増やしたことによるロード時間が長くなったことも考えられます。
このサイトでは、「Compress JPEG & PNG images」を利用し、画像の圧縮を行っています。気になる方は是非検索して導入してみてください。

実際に設定をする

nginxでは、「プロキシキャッシュ」と「FastCGIキャッシュ」の2つのキャッシュ機能が搭載されています。
リバースプロキシを利用されている方は、「プロキシキャッシュ」の方が適切なこともありますが、今回RCCはネットワーク環境が複雑なため、Webサーバ単体で適用できる「FastCGIキャッシュ」を選びました。

/etc/nginx/nginx.conf 内のhttpディレクティブ内に以下の1行を書き足します。

# fastcgi cache
ffastcgi_cache_path /var/cache/nginx/cache levels=1:2 keys_zone=wp-key:100m inactive=1d max_size=128m;
levels: キャッシュの階層を示しています
keys_zone: 複数ホストで運用する際には適切に設定します:メモリ最大サイズを設定
inactive: キャッシュの有効期間
max_size: キャッシュ全体の最大メモリサイズ(全てのホストで共通)

続いて、個別の設定ファイル(/etc/nginx/conf.d/*.conf)に以下のような事項を記述していきます

# headerにキャッシュが有効であるか出力する
add_header Fastcgi-Cache $upstream_cache_status;

# fastcgi cacheのフラグ
set $do_not_cache 0;
set $mobilef '';

# POST中の場合
if ($request_method != "GET") {
    set $do_not_cache 1;
}
# WordPressにログイン中、コメント中、記事作成中
if ($http_cookie ~ ^.*(comment_author_|wordpress_logged_in|wp-postpass_).*$) {
    set $do_not_cache 1;
}
# 携帯用のキャッシュを作成する
if ($http_user_agent ~* '(iPhone|iPod|Opera Mini|Android.*Mobile|NetFront|PSP|BlackBerry)') {
    set $mobilef '.mobile';
}

location ~ \.php$ {
    fastcgi_pass   unix:/var/run/php-fpm/php-fpm.sock;
    fastcgi_index  index.php;
    fastcgi_split_path_info ^(.+\.php)(.*)$;
    fastcgi_param  SCRIPT_FILENAME  $document_root/$fastcgi_script_name;
    include        fastcgi_params;

    # fastcgi cacheの設定
    fastcgi_no_cache $do_not_cache;
    fastcgi_cache_bypass $do_not_cache;
    fastcgi_cache wp-key;
    fastcgi_cache_key    $scheme://$host$request_uri$mobilef;
}

実はRCCのサイトは、パソコンとスマートフォンでは別のページを生成・配信しています。実はキャッシュ運用する際に、これってなかなか大変なんですよね。

したがって、今回は「fastcgi_cache_key」に対して、user_agentがスマホの時だけ「mobile」タグをつけて設定ファイルを作成しました。

キャッシュ自動リセット

あとは記事が投稿されたタイミングなどでキャッシュがリセットされれば最高ですよね。本来であれば、「nginx cache」などのプラグインを利用すれば簡単にリセットされるのですが、実はこれもPCとスマホのWキャッシュをしている環境では、うまく動かないことがあります。

従って、今回はWordPressテーマの「function.php」に直接以下のコードを書いて、記事投稿時などに自動でキャッシュ削除されるようにカスタマイズしました。

// 記事投稿時に自動でFastCGIキャッシュを削除
function nginx_cache_purge() {
    /* ここにNginxのキャシュを削除する処理 */
	array_map('unlink', glob("/var/cache/nginx/cache/*/*/*"));
	array_map('rmdir', glob("/var/cache/nginx/cache/*/*"));
	array_map('rmdir', glob("/var/cache/nginx/cache/*"));
}
 
/* 新規投稿、更新等のステータス変更で削除処理が発動 */
add_action( 'new_to_publish', 'nginx_cache_purge' );
add_action( 'publish_to_publish', 'nginx_cache_purge' );
add_action( 'pending_to_publish', 'nginx_cache_purge' );
add_action( 'draft_to_publish', 'nginx_cache_purge' );
add_action( 'auto-draft_to_publish', 'nginx_cache_purge' );
add_action( 'future_to_publish', 'nginx_cache_purge' );
add_action( 'publish_to_trash', 'nginx_cache_purge' );
add_action( 'post_updated' , 'nginx_cache_purge');
add_action( 'edit_post' , 'nginx_cache_purge');

チューニングは大切

今回は、nginxとFastCGIを利用して、サイトの高速化をすることについて紹介して参りました。WordPress環境で、FastCGIを利用したPCとスマホのWキャッシュと自動リセットについての記事はなかなか見つからないため、頑張って調べてまとめてみました。

実はRCCのサイトはオンプレサーバで稼働しているため、チューニングがかなり柔軟にできます。Webサイトリニューアルが行われてからも、複数回のチューニングを行っており、WordPressのクセにかなり爆速なサイトになっているはずです。(この記事を書きながら更にチューニングしてました)

それではみなさん良いお年を。てんちょでした。

参考ページ

CentOSのNginxにFastCGIキャッシュを設定してサイト速度を100倍にする
 https://www.rem-system.com/nginx-fastcgi-cache/
NginxでWordPressを使う時の設定をまとめてみた
 https://worklog.be/archives/3222
Nginx の fastcgi cache を利用して WordPress を高速化する
 https://mano.xyz/1619/

Twitterでフォローしよう

おすすめの記事