サイトをVarnishを使って爆速化した話。橋本技研ブログ売れるホームページ研究所、橋本技研の技術系備忘録ブログ。ショッピングカートシステムの制作などが得意です。サイトをVarnishを使って爆速化した話。Nuxt.JSあるコーポレートサイトをリリースしたのですが、最初のレスポンスが返ってくるのがちょっと遅いのでなんとかしたい。サイトの構成は以下のとおり。これとは別のサーバにインストールしてある。利用したCMSは、cockpitというOSSを採用。Cockpitは、いろいろカスタマイズが効いてかゆいところに手が届くので、マジでお勧め。※cockpit公式のDockerイメージは、ファイル名に日本語を使用できません。採用した理由は、画像やテキストを思い立った時にいつでも変更出来て、尚且つデザインにもしっかりこだわりたいという要望に応えるため。すべてのテキストと画像を差し替え可能にしてみた。ローカルの開発環境では、そこそこのレスポンスだったので、行けるかなと思ったけど、実際にVPSで動かしてみたら、ちょっと重い。レスポンスが返ってくるまでに、2秒ちょいかかる。そんなにアクセスが集中するタイプのサイトではないけれど、ApacheBenchで計測してみたら、1秒あたり0.9レスポンスしか返せない。Nuxtなので、最初の1ページさえ読み込まれてしまえば、あとはサクサクなんだけど、Googleからの評価も気になるし、やはり出来るだけ速くしたい。SPAでなくSSRを採用した理由は、OGPまわりをちゃんとしたかったのが理由なので、ヘッダーまわりだけサーバーサイドで処理して、あとはクライアントサイドでHeadlessCMSから取得させてみようかと思ったりもしたけど、そんなことしても、ユーザーは結局画面が組みあがるのを待つことになるので、本質的な解決にはならない。いう訳で、キャッシュを使うことにした。キャッシュは、Nginxの設定をごにょごにょするのは面倒くさい好きでないので、Varnishを使うことにした。Varnishは、速いのはもちろんだけど、動的にキャッシュをクリアしたりできる点がとても便利。特定のパスはキャッシュを使わないよう設定したり、指定したページのキャッシュだけをクリアしたり、全ページクリアなんてこともできる。今回は、キャッシュ期間をガッツリ長く設定しておき、CMSで内容を編集した後に、キャッシュを全クリアして更新するというシンプルかつ豪快(手抜きか?)な仕様にしてみた。Varnishの導入はとっても簡単、Dockerならね。Swarm)の設定ファイルはこんな感じに。メモリやCPU)を制限する設定もしてますが、まだチューニング中なのでそこは割愛。ファイルの永続化や設定ファイル設置のため、以下のディレクトリやファイルをマウント。※MySQL※certs.jsonは空のファイルを用意しておく必要があります。はまりポイントはパーミッション。500にしておく必要があったと思う。※走らせる前に、Dockerコマンドで「overlay」という名前のoverlayネットワークを作っておく必要があります。※wordpress、mysqlは空のディレクトリを用意しておきます。パーミッションは環境に合わせて適宜設定してください。webというラベルの付いたコンテナは、nodeイメージをベースにしてビルドしたもので、Nuxt.JSで構築したウェブサイトのイメージファイル。「hogehoge.com:5000/fugafuga/web:latest」なんてDockerイメージファイルは存在しないので念のため。サーバの入り口のリバースプロキシとしては、NginxやApacheではなく、Traefikを使って、ドメインやパスによる振り分け、SSL関係を簡単に済ませる構成とした。Traefikが超絶楽すぎるので、もう一生NginxやApacheの設定ファイルは触りたくない(と言いつつも、wordpressコンテナにはApacheが使われてたりして)ただし、処理能力はNginxより若干落ちる。ここがボトルネックになることはそうないよね。本題から外れるけど、Traefikは本当に便利。ドメインの設定は上記の設定ファイル内に書くだけでOK。振り分け先のコンテナのlabelに「traefik.frontend.rule=xxxxxx.com」とドメインを指定してコンテナを起動すれば、あとはTraefikが勝手にLetsEncryptの証明書を取得して、ドメイン宛のアクセスをそのコンテナに振り分けてくれる。コンテナ毎に、ドメインを設定するだけでマルチドメインのサーバが出来上がってしまう。パスなどの条件(正規表現も使えるし、パスの差し替えも出来る)によって、振り分け先のコンテナを変えることも可能。今回は、/blogから始まるパスは、Wordpressコンテナに振り分けている。そもそもがロードバランサーなので、同じコンテナを複数起動すれば負荷の分散もしてくれるし、標準でsocketにも対応してるし、マジで最高。※Traefikは、managerノードでなく、workerノードで走らせるほうが安全ですが、今回はVPS1台構成なのでやむ無くmanagerノードで走らせてます。(ちょっとTraefikに熱くなりすぎた...)先程の設定ファイルについて、簡単に説明すると、Traefikがすべての入力を受け持ち(開放するポートは、80と443)、パスが/blogに先頭一致するアクセスは、wordpressコンテナに振り分け、それ以外はvarnishコンテナに振り分けるよう設定している。Varnishの設定ファイル(default.vcl)は、以下のとおり。1w;}javaScriptチックな文法だけど、微妙に違っていて、いろいろはまりどころが多いけど、なんとなくやっていることが分かるのでは。Nuxt.js)を指定する。ホスト名とポートを環境に合わせて指定。Varnishに届いたリクエストを、どう対処するかを記述する。いう秘密のURLを用意してみた。ブックマークしておいて、呼び出せばキャッシュが全クリアされるという仕様。^/.*”)」がその命令で、ルート以降すべてのキャッシュが無効になる。割り当てる方が安心だと思うけど、まあCurl使いこなすクライアントさんいないよね)さらに、キャッシュしては困る呼び出し(問合せのPOSTなど)は、Varnishを迂回させてやる。今回は、/sys/以下の呼び出しの場合、pipeメソッドを呼び出して迂回させる設定に。※pipeした処理は、そのレスポンスもVarnishをスルーして返却される。vcl_backend_responseは、バックエンドからのレスポンスに対する追加の処理を記述する。レスポンスに、ttlを設定してやればキャッシュ期間をコントロールできる。「1w」と設定してやれば、Varnishに1週間キャッシュされるようになる。パスや拡張子によって、期間を変えることなんかも出来るので、用途に合わせて適切に設定して欲しい。ここはハマりポイントなんだけど、Varnishの設定方法についてググると、古いバージョンの情報ばかりが出てくる。現在のVarnish6とは設定方法が異なるので注意が必要。なんかを覗く方が有用な情報が得られたりするのでお勧め。あと、webコンテナについては、Nuxtでbuild済みのnodeサーバを用意した。コンテナを立ち上げればすぐにサイトが見えるようにした。webコマンド一発でサーバの設定&公開完了。Dockerはほんとに便利。ちなみに僕は、VPSはLinodeがお気に入り。Storageなら約1000円/月程度とお財布にやさしくて好き。100、総アクセス数1000などという、おそらくこのサイトが一生経験することの無いであろう負荷を掛けてみたけど、さらりとこなしてくれた。