2026年5月26日

2026年5月26日

WordPressへの突然のトラフィックスパイクを対処する方法

はじめに

SNSで記事がバズったり、メディアに掲載されたりして突然大量のアクセスが集中すると、準備のできていないWordPressサイトは簡単にダウンします。このようなトラフィックスパイクを生き残るには、事前の準備と即座に実行できる対応手順が不可欠です。本記事では、キャッシュ・CDN・データベース接続プールを活用してスパイクに耐えるWordPress環境の構築方法を解説します。

症状・原因

  • 急激なアクセス増加でサーバーのCPUが100%に達し500エラーが多発する
  • MySQLの接続数が上限(max_connections)に達し「Too many connections」エラーが発生する
  • 管理画面(wp-admin)にもアクセスできずメンテナンス操作ができない
  • PHPプロセスが枯渇してFast CGI queue overflowが発生する
  • 普段はキャッシュが機能しているがログイン済みユーザーや特定URLでキャッシュが無効になっている

解決手順

ステップ1:WP Super Cacheでページキャッシュを有効化

最も即効性の高い対策として、ページキャッシュを有効にします。

<?php
// wp-config.php に追加
define( 'WP_CACHE', true );

// WP Super Cache のカスタム設定(wp-content/wp-cache-config.php)
// インストール後に以下の設定を確認・変更

$cache_enabled         = TRUE;
$super_cache_enabled   = TRUE;  // mod_rewrite を使う高速キャッシュ
$cache_compression     = TRUE;
$cache_max_time        = 3600;  // 1時間キャッシュ
$cache_rejected_uri    = [
    '/wp-admin/',
    '/wp-login.php',
    '/wp-comments-post.php',
    '/cart/',       // WooCommerce カート
    '/checkout/',   // WooCommerce チェックアウト
    '/my-account/', // ログイン済みページ
];

// ログイン済みユーザーはキャッシュしない
$cache_not_logged_in = FALSE;  // ログインユーザーにはキャッシュを返さない

// .htaccess で mod_rewrite によるキャッシュ配信を設定
// (WP Super Cache が自動生成するが手動で確認)
# Apache mod_rewrite キャッシュルール確認
grep -A 30 "WP Super Cache" /var/www/html/.htaccess

# キャッシュファイルが生成されているか確認
ls -la /var/www/html/wp-content/cache/supercache/
find /var/www/html/wp-content/cache/supercache/ -name "*.html" | wc -l

ステップ2:CDNへのトラフィック分散

Cloudflareを使って静的アセットとページキャッシュをエッジで配信します。

# Cloudflare APIを使ってキャッシュルールを設定
CLOUDFLARE_TOKEN="your_api_token"
ZONE_ID="your_zone_id"

# 静的ファイルのキャッシュルールを作成
curl -X POST \
  "https://api.cloudflare.com/client/v4/zones/${ZONE_ID}/cache/rules" \
  -H "Authorization: Bearer ${CLOUDFLARE_TOKEN}" \
  -H "Content-Type: application/json" \
  -d '{
    "rules": [{
      "expression": "(http.request.uri.path matches \"\\.(css|js|png|jpg|gif|ico|woff2)$\")",
      "action": "set_cache_settings",
      "action_parameters": {
        "cache": true,
        "edge_ttl": {
          "mode": "override_origin",
          "default": 86400
        },
        "browser_ttl": {
          "mode": "override_origin",
          "default": 3600
        }
      }
    }]
  }'

# WordPress の wp-config.php でCDN URLを設定
# define('WP_CONTENT_URL', 'https://cdn.example.com/wp-content');

ステップ3:ProxySQLによるデータベース接続プール

高トラフィック時のDB接続枯渇をProxySQLで解決します。

# ProxySQL のインストール(Ubuntu)
wget https://github.com/sysown/proxysql/releases/download/v2.5.5/proxysql_2.5.5-ubuntu22_amd64.deb
sudo dpkg -i proxysql_2.5.5-ubuntu22_amd64.deb
sudo systemctl start proxysql

# ProxySQL Admin に接続して設定
mysql -u admin -padmin -h 127.0.0.1 -P 6032 << 'EOF'
-- バックエンドのMySQLサーバーを追加
INSERT INTO mysql_servers (hostgroup_id, hostname, port, max_connections)
VALUES (10, '127.0.0.1', 3306, 200);

-- 読み取りグループの設定
INSERT INTO mysql_servers (hostgroup_id, hostname, port, max_connections)
VALUES (20, '192.168.1.20', 3306, 400);  -- レプリカ

-- 接続プールの設定
UPDATE global_variables
SET variable_value = '100'
WHERE variable_name = 'mysql-max_connections';

UPDATE global_variables
SET variable_value = '3000'
WHERE variable_name = 'mysql-connection_max_age_ms';

