ソースデータ
- このプロジェクトでは、同じデータセンターにある10台のサーバーを使用しています。 nginx、PHP、MySQLを搭載したサーバー。 本格的なメールサーバーや言及に値するその他のサービスがない場合。
- このサイトの1日あたりのページビューは350万を超えています。
- 画像リクエストを除く、nginxへの1日あたり1,200万を超えるリクエスト。 それらの1/4はPHPに送られます。
- nginxからの1日あたり250 GBを超えるトラフィック(画像を除く)。
- データセンターでのサーバー復旧の予備期限は数日以上です。
失敗時には、次のものがありました。
- 1台のバックアップサーバー。
- サイトのカスタマイズバージョン。 バックアップのためにサイトを時々チェックしました。
- MySQLレプリケーションを使用したデータベースのコピー。
- ファイルのコピー。 監視によると、監視の遅れは20分を超えませんでした。
- SOA DNSゾーンレコードを構成し、ほぼすべてのユーザーがDNSゾーン設定を変更できるように1時間近く許可しました。
問題と解決策
失敗後、2つの方向に進むことにしました。
- サイトを既存の読み取り専用サーバーに復元し、すべてと「永久に」キャッシュします。
- 別のデータセンターの新しいサーバーを注文して、サイトを完全に復元します。
メインサーバーまたは複数のサーバーに同時に障害が発生したと想定しました。 しかし、彼らは長期的には10台のサーバーがすべてなくなる可能性は低いと考えていました。 以下は考慮に入れなかったものです。
- バックアップサーバーの作業設定は、メインサーバーのように定期的に更新されませんでしたが、それらはすべてリポジトリに保存されます。 その結果、エラーのあるURLの一部を取得し、一部のページがキャッシュされませんでした。
- キャッシュ。 10の代わりにキャッシュなしで1-nサーバーへの訪問者を許可することは、彼にとって「致命的」です。 特に前の段落と併せて。
- 切り替えの過程で、プロジェクト自体が読み取り専用モードに完全には対応していないことが判明する場合があります。 すでにキャッシュ内にあるページを修正する必要があり、開発者が修正した後、キャッシュをクリーンアップする必要があります。 そのような困難を伴って作成されたキャッシュ全体を削除することに同意しないでください。 ますます多くのユーザーが新しいIPを取得し、サイトへの訪問者の数は増え続けています。 DNSを変更した後、1時間後にキャッシュをクリーニングし、サーバーを配置します。
- 1日に複数の強力な専用サーバーを取得できるデータセンターは見つかりませんでした。 すべてのバックアップがある場合でも、事前にこれを処理しないと、サイトの完全な復元をすぐに開始できません。
これはすべて事前に行うことができ、事実に基づいて行動することを余儀なくされました。
最初の段落では、ソリューションのログを分析し、構成ファイルを読み取り専用モード用に編集しました。 すなわち:
- ログインできないという文化的なメッセージをユーザーに伝えました。
- ユーザーがPHPにアクセスできないように、nginxレベルでレコード上のコメントやその他のアクションを停止しました。
- 必要な場所でreturn 503とerror_page 503 = /trouble.htmlを使用しました 。
- 他のすべてのページをキャッシュするバグも修正されました。
2番目と3番目の段落で、次の決定が行われました。 IPが優先であることを確認し、504エラーではなく各リクエストがキャッシュにページを作成し、必要に応じて更新することを保証します。 nginxのパフォーマンスを心配することなく、少なくとも少しサイトを復活させる必要があったため、他の訪問者をバイパスしてキャッシュを生成するためにEvil Ifを使用しました。
この場合、次のようになりました。
fastcgi_pass unix:/var/run/php-fpm/fpm-all.sock; if ( $remote_addr = 8.8.8.8 ) { #if ( $remote_addr ~ (8.8.8.8|127.0.0.1) ) { # fastcgi_pass unix:/var/run/php-fpm/fpm-private.sock; # #set $nocache 1; #fastcgi_cache_bypass $nocache; }
8.8.8.8の代わりに、IPを使用します。
さらに、2つのPHP-FPM プールがありました : fpm- private-私たちにとってはfpm-all-残りのためです。 キャッシュを更新するために、 fastcgi_cache_bypassディレクティブが使用されました 。
キャッシュを作成するために、 wget -r -l0 -np-example.comを実行しました。 キャッシュを更新するために、$ nocacheで行のコメントを外しました。 したがって、キャッシュを生成し、必要に応じてIPからキャッシュを更新する機能を備えた作業サイトを取得しました。 数時間の操作の後、すでに数十ギガバイトのキャッシュがありました。
サーバー設定の最適化の問題についてはほとんど触れていません。そのようなトピックについては、別の記事で詳しく説明しています。 この場合、データベースクエリは読み取り専用であったため、MySQLの最適化は簡単でした-データベースはボトルネックではありませんでした。 nginxの構成は、すべての接続を処理するためのタイムアウトとバッファーの調整に落ちました。 画像をアップロードするための追加のサーバーがなくなったため、ネットワークに大きな負荷がかかりました。 弱点はPHPでした。 大きなキャッシュを生成した後でも、PHP-FPMにキューがあるため、20秒間ページが生成されました。
最後の点に関して-新しいサーバーの検索。 この問題を迅速に解決することはできませんでした。 データセンターは、最大コアi3-i7特性と1〜2日間の8GBのRAMを備えたサーバーのみを提供でき、より強力なサーバーはさらに長く待たなければならず、さらに契約を締結してサーバーの料金を支払う必要がありました。 3日間でホットリザーブ用の4つの強力なサーバーを取得することに合意したデータセンターを見つけました。 現在、これらのサーバーはサイトにとって機能するのに十分であり、私たちにとって重要ではないいくつかの重いモジュールはありません。 必要に応じて、別のデータセンターで作業するように切り替えることができます。
バックアップサーバーの問題の解決策は、プライマリに問題が発生した場合の追加サーバーの提供に関するバックアップデータセンターとの予備合意です。 さらに賢く、サイトを複数のデータセンターに拡張することもできます。
まとめ
- バックアップなしでは生きていけないので、監視や手などで定期的にチェックする必要があります。 特に注意する必要はありません。
- バックアップサーバーの検証は完全に行われる必要があります。 私たちの場合、同様の状況を予測していなかったため、十分な負荷テストがありませんでした。
- バックアップサーバーが1つしかない場合は、すぐに構成して、実際の負荷がかかっている制限モードでも動作するようにします。
- プロジェクトチームまたはアーキテクトおよび管理者との最も起こりそうにない状況(爆発、火災、突然サーバーにアクセスできなくなったときのデータセンター内のその他の状況)をモデル化する時間を取ります。 分析とその結果、そのようなケースの文書化、および動作のテストによる構成ファイルの準備により、考えられるほとんどの障害が修正されます。 その後、UFOがサーバーに到着しても、これを予期していなかったとは言わず、プロジェクトを復元できます:);
- 私たちの場合、サイトは1時間強の間完全に利用できませんでした。 さらに数時間作業が中断されました。 このような状況に備えておくと、DNSレコードの更新に1時間を費やして、最初の訪問者に対応するためのキャッシュを生成できます。将来的には、負荷が大きく下がらないようにします。
私たちの場合、データセンターは1日以上後に作業を復元しました。 読み取り専用モードで作業していたため、データを戻す必要はありませんでした。 サーバーを確認した後、ドメインを戻しました。
サーバーへのアクセスが無期限に失われ、バックアップがある場合の困難な瞬間に私の経験があなたに役立つことを願っていますが、別のデータセンターにはバックアップクラスターはありません。 コメントをお寄せいただければ幸いです。そのような状況でどのように行動しますか?