ホームページ  >  記事  >  コンピューターのチュートリアル  >  システムは壊れています。コードは認識するだけで、人は認識しません。

システムは壊れています。コードは認識するだけで、人は認識しません。

王林
王林転載
2024-02-19 10:51:24797ブラウズ

システムは壊れています。コードは認識するだけで、人は認識しません。

親愛なる皆さん、私のアドバイスを聞いて、内部システム コール、外部システム コール、またはパッシブ トリガー コール (たとえば、 MQ の消費、コールバックの実行など)、必要な条件チェックを必ず追加してください。この状態は間違いなく送信される、間違いなく値がある、間違いなく空ではないなどと言う一部の同僚を信じないでください。いや、旧正月直前に騙されて生産事故を起こしてしまい、年末ボーナスが実質半額になってしまいました。

システムの高い可用性と安定性を確保するために、人ではなくコード自体に焦点を当てることにしました。ここでは、あなたにも役立つかもしれないいくつかの小さなレッスンを紹介します。

1.何が起こったのか

私のビジネス シナリオは次のとおりです。ビジネス A が変更されると、MQ メッセージの送信がトリガーされ、アプリケーションは MQ メッセージを受信し、処理後にデータを Elasticsearch に書き込みます。

(1) A社から異常アラームを受信しました。その時のアラームは以下の通りです。

(2) 一見すると少し奇妙に思えますが、どうしてこれが Redis の例外になるのでしょうか?その後、Redis に接続しましたが、問題はありませんでした。Redis クラスターを再度確認したところ、すべてが正常でした。それで、偶発的なネットワークの問題だと思って放置しました。

その後、技術的な問題グループで、一部のユーザーに異常な状況が発生しているとカスタマー サービスから報告があり、すぐにシステムをチェックして散発的な問題の存在を確認しました。

(4) そこで、習慣に従っていくつかのコアコンポーネントを調べてみました。

ゲートウェイのステータス、コア ビジネス Pod の負荷ステータス、およびユーザー センター Pod の負荷ステータス。
  • Mysql の状況: メモリ、CPU、遅い SQL、デッドロック、接続数など。
  • SQL の速度が遅く、メタデータのロック時間が長いことが判明しました。これは主に、大きなテーブルの全テーブル クエリによって引き起こされる大量のデータと実行速度の遅さが原因であり、その結果、メタデータ ロックも長引く原因となっていました。データベース接続の数。
リーリー

(6) いくつかの遅いセッションをすぐに強制終了した後、システムがまだ完全に復元されていないことがわかりました。なぜですか?データベースは正常になっているのに、なぜ完全に復元されていないのでしょうか?引き続きアプリケーション監視を見てみると、ユーザーセンターにある10台のPodのうち2台が異常で、CPUとメモリが枯渇していることが分かりました。使用中に時々異常が発生するのも不思議ではありません。そこで、すぐにポッドを再起動し、最初にアプリケーションを復元しました。

(7) 問題が見つかったので、ユーザー センターのポッドがハングアップした原因を引き続き調査します。次の疑問点から分析を開始してください:

Elasticsearch にデータを同期するコードに何か問題がありますか? Redis に接続できないのはなぜですか?
  • 例外が多すぎるため、例外アラーム メッセージを送信するためのスレッド プール キューがいっぱいになり、OOM が発生する可能性がありますか?
  • ビジネス A の大きなテーブルに対して無条件の完全なテーブル クエリをどこで実行できますか?
  • (8) 疑わしい点の調査を続ける a. 最初は、Redis 接続が取得できず、スレッド プールのキューに例外が入り、キューがバーストして OOM が発生したのではないかと考えました。この考えに従って、コードを変更し、アップグレードし、観察を続けましたが、同じように SQL とユーザー センターの爆発が遅くなりました。異常はないので、疑い点bも除外できます。

(9) この時点で、C の疑いがあることはほぼ確実ですが、業務 A の大きなテーブルに対するフルテーブルクエリが呼び出され、ユーザー センターのメモリが過大になり、JVM がリサイクルする時間がなく、CPU を直接爆発させます。同時に、テーブル全体のデータが大きすぎるため、クエリ中のメタデータのロック時間が長すぎ、接続の解放が間に合わず、最終的にはほぼ枯渇してしまいます。

(10) そこで、ビジネス A の大きなテーブルをクエリするために必要な検証条件を変更し、オンライン観察用に再展開しました。最終的な位置決めに問題があった。

2. 問題の原因

業務テーブルBを変更する場合、MQメッセージの送信(業務テーブルAのデータをESに同期)する必要があるため、MQメッセージを受信後、業務テーブルAに関するデータを問い合わせて同期を行う必要があります。データを Elasticsearch に送信します。

しかし、業務テーブルBを変更する際、業務テーブルAに必要な必要条件が無く、必要条件の検証も怠ったため、業務Aの大きなテーブルをフルテーブルスキャンすることになりました。なぜなら:### リーリー

当時ビジネス B のテーブルが頻繁に変更されていたため、より多くの MQ メッセージが送信および消費され、ビジネス A の大きなテーブルのフル テーブル スキャンがさらにトリガーされ、その結果、Mysql メタデータのロック時間が長くなりました。長すぎるため、最後の接続でデータが過剰に消費されます。

同時に、業務 A の大規模なテーブル クエリの結果は毎回ユーザー センターのメモリに返されるため、JVM ガベージ コレクションがトリガーされますが、リサイクルすることはできません。疲れ果てています。

Redis が接続を取得できない例外については、単なる煙爆弾であり、送信および消費される MQ イベントが多すぎるため、少数のスレッドがすぐに Redis 接続を取得できません。

最後に、MQ イベントを消費するコードに条件検証を追加し、クエリ ビジネス A テーブルにも必要な条件検証を追加してオンラインに再デプロイし、問題を解決しました。

3. レッスンを要約する

この事件の後、私もいくつかの教訓をまとめて皆さんと共有しました:

(1) オンラインの問題には常に注意を払い、問題が発生したら放置せず、すぐに調査してください。ほとんどの問題はネットワークとは何の関係もありません。

(2) 大規模なビジネス テーブル自体を保護する必要があり、クエリに必要な条件検証を追加する必要があります。

(3) MQ メッセージを使用するときは、必要な条件を確認する必要があり、情報ソースを信頼しないでください。

(4) 「この状態は必ず伝わる、必ず価値がある、絶対に空ではない」などと言う同僚の言葉を決して信じないでください。システムの高可用性と安定性を確保するために、人ではなくコードのみを認識します。

(5) 問題が発生した場合の一般的なトラブルシューティング手順:

CPU、デッドロック、データベースの SQL が遅い。

    CPU、メモリ、アプリケーションのゲートウェイとコア コンポーネントのログ。
  • (6) ビジネスの可観測性とアラームは不可欠であり、問​​題をより迅速に発見して解決できるように包括的である必要があります。

以上がシステムは壊れています。コードは認識するだけで、人は認識しません。の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はmryunwei.comで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。