「高トラフィック」の悪夢とサーバーダウンの不安
ウェブサイトが安定して稼働していると思っていた矢先、突然ダウンしてしまう場面を想像してみてください。原因は、記事がバズったことや、広告キャンペーンによるトラフィックの急増かもしれません。筆者もかつて、502 Bad Gatewayエラーを連発する VPSの対応で徹夜したことがあります。RAMを4GBから16GBにアップグレードしても、CPU使用率は制御不能なまま100%に跳ね上がっていました。
実際の問題はサーバーのスペック不足ではなく、リクエストの処理方法にありました。アクセスがあるたびに、NginxはPHP-FPMを呼び出し、PHPはMySQLにクエリを投げ、ようやく結果を返します。このプロセスが数千回繰り返されることで、リソースはあっという間に枯渇してしまいます。
なぜ高スペックなサーバーでも重くなるのか?
ブログや商品ページのコンテンツの多くは、頻繁には変更されません。同じコンテンツに対してサーバーに何度もPHPコードを実行させ、データベースにクエリを投げさせるのは、非常に大きな無駄です。
主な原因はI/O WaitとCPU Overloadです。NginxのFastCGI Cacheを使用しても、膨大な同時接続(コンカレント)リクエストが発生すると、パフォーマンスには限界が生じます。ここで、負荷を肩代わりするためのより専門的なキャッシュレイヤーが必要になります。
現在主流の3つの解決策
パフォーマンスの課題に直面したとき、エンジニアは通常、次の3つのアプローチから選択します。
- ハードウェアのアップグレード: 手っ取り早いですがコストがかかります。RAMを無限に増やすことはできませんし、冗長な処理という根本的な解決にはなりません。
- オブジェクトキャッシュ(Redis/Memcached)の利用: データベースの負荷を軽減します。しかし、Redis from データを取得するために依然としてPHPを動かす必要があり、CPUは働き続けることになります。
- リバースプロキシキャッシュの利用: これが最も効果的な解決策です。ウェブサーバーの前面にキャッシュレイヤーを配置し、HTMLをRAMに保存して、ユーザーに即座に返します。
Varnish Cache — 超高速な「中継ステーション」
Varnish Cacheは非常に強力なHTTPアクセラレータです。自動販売機のようなものだと考えてください。ユーザーがウェブページをリクエストすると、VarnishはRAM内にコピーがあるか確認します。あれば(Cache Hit)、わずか10〜50msで返します。なければ(Cache Miss)、そこで初めてNginxにリクエストを転送します。
筆者の実務経験では、Varnishを導入した後、一般的なWordPressサイトでCPU使用率を10%未満に抑えつつ、負荷耐性を20倍に高めることができました。以下に、UbuntuでVarnishとNginxを組み合わせる方法を説明します。
詳細なインストール手順
ステップ1:NginxとVarnishのインストール
まず、以下のコマンドでシステムを更新し、必要なパッケージをインストールします。
sudo apt update
sudo apt install nginx varnish -y
ステップ2:Nginxをバックエンドに変更する
デフォルトではNginxはポート80で動作しています。Varnishを「最前線」(ポート80)に配置し、Nginxを後方(ポート8080)に下げます。
ウェブサイトの設定ファイル(通常はdefaultファイル)を開きます:
sudo nano /etc/nginx/sites-available/default
listen 80; を listen 8080; に変更します。IPv6の行がある場合は、それも忘れずに変更してください:
server {
listen 8080 default_server;
listen [::]:8080 default_server;
# ... 他の設定はそのまま維持 ...
}
その後、構文をチェックしてNginxを再起動します:
sudo nginx -t
sudo systemctl restart nginx
ステップ3:Varnishをポート80で待機するように設定する
次に、Varnishがポート80でリクエストを受け取り、ポート8080のNginxからデータを取得するように設定します。
Varnishのサービス設定ファイルを編集します:
sudo systemctl edit --full varnish
ExecStart の行を探し、-a :6081 を -a :80 に変更します:
ExecStart=/usr/sbin/varnishd -a :80 -a localhost:8443,PROXY -f /etc/varnish/default.vcl -s malloc,512m
ヒント: -s malloc,512m パラメータは、キャッシュ保存用に512MBのRAMを割り当てます。サーバーに8GB以上のRAMがある場合は、思い切って1gや2gに増やしても良いでしょう。
次に、VCLファイル内でVarnishがバックエンドのNginxを参照するように設定します:
sudo nano /etc/varnish/default.vcl
backendブロックを確認し、以下の設定になっているか確認します:
backend default {
.host = "127.0.0.1";
.port = "8080";
}
最後に、サービスを再起動します:
sudo systemctl daemon-reload
sudo systemctl restart varnish
SSL(HTTPS)への対応
VarnishはHTTPSを直接サポートしていません。これに対処するために、SSL Termination(SSL終端)という構成をとります。
データフローは次のようになります:**ユーザー (Port 443) -> Nginx (SSL処理) -> Varnish (Port 80) -> Nginx (バックエンド – Port 8080)**。この方法により、安全なSSL証明書を維持しつつ、Varnishの爆速なスピードを享受できます。
ポート443をリッスンするNginxサーバーブロックを設定し、Let’s Encryptをインストールして、proxy_pass でリクエストを http://127.0.0.1:80 に転送するだけです。
実際の効果を確認する
Varnishが動作しているか確認するには、curl コマンドでヘッダーを確認します:
curl -I http://your-domain.com
Via: 1.1 varnish という行が表示されれば、正常に動作しています。より詳細に監視するには、varnishstat コマンドを使用します。このツールはキャッシュのHit/Miss率をリアルタイムで表示し、リクエストの何パーセントがRAMから提供されているかを確認できます。
おわりに
Varnishの導入自体はそれほど難しくありません。ただし、管理画面(wp-adminなど)や決済ページを誤ってキャッシュしないように、default.vcl ファイルを微調整する必要があります。
まずはこの基本設定から始めてみてください。その後、使用しているソースコード(WordPressやLaravelなど)に応じて、Cookieの除外ルールなどを追加していくことになります。NginxとVarnishの強力なコンビがあれば、ハードウェアの追加コストをかけずに、1日あたり数百万件のアクセスをさばくことができるでしょう。

