独立サイトの負荷分散:マルチインスタンス構成、ヘルスチェック、セッション維持、フェイルオーバー
1. 負荷分散が必要なとき、過剰設計になるとき
負荷分散は最初から導入すべきものではありません。日次アクセスが5000以内なら、2コア4GのVPS1台でNginx+PHP+MySQLを動かせば十分で、数百元でLBを買うと複雑さが増すだけです。マルチインスタンスが本当に必要なシグナルは3つあります。単一マシンのCPUが長期的に60%を超える、リリース時に必ず停止が必要、単一障害で問い合わせを失ったことがある。このうち2つに当てはまったら、LBを導入しましょう。
独立サイトの典型的なアップグレード経路は、単一VPSでcomposeを動かす(日次1万以内)→ MySQLを別マシンに分離(日次3万)→ アプリを2台+クラウドLBで動かす(日次5万)→ アプリ3〜5台+自動スケーリング(日次20万以上)です。ステップを飛ばさないでください。CDNはLBより先に静的トラフィックを受け止め、オリジンサーバーの負荷を半分に減らせます。詳しくはCDNグローバル高速化。
| フェーズ | デプロイ形態 | アプリインスタンス数 | 日次アクセスの目安 | 月額コスト増分 |
|---|---|---|---|---|
| 立ち上げ期 | 単一VPS+compose | 1 | 1万未満 | 0 |
| 成長期 | アプリ1台+DB独立1台 | 1 | 1万〜5万 | +150円 |
| 安定期 | アプリ2台+クラウドLB | 2 | 5万〜20万 | +LB費用約100元 |
| ピーク時 | アプリ3〜5台+自動スケーリング | 3至5 | 20万超 | +時間単位の課金 |
2. L4かL7か:独立サイトはどの層を選ぶか
負荷分散は4層(L4、TCP/IPで転送)と7層(L7、HTTPパスで転送)に分かれます。L4は性能が高く設定も簡単ですが、ポート単位の転送しかできません。L7はドメイン、パス、Headerに基づいてルーティングでき、カナリアリリースやHTTPSオフロードも可能です。独立サイトはL7を選びましょう。パスごとに振り分ける必要があるからです。静的ファイルはCDN、APIはアプリ、管理画面は別のインスタンス群へ。
クラウド各社のLB選び:AWSはALB(Application Load Balancer)、Alibaba CloudはSLBまたはALB、Tencent CloudはCLB。機能は重なり合い、料金は月100〜200元から。判断基準はひとつ。要件が「2台のマシンを順番に回す」だけなら最安のL4 LBを選ぶ。パスによるルーティング、カナリアリリース、ドメイン別の振り分けが必要ならL7 LBを選ぶ。
| 比較項目 | L4 TCPロードバランシング | L7 HTTPロードバランシング |
|---|---|---|
| 振り分けの基準 | IP+ポート | ドメイン/パス/Header/Cookie |
| パフォーマンス | 非常に高い、マイクロ秒級 | やや低い、ミリ秒級 |
| HTTPSのオフロード | 非対応 | 対応、証明書はLBに配置 |
| カナリアリリース | トラフィック比率では不可 | 重み付けでトラフィックを切替可能 |
| 独立サイトでの適用 | シンプルな2台の順番回し | マルチパスルーティング、カナリア |
| 月額の目安 | 約80〜120元 | 約150〜250元 |
三、ヘルスチェック:誤検知で切り離さないための設定
ヘルスチェックはLBの要です。緩すぎると落ちたマシンがトラフィックを受け続け、厳しすぎると起動が少し遅いだけで誤って切り離され、雪崩を引き起こします。独立サイトの標準設定は、チェックパスを/health(200のみ返し、DBは見ない。DBの遅延をLBに伝染させないため)、間隔10秒、3回連続失敗で切り離し、2回連続成功で復帰です。
/healthは軽量でなければなりません。よくある誤りはMySQL接続を1回確認させることで、DBが揺らぐと全アプリインスタンスがLBから外れ、サイト全体が503になります。正しい方法は、/healthはプロセスの生存状態だけを返し、DBの健全性は独立した/health/dbで確認し、監視のみで切り離しの判断には使わないことです。監視アラートのしきい値は次を参照サイト監視とアラート。
| パラメータ | 推奨値 | 説明 | よくある誤り |
|---|---|---|---|
| チェックパス | GET /health | DBを見ず200のみ返す | DBを見て全台切り離し |
| チェック間隔 | 10秒 | 感度と誤検知のバランス | 1秒は攻めすぎ |
| タイムアウト | 5秒 | 超えると1回失敗 | 1秒は短すぎ |
| 不健全のしきい値 | 3回連続失敗 | ノードを切り離し | 1回失敗で切り離し |
| 健全なしきい値 | 2回連続成功 | 復帰キュー | 1回成功で復帰 |
| レスポンスコード | 200は健全 | その他は失敗 | 503を健全扱い |
四、セッション維持:できるだけオフにする
多くの人が初めてマルチインスタンスを組むとき、まず「ユーザーがA機でログインして、次のリクエストがB機に届いたらログアウトするのでは」と考え、セッション維持をオンにします。これは短期は楽でも長期でツケが回るやり方です。セッション維持の問題は、A機が落ちるとA機に張り付いた全ユーザーがログアウトし、フェイルオーバーの意味が半減することです。
正しい方法は、セッションをアプリのメモリから外に出すことです。PHPはRedisにsessionを保存し、NodeはJWTのステートレストークンを使い、ログイン状態をすべて共有ストレージに集約します。こうすればどのアプリインスタンスでもどのユーザーのリクエストを処理でき、どれか1台が落ちてもオンラインユーザーに影響しません。セッション維持をオンにするのは、古いシステムを変えられない、またはサードパーティプラグインがローカルsessionに強く依存している、の2つの場合だけです。
| セッション方式 | 拡張性 | 障害時の影響 | 移行コスト | 推奨度 |
|---|---|---|---|---|
| ローカルファイルsession | 悪い、stickyが必須 | 1台停止=ユーザーログアウト | 低 | 非推奨 |
| Redisでsessionを一元管理 | 良い | 無停止で切替 | 中、設定変更で対応 | 推奨 |
| JWTステートレスtoken | 最適 | 無停止で切替 | 高、認証の改修が必要 | 新規プロジェクトに推奨 |
| LB cookieスティッキー | 悪い例 | 固定されたマシンが落ちると切断 | 低、スイッチを入れるだけ | 一時的な移行のみ |
五、フェイルオーバー:LBが本当に切り替わるか検証する方法
LBを設定しただけではフェイルオーバーは機能しません。多くのチームは稼働後に一度もマシンを止めてみないまま、本当に落ちて初めてLBにヘルスチェックが設定されていない、セキュリティグループが開放されていないと気づきます。稼働前に必ず一度、能動的な障害訓練を行ってください。本番環境(またはステージング)でアプリAを手動で停止し、LBが30秒以内にトラフィックをBへ切り替えるか、ユーザーのリクエストが違和感なく処理されるかを確認します。
もう一つのよくある落とし穴は、2台のアプリインスタンスが同じ物理マシンや同じ電源ラックにあることです。ラック全体の停電で2台とも落ちます。少なくとも2つのアベイラビリティゾーン(AZ)にまたがって配置するか、最低でも2台の異なるホストに分けてください。バックアップと復旧訓練の完全な方法論はこちらサイトのバックアップと復元演習。
事例:あるB2Bサイトは当初1台のVPSでWordPressを運用していました。ある未明にホストのメンテナンスで停電し、サイトが4時間ダウン、その間にヨーロッパの顧客からの問い合わせを3件逃しました。その後、2台目のアプリインスタンスをクラウドLBに接続し、sessionをRedisに移し、アベイラビリティゾーンをまたいで配置しました。次のメンテナンス時間には、インスタンスBが自動的に全トラフィックを引き継ぎ、顧客も営業も気づきませんでした。月300元のインスタンス費用は、一度のダウンで失う問い合わせの価値よりはるかに安いのです。
| 訓練シナリオ | 操作 | 期待結果 | 基準を満たさない場合の対応 |
|---|---|---|---|
| アプリプロセスを停止 | systemctl stop app | 30秒以内にLBが切り離し、トラフィックをBへ | ヘルスチェックパスを確認 |
| アプリのネットワークを遮断 | iptablesでポートをブロック | 10秒以内に切り離し | セキュリティグループでLBの網段を開放しているか確認 |
| マシンを再起動 | reboot | 起動後に自動でキューへ復帰 | 起動スクリプトとhealthを確認 |
| データベースの揺らぎ | スロークエリを注入 | アプリが誤って切り離されない | healthでDBを確認してはいけない |
| 全トラフィックをBへ | 重みをBに100設定 | Bが単独で5分間耐える | Bの処理能力を負荷テスト |
FAQ よくある質問
1日の訪問数がいくつならロードバランサーが必要?
セッション維持は結局必要か?
ヘルスチェックでデータベースを確認してはいけないのはなぜ?
2台のインスタンスを同じ物理マシンに置いてもいいですか?
クラウド事業者のLBの月額はいくらですか?
フェイルオーバーが本当に機能しているか、どう確認しますか?
最後に
独立系サイトにとってのロードバランサーの価値は、半分はトラフィックをさばくこと、もう半分は障害をさばくことです。前者は多くの人が計算できますが、後者は見落とされがちです。アプリインスタンスを1台増やすコストで、「1台落ちてもユーザーは気づかない」状態を買える。これはB2Bの問い合わせ獲得の場面では、そのままお金になります。
実装は3ステップ。まずアプリをステートレス化し、セッションをRedisへ移します。次に2台目のインスタンスを立ち上げ、クラウドLBの背後にぶら下げ、ヘルスチェックを設定します。最後にプロセスをkillする演習を1回行い、30秒以内にトラフィックが切り替わることを確認します。この3ステップを終えて、初めてマルチインスタンス構成が実用になります。関連する監視アラートはサイト監視とアラート、自動スケーリングの応用は自動スケーリング。
覚えておきたい一言。ロードバランサーの意味は負荷分散ではなく、どのマシンが落ちてもユーザーも問い合わせも気づかないようにすることです。