-- 設定を適用
LOAD MYSQL SERVERS TO RUNTIME;
SAVE MYSQL SERVERS TO DISK;
LOAD MYSQL VARIABLES TO RUNTIME;
SAVE MYSQL VARIABLES TO DISK;
EOF

# wp-config.php の DB_HOST を ProxySQL に向ける
# define('DB_HOST', '127.0.0.1:6033');  // ProxySQLのポートは6033

ステップ4:PHPプロセスとサーバーのオートスケール設定

PHP-FPMのプロセス数を動的に調整してスパイクに対応します。

# /etc/php/8.2/fpm/pool.d/www.conf の設定
[www]
pm = dynamic
pm.max_children        = 100   # 最大プロセス数
pm.start_servers       = 20    # 起動時プロセス数
pm.min_spare_servers   = 10    # 最小待機プロセス数
pm.max_spare_servers   = 40    # 最大待機プロセス数
pm.process_idle_timeout = 30s  # アイドルタイムアウト
pm.max_requests        = 500   # 各プロセスの最大リクエスト数(メモリリーク対策)

# nginx のワーカー設定
# /etc/nginx/nginx.conf
worker_processes        auto;  # CPUコア数に合わせる
worker_rlimit_nofile    65535;
events {
    worker_connections  4096;
    use                 epoll;
    multi_accept        on;
}

# 設定反映
sudo php-fpm8.2 -t && sudo systemctl reload php8.2-fpm
sudo nginx -t && sudo systemctl reload nginx

ステップ5:過負荷時のメンテナンスモード設定

緊急時にWordPressをメンテナンスモードに切り替えて管理者だけが操作できるようにします。

<?php
// mu-plugins/emergency-maintenance.php

/**
 * 緊急メンテナンスモード
 * 環境変数 WP_MAINTENANCE=true でアクティブ化
 */
add_action( 'init', function () {
    // 環境変数でメンテナンスモードを制御
    if ( 'true' !== getenv( 'WP_MAINTENANCE' ) ) {
        return;
    }

    // 管理者とローカルIPは通過させる
    $allowed_ips = [ '127.0.0.1', '::1', '203.0.113.10' ]; // 管理者のIP
    $client_ip   = $_SERVER['REMOTE_ADDR'] ?? '';

    if ( in_array( $client_ip, $allowed_ips, true ) ) {
        return;
    }

    // ログイン済み管理者は通過
    if ( function_exists( 'is_user_logged_in' ) && is_user_logged_in() ) {
        $user = wp_get_current_user();
        if ( in_array( 'administrator', (array) $user->roles, true ) ) {
            return;
        }
    }

    // 503 メンテナンスページを返す
    http_response_code( 503 );
    header( 'Retry-After: 3600' );
    header( 'Content-Type: text/html; charset=UTF-8' );

    echo '<!DOCTYPE html><html lang="ja"><head><meta charset="UTF-8">';
    echo '<title>メンテナンス中</title></head><body>';
    echo '<h1>只今メンテナンス中です</h1>';
    echo '<p>大変ご不便をおかけします。しばらくお待ちください。</p>';
    echo '</body></html>';
    exit;
} );

// メンテナンスモードの有効化コマンド(WP-CLI)
// export WP_MAINTENANCE=true && sudo systemctl reload php8.2-fpm

注意事項

  • WP Super CacheのSuper Cacheモード(mod_rewrite)はPHPを経由しないため最速だが、設定ミスでキャッシュが効かない場合がある。curl -I https://example.com/ | grep X-Cache でキャッシュヒットを確認すること
  • ProxySQLのmax_connectionsはMySQLのmax_connections以下に設定すること。ProxySQL側で多すぎる接続を許可するとMySQL側でエラーが発生する
  • オートスケーリング(AWS Auto Scaling等)を使う場合、WordPressのファイルシステムを共有ストレージ(EFS等)に移行しないと各ノードでファイルの不整合が発生する
  • PHPのメモリ制限(memory_limit)を超えるプロセスは即時強制終了されるため、スパイク時にmemory_limit = 256M以上に設定することを検討する
  • CloudflareのキャッシュはデフォルトでHTMLページをキャッシュしない。「Cache Level: Cache Everything」ページルールを設定する際はログインページ等の除外設定を忘れずに行う

まとめ

トラフィックスパイクへの対応は「キャッシュ→CDN→接続プール→スケールアウト」の順で段階的に実施することで、コストを抑えながら効果を最大化できます。日頃からの監視については「New Relic APMでWordPressのパフォーマンスを監視する方法」を、CDNの選定については「WordPressに最適なCDNを選ぶ方法」も参照してください。

お気軽にご相談ください

お見積りへ お問い合わせへ