インタビュアー: パフォーマンス テストのボトルネック調整は本当に得意ですか?

はじめに: パフォーマンスのボトルネックのチューニング

実際の性能テストでは、TPS が圧力を上げられないなど、さまざまな問題が発生しますが、その原因はさまざまですので、テスターは開発者と協力して、できるだけ早くボトルネックを分析し、特定する必要があります。

理想的性能测试指标结果可能不是很高,但一定是平缓的。

パフォーマンス調整の手順

  1. 問題の特定: パフォーマンス監視データとパフォーマンス分析の結果に基づいて、パフォーマンスの問題を特定します。

  2. 原因の特定: 問題を特定した後、問題を分析して問題の原因を特定します。

  3. 解決策を決定します (サーバーパラメータ構成の変更/ハードウェアリソース構成の追加/コードの変更)。

  4. ソリューションを検証し、調整結果を分析します。

注: パフォーマンス テストのチューニングは 1 回限りのプロセスではありません。同じパフォーマンスの問題に対して、最終的にパフォーマンス チューニングの目標を完了するまで、上記の手順を複数のサイクルを繰り返す必要がある場合があります。つまり、テストで問題を見つけ、> 問題を見つけます。原因 -> 調整 -> 検証 -> 分析 -> 再度テスト...

パフォーマンスのボトルネック確率分布

60%: データベースのボトルネック

  • データベース サーバーの CPU 使用率が高い (クエリが遅い、SQL が多すぎる、接続が多すぎる)
  • スローされる接続が多すぎます (接続プールの設定が小さすぎるため、接続がキューに入れられます)
  • データベースでデッドロックが発生する

25%: アプリケーションのボトルネック

  • アプリケーションのメモリリーク
  • アプリケーションでスレッド競合/デッドロックが発生する
  • プログラムコードのアルゴリズムの複雑さ
  • ミドルウェアやサードパーティアプリケーションに異常が発生する
  • 計算負荷の高いタスクは CPU 負荷を高める
  • 高い I/O 負荷を引き起こす I/O 集中型タスク

10%: 圧力測定ツールのボトルネック

  • JMeter には単一マシンの負荷容量が限られているため、シミュレートする必要があるユーザー リクエストの数がその負荷制限を超えると、TPS は対応できなくなります。

5%: Linux マシンが異常です

  • Linux の空きメモリを再利用できません (オーバーヘッド レートが再利用レートよりも大きい)
     

システムリソース

画像

  • CPU

    • 監視内容:CPU使用率、CPU使用率の種類(ユーザープロセス、カーネルプロセス)
    • ボトルネック分析: CPU がいっぱい (ほぼ 100%) CPU がいっぱいになると同時に他の指標の変曲点が現れるかどうかを確認する必要があります。
  • メモリ

    • 監視内容:実メモリ、仮想メモリ
    • ボトルネック分析: メモリが不足すると、オペレーティング システムは仮想メモリを使用し、仮想メモリからデータを読み取るため、処理速度に影響します。
  • 磁盘 I/O

    • 監視内容:I/O速度、ディスク待機キュー
    • ボトルネック分析: ディスク I/O がボトルネックになると、ディスク I/O がビジーになり、実行中にトランザクションが I/O で待機するようになります。
  • 通信網

    • 監視内容:ネットワークトラフィック(帯域幅使用量)、ネットワーク接続ステータス
    • ボトルネック分析: インターフェイスによって送信されるデータ パケットが大きすぎて、帯域幅の送信容量を超える場合、ネットワーク リソースの競合が発生し、TPS が失敗する原因になります。

ボトルネックを発見したら、あとは適切な薬を処方するだけです。簡単に言えば、どこにボトルネックが発生しても、圧力を下げるかボトルネックのリソースを増やすだけで (アプリケーション ソフトウェアにボトルネックや最適化の余地がなくなった後)、症状は軽減されます。

  • CPU ボトルネック: CPU リソースを増やします。
  • メモリのボトルネック: メモリを増やしてキャッシュを解放します。
  • ディスク I/O ボトルネック: より高性能のディスク (ソリッド ステート SSD など) に交換します。
  • ネットワーク帯域幅のボトルネック。ネットワーク帯域幅を増加します。
     

CPU

バックグラウンド サービスのすべての命令とデータ処理は CPU によって処理され、サービスによる CPU の使用率はサービスのパフォーマンスに決定的な役割を果たします。

上位パラメータの詳細な説明

以下では、top コマンドの出力例を使用して、CPU の主なインジケーターを説明します。

画像

  • us(user): (優先順位のない) ユーザー プロセスの実行に費やされた CPU 時間の割合。

    • シェル プログラム、さまざまな言語のコンパイラ、データベース アプリケーション、Web サーバー、およびさまざまなデスクトップ アプリケーションはすべて、ユーザー アドレス空間で実行されるプロセスです。

    • これらのプログラムがアイドル状態でない場合、CPU 時間のほとんどはユーザー モードで実行されます。

  • sy(system): カーネル プロセスの実行に費やされた CPU 時間の割合。

    • プロセスによって使用されるすべてのシステム リソースは、Linux カーネルによって処理されます。ユーザー モード (ユーザー アドレス空間) のプロセスが、メモリの割り当て、I/O 操作の実行、子プロセスの作成など、システム リソースを使用する必要がある場合、カーネル モード (カーネル アドレス空間) の実行に入ります。実際、次の瞬間にプロセスを実行するかどうかを決定するプロセス スケジューラは、カーネル モードで実行されます。

    • オペレーティング システムの設計では、カーネル モードで費やす時間を可能な限り短くする必要があります。通常、sy 比率が高すぎる場合は、テスト対象のサービスがユーザー モードとシステム モードの間で頻繁に切り替わることを意味し、この時点でシステム全体のパフォーマンスがある程度低下します。

    • 在实践中有一类典型的情况会使 sy 变大,那就是大量的 I/O 操作,因此在调查 I/O 相关的问题时需要着重关注它。

    • 大部分后台服务使用的 CPU 时间片中 us 和 sy 的占用比例是最高的。同时这两个指标又是互相影响的,us 的比例高了,sy 的比例就低,反之亦然。

    • 另外,在使用多核 CPU 的服务器上,CPU 0 负责 CPU 各核间的调度,CPU 0 上的使用率过高会导致其他 CPU 核心之间的调度效率变低。因此测试过程中需要重点关注 CPU 0。

  • ni(niced): nice 重み付けとして使用されるプロセスに割り当てられたユーザー モード CPU 時間の割合。

    • Linux の各プロセスには優先度があり、優先度の高いプロセスが最初に実行する権利を持ち、これを pri と呼びます。プロセスには優先度の他に優先度補正値もあります。この補正値をプロセスのナイス値と呼びます。
    • ここで示されている ni は、nice 値が調整されたプロセスによって消費された CPU 時間を表します。システム内のどのプロセスも nice 値を調整していない場合、ni は 0 として表示されます。
    • 一般に、テストされたサービスとサーバー全体の ni 値はそれほど高くありません。テスト中に ni の値が比較的高い場合は、サーバーの Linux システム構成とテスト対象のサービスの実行パラメーターから理由を見つける必要があります。
  • id(idle): アイドル状態の CPU 時間の割合。

    • 一般に、us + ni + id は 100% に近いはずです。

    • オンライン サービスの運用中は、突然のトラフィックの急増に対処するために、ある程度の ID の冗長性を保持する必要があります。

    • パフォーマンス テスト中に、ID が常に非常に低く、スループットが向上しない場合は、テスト対象のサービスのスレッド/プロセス構成、サーバー システム構成などを確認する必要があります。

  • wa(I/O wait): CPU が I/O の完了を待機する時間の割合。

    • ディスク I/O 操作は、CPU の処理速度に比べて非常に遅いです。このような操作は数多くありますが、たとえば、CPU がディスクの読み取りおよび書き込み操作を開始した後、ディスクの読み取りおよび書き込み操作の結果を待つ必要があります。 CPU は、ディスクの読み取りおよび書き込み操作が完了するまでのみアイドル状態になれます。

    • Linux 系统在计算系统平均负载时会把 CPU 等待 I/O 操作的时间也计算进去,所以在我们看到系统平均负载过高时,可以通过 wa 来判断系统的性能瓶颈是不是过多的 I/O 操作造成的。

    • 磁盘、网络等 I/O 操作会导致 CPU 的 wa 指标提高。通常情况下,网络 I/O 占用的 wa 资源不会很高,而频繁的磁盘读写会导致 wa 激增。

    • テスト対象のサービスが I/O 集中型のサービスではない場合、テスト対象のサービスのログ量、データ読み込み頻度などを確認する必要があります。

    • wa が 10% を超えると、システムはフリーズし始めます。20% を超えると、システムはほとんど動かなくなります。50% を超えると、ディスクに障害が発生する可能性があります。

  • hi: ハード割り込みによって消費された時間の割合。

  • si: ソフト割り込みによって消費された時間の割合。

    • ハード割り込みは、ペリフェラルから CPU への割り込みであり、つまり、ペリフェラル ハードウェアによって CPU またはメモリに送信される非同期信号はハード割り込み信号であり、ソフト割り込みは、ソフトウェア自体によってオペレーティング システム カーネルに送信される割り込み信号です。
    • これは通常、ハード割り込みハンドラーまたはプロセス スケジューラーによるオペレーティング システム カーネルへの割り込みであり、これをシステム コールと呼ぶことがよくあります。
    • パフォーマンス テスト中、hi は一定の CPU 使用率を持ちますが、高すぎることはありません。 I/O 集中型のサービスの場合、si の CPU 使用率は高くなります。
  • st: 仮想マシンが CPU リソースを待機する時間。

    • st は、Linux が仮想マシンとして実行されている場合にのみ意味を持ちます。これは、仮想マシンが CPU リソースを待機する時間を表します (仮想マシンには仮想 CPU が割り当てられます。実 CPU が必要な場合、実 CPU は他の仮想マシンのタスクを実行している可能性があるため、待機する必要があります)。

事例分析

現象:ワとイド

  • wa (IO 待機) の値が高すぎます。これは、ハード ディスクに I/O ボトルネックがあることを示しています。

  • 高い ID (アイドル) 値は、CPU がアイドル状態であることを示します。

    • id 値が高くてもシステムの応答が遅い場合は、CPU がメモリ割り当てを待っている可能性がありますので、メモリ容量を増やす必要があります。

    • id 値が常に 10 未満である場合、システムの CPU 処理能力は比較的低く、システム内で最も要求の厳しいリソースが CPU であることを示しています。


現象: CPU の us と sy は高くありませんが、wa が非常に高いです。

テスト対象のサービスがディスク I/O を集中的に使用するサービスの場合、wa が高くても正常です。しかし、そのようなサービスではない場合、wa が高い理由として考えられるのは次の 2 つです。

  • このサービスには、ディスクの読み取りと書き込みのビジネス ロジックに問題があります。読み取りと書き込みの頻度が高すぎる、書き込まれるデータの量が多すぎる (無理なデータ読み込み戦略、ログが多すぎるなど)。問題。

  • サーバーのメモリが不足しており、サービスはスワップ パーティションに対して常にスワップインおよびスワップアウトされています。


現象: CPU 対スループット

  1. CPU 使用率が高くなく、スループットが低いため、開始されるサーバー側のスレッド プールが少なすぎる可能性があります。

  2. CPU 使用率が非常に高く、スループットが低く、サーバーの処理が遅く、データベースの操作が遅くなる可能性があります。

  3. 高い CPU 使用率と高いスループット:

    • サーバーには強力な処理能力があるため、CPU 使用率を減らすためにスレッド数を調整する必要があります。
    • データベース接続数、遅い SQL、ファイル ハンドルの最適化。
    • 物理的な装備を改善します。

負荷

Linux のシステム負荷とは、特定の時間間隔 (1 CPU サイクル) 中の実行キュー内のプロセスの平均数を指します。

(注: Linux の負荷はシステム全体の負荷、つまり CPU 負荷 + ディスク負荷 + ネットワーク負荷 + その他の周辺機器の負荷を反映します。これは CPU 使用率と完全に同等ではありません。Unix などの他のシステムでは、負荷は依然として CPU のみを表します。負荷。)

サーバー負荷の定義から、服务器运行最理想的状态是所有 CPU 核心的运行队列都为 1,即所有活动进程都在运行,没有等待。この状態ではサーバーが負荷しきい値以下で動作していることがわかります。

通常、経験によれば、サーバーの負荷はしきい値の 70% から 80% の間にある必要があり、これにより、トラフィックの増加に対処するためにある程度のパフォーマンスの冗長性を残しつつ、サーバーのパフォーマンスのほとんどを利用できるようになります。

システム負荷のしきい値を表示するコマンドは次のとおりです。

画像


Linux には、システム負荷を表示するためのコマンドが多数用意されています。最もよく使用されるのは top と uptime です。

トップとアップタイムの負荷に対する出力は両方とも同じです系统最近 1 分钟、5 分钟、15 分钟的负载均值:

画像

これら 3 つの値の使用法は CPU コアの数に関連しています。まず、物理 CPU コアの合計数を確認します。

  • /proc/cpuinfo のプロセッサの最大値は、必ずしも CPU のコア数であるとは限りません。CPU がハイパースレッディング テクノロジをサポートしている可能性があるため、プロセッサ数は物理コア数の 2 倍になります。

  • ここで正確なコア数が必要になります。具体的な方法は、/proc/cpuinfo ファイル内のすべての物理 ID の後の値を検索し、最大値を取得し、それに 1 を加算して実際の CPU 数を取得します。次に、任意のプロセッサの下の CPU コア (CPU のコア数) を見つけます。実際の CPU の数とコアの数を掛けたものが、CPU の物理コアの合計数となります。

例:

[root@localhost home]# cat /proc/cpuinfo |grep "physical id"
physical id     : 0
physical id     : 0
[root@localhost home]# cat /proc/cpuinfo |grep "cpu cores"
cpu cores       : 2
cpu cores       : 2

物理CPUの数は0+1=1、各CPUのコア数は2なので、物理コアの総数は2x1=2となります。

計算の結果、マシンが単位時間あたりに処理できる処理数は 2 です。単位時間あたりの処理数が 2 を超えると、輻輳が発生し、負荷は増加し続けます。 、システムクラッシュやその他の異常な状況が発生します。


パフォーマンステストにおいて、システム負荷はシステム全体の動作状態を評価するための最も重要な指標の 1 つです。いつもの:

  • 負荷テスト中: システム負荷はしきい値に近い値である必要がありますが、しきい値を超えてはなりません。

  • 同時テスト中: システム負荷はしきい値の 80% を超えることはできません。

  • 安定性をテストする場合: システム負荷はしきい値の約 50% である必要があります。


緊急時の機械対応

  • 1 分間の負荷が非常に高く、5 分間の負荷が比較的高く、15 分間の負荷があまり変動しない場合、高負荷は緊急であり許容できることを意味します。

  • 高負荷が続き、5分負荷、15分負荷が警報値を超えた場合は、この時点で対応を検討する必要があります。

  • 15 分間の負荷が 1 分間の負荷よりも高ければ、高負荷の状況が緩和されたことを意味します。
     

メモリ

パフォーマンス テスト中のメモリ監視の主な目的は、テスト対象のサービスが占有するメモリの変動を確認することです。

上位パラメータの詳細な説明

Linux システムには、指定したプロセスのメモリ使用量を取得できるコマンドが複数あります。最も一般的に使用されるのは、次の図に示すように、top コマンドです。

画像

  • VIRT: プロセスによって使用される仮想メモリの総量。 これには、すべてのコード、データ、共有ライブラリに加えて、スワップアウトされたページ、および申請されたすべての合計メモリ領域が含まれます。

  • RES: プロセスがスワップせずに使用している物理メモリ (スタック、ヒープ)。 メモリ セグメントはメモリの申請後に再割り当てされました。

  • SHR: プロセスによって使用される共有メモリの合計量。 この値は、他のプロセスと共有される可能性のあるメモリのみを反映しており、このメモリが現在他のプロセスによって使用されていることを意味するものではありません。

  • SWAP: スワップアウトされるプロセスによって使用される仮想メモリのサイズ。 交換されるのは、申請されたものの使用されていないスペース (スタック、ヒープ、共有メモリを含む) です。

  • DATA: 実行可能コードを除くプロセスの物理メモリの合計量、つまりプロセスのスタックとヒープによって要求される合計スペース。

上記の説明からわかるように、测试过程中主要监控 RES 和 VIRT。对于使用了共享内存的多进程架构服务,还需要监控 SHR。

フリーパラメータの詳しい説明

free コマンドは、物理メモリ、スワップ メモリ (スワップ)、カーネル バッファ メモリを含むシステム メモリの使用状況を表示します。 -h オプション (表示単位の制御) を追加すると、出力がより分かりやすくなります。

画像

メモリの状態を継続的に監視する必要がある場合があります。この場合、-s オプションを使用して間隔を秒単位で指定できます。たとえば、free -h -s 3 は、ctrl + c が入力されるまで 3 秒ごとにメモリ使用量を出力することを意味します。が押されます。

  • Mem 行: 物理メモリの使用量。

  • スワップライン: スワップスペースの使用量。

    • スワップ スペースはディスク上の領域であり、パーティションまたはファイルにすることができるため、特定の実装はスワップ パーティションまたはスワップ ファイルになります。システムの物理メモリが不足している場合、Linux はアクセス頻度の低いデータをスワップ用のメモリに保存し、システムが各プロセスに対応できる物理メモリを増やします。システムがスワップに格納されているコンテンツにアクセスする必要がある場合、システムはスワップ上のデータをスワップはメモリにロードされます。これは、スワップ アウトおよびスワップ インと呼ばれることがよくあります。

    • スワップ領域はメモリ不足の状況をある程度緩和できますが、ディスク データの読み書きが必要なため、パフォーマンスはあまり高くありません。したがって当交换空间内存开始使用,则表明内存严重不足

    • 如果系统内存充足或是做性能压测的机器,可以使用 swapoff -a 关闭交换空间,或在 /etc/sysctl.conf 文件中设置 swappiness 值。システム メモリが十分でない場合は、物理メモリのサイズに応じてスワップ領域のサイズを設定する必要がありますが、具体的な戦略についてはインターネット上に豊富な情報があります。

  • 合計列: システムの使用可能な物理メモリとスワップ領域のサイズの合計。

  • used 列: 使用された物理メモリとスワップ領域のサイズ。

  • 空き列: 利用可能な物理メモリとスワップ領域の量 (使用されていない物理メモリの実際の量)。

    • 在吞吐量固定的前提下,如果内存持续上涨,那么很有可能是被测服务存在明显的内存泄漏,需要使用 valgrind 等内存检查工具进行定位。
  • 共有列: 共有によって使用される物理メモリのサイズ。

  • バッファ/キャッシュ列: バッファとキャッシュによって使用される物理メモリのサイズ。

    • Linux 内核为了提升磁盘操作的性能,会消耗一部分空闲内存去缓存磁盘数据,就是 buffer 和 cache。

    • すべてのアプリケーションに十分なメモリが割り当てられており、物理メモリがまだ残っている場合、Linux はこの空きメモリを再利用して全体的な I/O 効率を向上させようと試みます。その方法は、この残りのメモリをキャッシュとバッファの 2 つの部分に分割することです。 . .

    • それで、空闲物理内存不多,不一定表示系统运行状态很差,因为内存的 cache 及 buffer 部分可以随时被重用,在某种意义上,这两部分内存也可以看作是额外的空闲内存。

  • available 列: アプリケーションがまだ使用できる物理メモリの量。

    • アプリケーションの観点から見るとavailable = free + buffer + cache。これはあくまで理想的な計算方法であり、実際のデータはさらに大きな誤差を伴うことが多いことに注意してください。

キャッシュメモリを解放する

方法 1: キャッシュ メモリを手動で解放する

snyc
echo 3 > /proc/sys/vm/drop_caches
free -m

方法 2: 自動的にリリースされるように Linux 構成を変更する

/proc/sys/vm/drop_caches 这个值的 0 改为 1

磁盘 I/O

パフォーマンス テスト中に、テスト対象のサービスによるディスクの読み取りと書き込みが頻繁に行われると、大量のリクエストが I/O 待ち状態になり、システムの負荷が増加し、応答時間が長くなり、スループットが低下します。減少します。

性能監視を行う際の留意点

  1. I/O 使用率: ディスクの実際の I/O が最大値に近いかどうか。近い場合は問題があります。

  2. I/O キュー: 現在の I/O キューの長さが 0 にならない場合は、問題が発生しています。

固态硬盘:500M/s
机械硬盘:不超过 200M/s

iostatパラメータの詳細な説明

iostat コマンドを使用して、Linux でディスクのステータスを監視できます。

iostat -d 2 10 は、基本データを 2 秒ごとに 10 回カウントすることを意味します。

画像

  • tps: デバイスの 1 秒あたりの送信数。 「転送」とは「I/O リクエスト」を意味します。複数の論理リクエストを「単一の I/O リクエスト」に組み合わせることができます。 「1 回の転送」リクエストのサイズは不明です。

  • kB_read/s: デバイス (driveexpressed) から読み取られた 1 秒あたりのデータ量 (キロバイト単位)。

  • kB_wrtn/s: デバイス (driveexpressed) に書き込まれる 1 秒あたりのデータ量 (キロバイト単位)。

  • kB_read: 読み取られたデータの合計量 (キロバイト単位)。

  • kB_wrtn: 書き込まれたデータの総量 (キロバイト単位)。

iostat -d の出力から、システム動作の最も基本的な統計データを取得できます。ただし、パフォーマンス テストの場合、これらのデータからはそれ以上の情報は得られません。 -x パラメータを追加する必要があります。

iostat -xパラメータの詳細な説明

たとえば、iostat -x 2 10 は、より詳細なデータを 2 秒ごとに 10 回カウントすることを意味します。

画像

  • rrqm/s: このデバイスに関連する読み取りリクエストが 1 秒あたりにマージされた数。

    • システム コールがデータを読み取る必要がある場合、VFS は各 FS にリクエストを送信し、異なる読み取りリクエストが同じブロックのデータを読み取っていることを FS が検出すると、FS はリクエストをマージします。
  • wrqm/s: このデバイスに関連する書き込みリクエストが 1 秒あたりにマージされた数。

  • await:各I/Oリクエストの平均処理時間(単位:ミリ秒)。

    • await のサイズは通常、サービス時間 (svtcm)、I/O キューの長さ、および I/O リクエストの発行パターンによって異なります。 svtcm が await に近いと仮定すると、I/O の待ち時間がほとんどないことになります。

    • 假设 await 远大于 svctm(如大于 5),就要考虑 I/O 有压力瓶颈,说明 I/O 队列太长,应用得到的响应时间变慢。応答時間がユーザーの許容できる時間を超えている場合は、ディスクをより高速なものに交換することを検討してください。

  • svctm: I/O 平均サービス時間。

  • %util: 統計時間中に I/O 操作に使用される割合。

    • たとえば、統計間隔が 1 秒で、デバイスが 0.8 秒間 I/O を処理し、0.2 秒間アイドル状態である場合、デバイスの %util = 0.8/1 = 80% となり、デバイスのビジー度を示します。

    • %util 接近100% 表明 I/O 请求太多,I/O 系统繁忙,磁盘可能存在瓶颈。

iostat -x 完整参数如下:

- rrqm/s: 每秒进行 merge 的读操作数目。即 delta(rerge)/s 
- wrqm/s: 每秒进行 merge 的写操作数目。即 delta(wmerge)/s 
- t/s: 每秒完成的读 I/O 设备次数。即 delta(rioVs 
- w/s: 每秒完成的写 1/O 设备次数。即 delta(wio)/s 
- rsec/s: 每秒读扇区数。即 delta(rsect)/s 
- ws0c/s: 每秒写扇区数。即 deita(wsect)/s 
- rkB/s: 每秒读 K 字节数。是 rsect/s 的一半,因为每扇区大小为 512 字节。(需要计算) 
- wkB/s: 每秒写 K 字节数。是 wsect/s 的一半。(需要计算) 
- avgrq+sz: 平均每次设备 I/O 操作的数据大小(扇区)。delta(rsect+wsect)/delta(rio+wio) 
- avgqu-sz: 平均I/O队列长度,即delta(avea)/s/1000(因为 aveq 的单位为毫秒)。 
- await: 平均每次设备 I/O 操作的等待时间(毫秒)。即 delta(ruse+wuse)/delta(rio+wio) 
- svctm: 平均每次设备 I/O 操作的服务时间(毫秒)。即 delta(use)/delta(rio+wio) 
- %util:一秒中有百分之多少的时间用于 I/O 操作,或者说一秒中有多少时间 I/O 队列是非空的。即 delta(use)/s/1000(因为 use 的单位为毫秒)

通信網

パフォーマンス テストにおけるネットワーク監視には、主にネットワーク トラフィックとネットワーク接続ステータスの監視が含まれます。

ネットワークトラフィック監視

多くの方法があり、インターネット上には多くのシェル スクリプトがあります。 nethogs コマンドを使用することもできます。このコマンドは top と似ており、リアルタイムの対話型コマンドです。実行インターフェイスは次のとおりです。

画像

バックグラウンド サービスのパフォーマンス テストでは、テキスト結果を返すサービスはトラフィックにあまり注意を払う必要はありません。


帯域幅を理解する

ライブ ブロードキャストやネットワーク ディスク (ファイルのアップロードとダウンロード) などの一部の特定のアプリケーションでは、帯域幅のボトルネックも頻繁に発生するシナリオです。

服务端的带宽分为上行(out)和下行(in)带宽(分别对应客户端的下载和上传)。

  • ビデオやニュースの視聴に使用される帯域幅: クライアントのダウンロード、サーバーのアップリンク帯域幅。

  • サーバーがクライアントのデータを受信するために使用する帯域幅 (クライアントのアップロード帯域幅とサーバーのダウンリンク帯域幅)。

さまざまなニュース Web サイトなどの Web サーバーは、通常、サーバー側のアップストリーム (出力) 帯域幅をより多く必要としますが、メール サーバー、ネットワーク ディスク サーバーなどは、通常、サーバー側のダウンストリーム (入力) 帯域幅をより多く必要とします。

帯域幅レートの計算式を理解する

  • 1 Mb/秒の帯域幅速度は 128 KB/秒 (1024Kb / 8KB)

  • 100 Mb/s の帯域幅速度は 12.5 Mb/s (通常、ネットワーク損失を考慮して 10M/s または 1280KB/s として計算されます)

例: 5000 万画素の携帯電話で写真を撮影すると、写真のサイズは約 20MB になり、次の帯域幅では時間がかかります。

  • 10M の帯域幅には約 20 秒かかります: 消費時間 = トラフィック / レート = 20MB / (10Mb/8) = 20 / 1.25 = 16 秒 (1MB/s=128KB/s の速度に基づく 20 秒)

  • 100M の帯域幅には約 2 秒かかります: 消費時間 = トラフィック / レート = 20MB / (100Mb/8) = 20 / 12.5 = 1.6 秒 (10MB/s=128KB/s の速度に基づく 2 秒)

  • 1000M 帯域幅は約 0.2 秒です: 消費時間 = トラフィック / レート = 20MB / (1000Mb/8) = 20 / 125 = 0.16 秒 (100MB/s=128KB/s の速度に基づく 0.2 秒)


事例分析

画像

現象:監視グラフからわかるように、現在のネットワーク トラフィックは基本的にネットワーク帯域幅を埋め尽くしており、ネットワークにボトルネックが存在します。

解決:

  • ハードウェアによる解決策: 帯域幅を増やします (帯域幅は安価です)。
  • ソフトウェアソリューション:業務に応じたデータ送信内容を効率化できるか、非同期で送信できるかを分析します。
     

ネットワーク接続状態の監視

パフォーマンス テストにおけるネットワークの監視は主に監視です网络连接状态的变化和异常

  • TCP プロトコルを使用するサービスの場合、サービスによって確立された接続 (つまり、ESTABLISHED 状態の TCP 接続) の変化を監視する必要があります。

  • HTTP プロトコル サービスの場合、テスト対象のサービスに対応するプロセスを監視する必要があります网络缓冲区的状态、TIME_WAIT 状态的连接数等


 netstat、ss など、Linux に付属の多くのコマンドはすべて上記の機能をサポートしています。

次の図は、指定された pid プロセスに対する netstat の監視結果を示しています。

画像

完全なコマンド出力:

画像

データベース

遅いクエリ

より具体的な遅い SQL の分析と最適化については、「MySQL の遅い SQL と最適化計画」を参照してください。

MySQL リソースにボトルネックがある場合は、まず遅いクエリ (カスタム実行時間しきい値を超える SQL) を探します。

1) SQL ステートメントを使用して、スロー クエリ ログが配置されているディレクトリを見つけ、ログを表示します。

show variables like "slow%";

2) スロー クエリ ログはクエリの完了後に記録されるため、アプリケーションに実行効率の問題が反映されている場合、スロー クエリ ログをクエリしても問題を特定できません。この時点で、show processlist コマンドを使用して現在の MySQL スレッドのステータスを表示し、SQL の実行をリアルタイムで表示できます。

例:

mysql -uroot -p123456 -h127.0.0.1 -p3307 -e "show full processlist" |grep dbname |grep -v NULL

3) 遅いクエリ SQL を見つけたら、実行プラン (説明) を分析 (または DBA へのフィードバックや処理のための開発) に使用できます。最も簡単なトラブルシューティング方法をお勧めします。手順は次のとおりです。

  1. SQLを分析して、不要なフィールド/データがロードされていないか確認します。
  2. SQL がインデックスにヒットするかどうかを分析します。
  3. SQLが複雑な場合は、SQL構造を最適化します。
  4. テーブル内のデータの量が大きすぎる場合は、テーブルを分割することを検討してください。
  5. ……

接続数

データベース接続プールの使用量

  • データベース接続プールがいっぱいの場合、実行する新しい SQL ステートメントがある場合、接続プール内の接続が解放されるまで待機することしかできません (前の SQL ステートメントが実行されるのを待ちます)。

  • 監視の結果、データベース接続プールの使用率が高すぎる場合、またはキューイングが頻繁に発生する場合は、チューニングを実行する必要があります。

最大接続数の表示/設定

-- 查看最大连接数
mysql> show variables like '%max_connection%';
+-----------------------+-------+
| Variable_name         | Value |
+-----------------------+-------+
| extra_max_connections |       |
| max_connections       | 2512  |
+-----------------------+-------+
2 rows in set (0.00 sec)

-- 重新设置最大连接数
set global max_connections=1000;

/etc/my.cnf でデータベース接続の最大数を設定します。

[mysqld]
max_connections = 1000

現在の接続数を表示する

mysql> show status like  'Threads%';
+-------------------+-------+
| Variable_name     | Value |
+-------------------+-------+
| Threads_cached    | 32    |
| Threads_connected | 10    |
| Threads_created   | 50    |
| Threads_rejected  | 0     |
| Threads_running   | 1     |
+-------------------+-------+
5 rows in set (0.00 sec)
  • Threads_connected: 現在の接続数を示します。結果は show processlist と同じです。正確には、Threads_running は現在の同時実行数を表します。

  • Threads_running: アクティブ化された接続の数を示します。通常、接続された値よりもはるかに低くなります。

  • Threads_created: 作成されたスレッドの数を示します。

    • MySQL サーバー構成ファイルで thread_cache_size を設定すると、クライアントが切断されたときに、このクライアントを処理するサーバーのスレッドは破棄されるのではなく、次のクライアントに応答するためにキャッシュされます (キャッシュ数が上限に達していない場合)。

    • Threads_created 値が大きすぎる場合は、MySQL サーバーがスレッドを作成していることを示しており、これも比較的リソースを大量に消費するため、構成ファイル内の thread_cache_size 値を適切に増やすことができます。

サーバーのthread_cache_sizeの値をクエリします。

mysql> show variables like 'thread_cache_size';
+-------------------+-------+
| Variable_name     | Value |
+-------------------+-------+
| thread_cache_size | 100   |
+-------------------+-------+
1 row in set (0.00 sec)


## ロック

详见《MySQL 事务和锁》。
 

キャッシュヒット率

  1. 通常、SQL クエリはディスク上のデータベース ファイルからデータを読み取ります。

  2. 特定の SQL クエリ ステートメントが以前に実行されたことがある場合、SQL ステートメントとクエリ結果はキャッシュされ、次回同じ SQL ステートメントがクエリされると、その SQL ステートメントはデータベース キャッシュから直接読み取られます。 (クエリ キャッシュは MySQL 8 以降非推奨になっていることに注意してください。)

画像

監視ポイント

  • 業務実行時のSQLクエリのキャッシュヒット率(総クエリ数に対するクエリ文がキャッシュを読み込んだ回数の割合)。

  • キャッシュ ヒット率が低すぎる場合は、キャッシュ ヒット率を向上させるために、対応するコードと SQL クエリ ステートメントを最適化する必要があります。
     

事例分析

テスト結果の分析

結論: 現在のテスト結果 (以下の図を参照) から判断すると、パフォーマンスに問題があります。

現象: 同時実行数が 50 に達すると、TPS は 52 になります。応答時間は 4.4 秒 (必要な 5 秒未満) ですが、データベース サーバーの CPU 使用率が非常に高い (ほぼ 100%) ため、データベースのチューニングと分析に重点を置きます。

画像

トラブルシューティングのプロセス

  1. top コマンドを使用して、mysqld が原因であるか、他の理由が原因であるかを観察して判断します。

    • CPUはユーザーCPUとカーネルCPUに分かれます。他のリソース指標の分析に基づいて、メモリ、ディスク IO、ネットワークなどの指標に異常がないことがわかり、カーネルの CPU 使用率は高くないと判断されます。ユーザープロセスの使用率が高い。
    • 現在 CPU 使用率が高いのは mysqld プロセスであることを確認します。
  2. データベース サーバーの CPU 使用率が高い原因として考えられるもの (SQL の遅さ、SQL ステートメントが多すぎる、接続が多すぎるなど) を分析します。

    • 遅い SQL が存在するかどうかを確認します。

      • スロークエリログをチェックして、予想される指標を超える SQL ステートメントがないかどうかを確認し、実行計画が正確かどうか、インデックスが欠落していないか、データ量が大きすぎるかどうかなどを分析してトラブルシューティングします。
      • 現在のケースのスロー クエリ ログを分析したところ、スロー クエリは存在しませんでした。
    • SQL ステートメントまたは接続が多すぎるかどうかを確認します。

      • 現在のデータベースで実行中の SQL ステートメントと接続プールのステータスを表示するには、使用show full processlistし、多数の SQL ステートメントが実行を待機していることを確認します。
      • 操作中のシステム ログを分析した結果、モールのホームページにアクセスするたびに、データベース内で 19 個のクエリ SQL を実行する必要があることが判明しました。

解決

  • ハードウェア解決策: CPU を増やします。
  • ソフトウェアによる解決策: 一度に大量の SQL をロードする必要性を減らすには、バッチ化された非同期ロード方法 (データが表示されている場所でクエリを実行する) の使用を検討してください。

JAVAアプリケーション

JVM

JVM (JAVA Virtual Machine): JAVA プログラムの実行に特別に使用される仮想空間。

JAVAアプリケーションの動作メカニズム

画像


JVM アーキテクチャの概要

画像

  • JVMのメモリは、ヤング領域(若い世代)、オールド領域(古い世代)、パーマ領域(永続世代)の3つの大きな領域に分かれており、ヤング領域にはEdgn領域、S0領域(From領域)、S1領域(エリアへ)。

  • ヤング領域とオールド領域はヒープ(heap)領域に属しヒープメモリを占有しますが、パーマ領域は永続世代と呼ばれヒープメモリを占有しません。

  • PermSpace には主に静的なクラス情報とメソッド情報、静的なメソッドと変数、最終的にアノテーションが付けられた定数情報などが格納されます。

JAVAランタイムメモリのパーティショニング

画像

重点关注:堆区(动态变化)。私たちがよく言うパフォーマンス チューニングは、ヒープ内のパフォーマンス チューニングを指します。

モニタリング ポイント:テスト中は必須です关注堆区的空间是否持续上升而没有下降。

ガベージコレクションの仕組み

ガベージコレクションメカニズムとは何ですか

  • ガベージ コレクションとは、新しいアプリケーションに適用され使用されたメモリ領域の一部をリサイクルすることを指します。

  • ガベージ コレクション メカニズムはヒープ領域のメモリ上で実行されます。

監視ポイント

  • メモリリーク: オブジェクトが参照を保持したまま解放しないため、宣言サイクルが長くなり、オブジェクトが正しく保持されているとメモリが足りなくなり、頻繁に GC が発生します。

  • システムがガベージ コレクションを実行しているときは、ユーザーの業務を処理できません。ガベージコレクションが頻繁に行われすぎると、システムの業務処理能力が低下します。

  • Full GC メモリは比較的大きく、ガベージ コレクション時間が比較的長いため、この間は業務が処理できず、システムへの影響が比較的大きいため注意が必要ですFull GC 频率


ガベージ コレクション メカニズムの動作手順は次のとおりです。

画像

  1. 新しいプログラムが実行されるとき、最初にメモリ空間を申請する必要があり、若い世代から最初に適用されます。

  2. 若い世代がいっぱいになると、ガベージ コレクションが実行されますYoung GC(Minor GC) (すべてのマイナー GC はアプリケーション スレッドを停止する「stop-the-world」をトリガーしますが、今回は無視してください)。

  3. リサイクルする場合は、若い世代のメモリがまだ使用されているかどうかを確認してください。まだ使用されている部分は生存領域 2 に移動され、使用されていない部分は解放され、若い世代のメモリ領域がクリアされます。

  4. 新しいプログラムが実行されてメモリ領域を申請し、その後、若い世代から申請されます。

  5. 若い世代が再びいっぱいになると、ガベージ コレクションが実行されますYoung GC。まだ使用中のメモリはサバイバルエリア 1 に移動され、サバイバルエリア 2 のメモリもサバイバルエリア 1 に保存されます。この時点で若い世代とサバイバルエリア2はクリアとなります。

  6. 上記の手順 1 ~ 5 を繰り返します。

  7. 記憶の一部が生存領域に長期間存続している場合 (記憶が生存領域内で 10 回程度移動されている場合)、記憶のその部分は古い世代に入れられます。

  8. 古い世代のメモリ領域が完全に占有されるまで、上記の手順 1 ~ 7 を繰り返します。この時点で、ガベージ コレクションが実行されます。Full GC(Major GC) (Full Gc は、実行中のすべてのスレッドを一時停止します (Stop)世界) メモリ領域を再利用するには、この時間を考慮する必要があります)。

JVMダンプ

JVMダンプとは何ですか

障害の特定 (特にメモリ不足) やパフォーマンスの分析中に、コードの問題のトラブルシューティングに役立つファイルがよく使用されます。これらのファイルは、JVM の実行中のメモリ使用量、スレッドの実行などを記録します。これは、よくダンプ ファイルと呼ばれるものです。

一般的に使用されるのは、ヒープ ダンプとスレッド ダンプ (javacore または Java ダンプとも呼ばれます) です。これは次のように理解できます: heap dump 记录内存信息的,thread dump 是记录 CPU 信息的

  • アプリケーションのメモリがオーバーフローしたり、メモリ使用量が長時間にわたって非常に高いことが判明した場合は、メモリ ダンプ分析によって原因を見つけることができます。

  • CPU 使用率が高いことが判明した場合は、スレッド ダンプを使用して、どのスレッドがどの作業を実行し、多くのリソースを占有しているかを特定します。

  1. ヒープダンプ

    • ヒープ ダンプ ファイルはバイナリ ファイルであり、指定された時点での Java スタックのスナップショットであり、特定の時点での JVM ヒープ内のオブジェクトの使用状況を保存するイメージ ファイルです。

    • ヒープ アナライザー ツールを使用してヒープ ダンプ ファイルを分析し、メモリ リークの原因となっているオブジェクト、またはメモリ リークの可能性があるオブジェクトを見つけるためにスタック領域を占有しすぎているオブジェクトを確認できます。

  2. スレッドダンプ

    • スレッドダンプファイルは主に、Javaアプリケーション内の各スレッドの、ある瞬間における実行位置、つまり、どのクラスのどのメソッドがどの行で実行されたかを保存します。

    • スレッドダンプはテキストファイルであり、これを開くと各スレッドの実行スタックがスタックトレースとして表示されます。

    • スレッド ダンプの分析を通じて、アプリケーションが特定の時点で「スタック」しているかどうか、つまり、データベース クエリに長期間応答できないなど、特定の時点での実行時間が長すぎるかどうかを知ることができます。 、最終的にはシステムクラッシュにつながります。

    • 単一のスレッド ダンプ ファイルは、絶対的な時点での状況を記録するだけであるため、通常はほとんど役に立ちません。さらに便利なのは、一定期間内にスレッドを実行することです。

    • スレッド ダンプ ファイルは、2 つの時点でのスレッドの実行位置を示すことができるため、分析時に特に効果的です。 2 つのデータの同じスレッドが同じ位置で実行されていることが判明した場合、プログラムは非常に高速に実行されるため、ここに問題がある可能性があります。とても時間がかかります。これら 2 つのファイルを分析することで、原因を特定し、問題を解決できます。
       

ダンプファイルを取得する

JDK に付属のツールを使用して、スレッド ダンプ ファイルとヒープ ダンプ ファイルを取得できます。つまり、JDK_HOME/bin/ ディレクトリにある 2 つのコマンド jmap と jstack です。

1) ヒープダンプファイルを取得する

./jmap -dump:format=b,file=heap.hprof 2576

これにより、Java アプリケーション プロセス 2576 の pid を含む heap.hprof ファイルが現在のディレクトリに生成されます。これはヒープ ダンプ ファイルです。

ダンプ内の生き残ったオブジェクトのみをエクスポートする必要がある場合は、:live パラメーターを使用できます。

jmap -dump:live,format=b,file=heapLive.hprof 2576

2) スレッドダンプファイルを取得する

./jstack 2576 > thread.txt

これにより、コマンドの実行結果がスレッド ダンプ ファイル thread.txt にダンプされます。ダンプ ファイルを使用すると、パフォーマンス分析ツールを使用してダンプ ファイル内の情報を取得できます (top -H -p <pid> を使用して、プロセス内で分析するスレッド ID を見つけ、そのスレッド ID を16 進数 その後、スレッド ダンプ ファイルで関連情報を検索します)。

画像


 

ダンプファイルを開く

1) JDK に付属の jhat コマンドを使用します。

jhatはJavaヒープを解析するためのコマンドで、ヒープ内のオブジェクトをhtml形式でオブジェクトの数やサイズなどを表示したり、オブジェクトクエリ言語をサポートしたりできます。

jhat -port 5000 heap.hrof

画像

サービスが開始されると、次のようにhttp://localhost:5000/ を通じてブラウザでサービスにアクセスできます。 /span> 

画像

2) Eclipse MAT ツールを使用する

一般に、アプリケーションのダンプ ファイルは非常に大きく、jdk の組み込みコマンドでこれらの大きなファイルを分析することは困難です。実際の運用環境では、サードパーティのツールを使用して、これらの大きなファイルを分析および配置するためにすばやく開く必要があります。

Eclipse Mat 分析ツールをインストールした後、ダンプ ファイルを Eclipse にインポートし、[Leak Suspects] をクリックして、分析する企業関連のコードを見つけます。

画像

画像


 

スレッドダンプファイルを分析する

スレッドダンプの詳しい説明

画像

スレッドのステータス:

  • NEW: 開始されていないため、ダンプに表示されません。
  • RUNNABLE: 仮想マシンで実行されます。
  • BLOCKED: ブロックされており、モニターのロックを待機しています。
  • WAITTING: 別のスレッドが特定の操作を実行するのを無期限に待機します。
  • TIMED_WAITTING: 別のスレッドが特定の操作を実行するのを時間制限付きで待機します。
  • 終了: 終了しました。

モニター:

画像

呼び出しの変更:

  • locked <address> ターゲット: クリティカル セクション オブジェクトのロックは再入可能であり、スレッドのステータスは RUNNABLE であることに注意してください。
  • ロック待ち <アドレス> ターゲット: ロックがまだ取得されていないため、待機領域に入り、スレッドのステータスがブロックされています
  • wait on <address> ターゲット: ロックを取得し、待機領域で待機しています。スレッドのステータスは WAITTING、TIMED_WAITTING です。
  • <address> を待機するパーキング ターゲット: スレッド プリミティブ。同期システムとは異なり、現在のパッケージで表示されます。

スレッドアクション:

  • runnable: スレッドのステータスは RUNNABLE です。
  • Object.wait() 内: 待機領域で待機中、スレッドのステータスは WAITTING または TIMED_WAITTING です。
  • モニターのエントリーを待っています: エントリー領域を待っています。スレッドのステータスはブロックされています。
  • 待機中状態: 待機エリアで待機中、駐車中。
  • sleep: スリープ状態のスレッドが Thread.sleep() を呼び出しました。

スレッド ダンプ分析の開始点

  1. エリア待機中: BLOCKED、ロック待機中、モニター入力待機中、これらの語彙名にはコード レベルで競合があります。

  2. 継続的 IO: 一般に、実行可能ファイル内の JDBC リンク コードなど、実行可能ファイルのキャプチャされた IO 呼び出しには問題があります。

  3. 非スレッドのスケジュールされた待機領域の待機: Object.wait() 内 (状況 1 によってこの状況が発生し、多数のスレッドが蓄積される可能性があります)。

  4. 「デッドロック」問題の解決策

    1. デッドロックが発生する可能性が最も高い時点でダンプを作成します。

    2. 大量のスレッド ブロックを引き起こしているスレッドを見つけます。

    3. このスレッドがブロックされた理由を調べてください。

    4. コードを読み取り、他のブロックされているスレッドまたは待機中のスレッドを反復処理し、その前の呼び出しによってこのスレッドが待機するかどうかを確認します。

  5. 注: GC 干渉を除き、フル GC の間はすべてのスレッドがブロックされます。

    • スレッド ダンプを表示するときは、まずメモリ使用量を確認します。
    • コマンド「-verbose:gc」を使用して、Full GC という単語があるかどうかを確認します。

ヒープダンプファイルを分析する

ヒープダンプを分析する必要があるのはどのような場合ですか?

メモリ不足、GC 例外、またはコード メモリ リークの疑いがある場合、ヒープ ダンプを作成して、ライフ サイクル内のエラー関連オブジェクトと関連コードを見つける必要があります。

JVMメモリモデル

  • 若い世代(エデン空間、フロムスペース、トゥスペースを含む)
  • 旧世代
  • PermGen スペース

2種類のGC

  • YoungGen GC:マイナーGC
  • フルGC:メジャーGC

よくある間違い

  • out of MemoryError: GC オーバーヘッド制限を超えています: リサイクル時間はシステム実行時間の 98% 以上を占めており、メモリ リークが原因である可能性が最も高くなります。

ケーススタディ: JVM ヒープメモリのオーバーフロー

JVM ヒープ メモリのリサイクルの詳細なプロセスの図: 下の図から、古い領域のスペースがいっぱいになった後、FGC (フル GC と呼ばれます) が実行されることがはっきりとわかります。新しく生成されたオブジェクトを収容できない場合、Java ヒープ メモリ オーバーフロー [JAVA HEAP OOM] が発生します。

画像

パフォーマンスの問題発見プロセス:

サーバー上のエラー ログを確認すると、[java.lang.OutOfMemoryError: Java heap space] というエラー メッセージが表示されます。エラー メッセージによると、jvm ヒープのメモリ領域が不足していると判断されるため、jvm コマンドを使用してこれを表示すると (次の図に示すように)、この時点で古い領域のメモリ空間がすでにいっぱいであることがわかります。

画像

同時に、jvisualvm 監視ツールを使用すると、古い領域スペースがいっぱいで (下図に示すように、単位はパーセントです)、ヒープ領域スペース全体が新しいオブジェクトを収容できなくなっていることもわかりました。

画像

推奨事項:大量のデータを一度にメモリに書き込むシナリオを検討してください。

ケーススタディ: 永続世代メモリのオーバーフロー

PermSpace には主に静的なクラス情報とメソッド情報、静的なメソッドと変数、最終的にアノテーションが付けられた定数情報などが格納されます。

現象:

特定のシステム インターフェイスのストレス テスト。ストレス テストの約 1 分前に TPS は 400 以上でした。その後、TPS はゼロに下がりました。バックグラウンド エラー ログは、java.lang.OutOfMemoryError:PermGenspace でした。jvm 監視ツールを使用して、永続世代 (永続領域) スペースがいっぱいである一方、Old 領域が空いていることを確認してください。

画像

画像

問題を特定します:

コード ブロックにコメントを付けて問題を特定します。パーマ領域のオーバーフローが主にクラス オブジェクトの大規模な作成に関連していることを考慮すると、シリアル化フレームワークを使用する場合、ロックの問題が問題となる可能性があります。

  1. JVMダンプファイルを取得します。

  2. 日食マット解析ツールをインストールします。

  3. ダンプ ファイルを Eclipse にインポートし、[Leak Suspects] をクリックして、分析対象の会社に関連するコードを見つけます。

画像

画像

解決:

開発チームと協議した後、msgpack0.6 バージョンのフレームワークを削除し、Java ネイティブのシリアル化フレームワークを使用することにしました。改造後はシステムtpsは400以上で安定しており、gc状態も正常です。

  • 修理前:

    画像

  • 修理後:

    画像

同様の問題を回避する方法:

  • 不要な jar パッケージをプロジェクトから削除します。
  • クラス オブジェクトの多用やリフレクションの多用は避けてください。

ケーススタディ: 頻繁な FGC

現象: システムの特定のインターフェイスで FGC が頻繁に発生します。

トラブルシューティングと解決策:

まず、JVM メモリ情報をチェックして、疑わしいオブジェクトを見つけます。コマンドは次のとおりです: jmap -histo

画像

メモリ オブジェクト インスタンス情報から、mysql 接続に関連していることがわかり、mysql 設定情報が検出されます。

<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">

システムは Spring Framework のデータ ソースを使用し、接続プールを使用していないことがわかりました。

使用连接池的好处:连接复用,减少连接重复建立和销毁造成的大量资源消耗。

次に、比較テストのために hikaricp 接続プールに切り替えます。

<bean id="dataSource" class="com.zaxxer.hikari.HikariDataSource"

30分間の圧力テスト中にfgcは現れず、問題は解決されました。

同様の問題を回避する方法:

  • 研究開発仕様は、研究開発による悪用を避けるために DB 接続プールを統合します。
  • 大きなオブジェクトや一時的なオブジェクトの使用を減らします。

ケーススタディ: ミラー GC の削減

現象:

現在、数十億のトラフィック、500 万人のアクティブ ユーザー、支払い変換率 10% の電子商取引ショッピング イベントがあると仮定します。アクティブ時間は、1 秒あたり 1,000 件のオーダーが生成され、各 Tomcat の最大同時サポート数が 500 であると仮定した場合、ラッシュの最初の数分間です。既存のサーバーが 3 台あり、すべて 4 コアと 8g が搭載されており、各サーバーには Tomcat がデプロイされ、負荷分散には nginx が使用されています。

サーバー 1 には 300 のオーダーがあります。各オーダーのヒープ領域サイズは 1Kb で、1 秒あたり約 300Kb のヒープ オブジェクトが生成されます。 Lucene を使用すると、Javabean が配置されているヒープ領域のサイズを動的に計算できます。注文を行うと、クーポン、在庫、ポイントなどの他のオブジェクトも生成されます。これらは 20 倍に拡大されます。つまり、1 秒あたり 6000Kb のオブジェクトが生成されます。順序クエリ操作があると仮定して、10 倍に拡大すると、1 秒あたり約 58MB のオブジェクトが生成されます。

このときのヒープサイズは初期および最大ともに3072MB、旧世代のサイズは2048MB、新世代のサイズは1024MB、Eden領域のサイズは819MB、s0、s1領域のサイズはともに102MBです。 819Mb / 58Mb = 14 秒、つまり、Eden 領域は約 14 秒でいっぱいになり、ミラー Gc がトリガーされ、この時点でアプリケーション スレッドが停止します。

最適化:

したがって、この時点で JVM 構成パラメータを調整する必要があります。古い世代のサイズは 1024MB、新しい世代のサイズは 2048MB、Eden 領域のサイズは 1638MB、s0 および s1 領域のサイズは両方とも 204MB です。 1638Mb/58Mb = 28 秒。これにより、ミラー Gc が削減され、最適化の結果が得られます。ただし、実際のオンライン JVM 操作に基づいてさらに最適化が行われていることがわかります。

画像

フレームの不適切な使用

ケーススタディ: フレームワークが提供する API の誤った使用

あるシステムのビジネス ロジック処理能力は非常に高速です (ローカル セルフテストの TPS は 20,000 以上に達する可能性があります)。しかし、フレームワーク フレームワークに接続された後の TPS は最大 300 程度までしか到達できません。システム負荷は非常に低いです。


トラブルシューティング:

この現象は、システムが何らかの方法でブロックされた可能性があることを示しており、システムのどのスレッドが異常であるかを確認するために、一般的にスレッドダンプが使用されます。

スレッド ダンプにより、[TIMED_WAITING] 状態のビジネス スレッドの割合が非常に高いことがわかりました。

# 线程的状态
* NEW:未启动,不会出现在 Dump 中。
* RUNNABLE:在虚拟机中执行的。
* BLOCKED:受阻塞并等待在监视器锁。
* WAITTING:无限期等待另一个线程执行特定的操作。
* TIMED_WAITTING:有时限的等候另一个线程执行特定的操作。
* TERMINATED:已退出。

画像

スレッド ダンプ情報に従って、会社のパッケージ名で始まる情報を検索し、下から上にスレッド ダンプ情報を表示します。

  • Framework.servlet.fServlet.doPost: フレームワーク API は、特定の操作を実行するために servletdopost メソッドをカプセル化します。
  • Framework.servlet.fServlet.execute: フレームワーク API は、servlt を実行します。
  • Framework.process.fProcessor.process: フレームワーク API は独自の論理処理を実行します。
  • Framework.filter.impl.AuthFilter.before: フレームワークはユーザー権限のフィルタリングにフィルターを使用します。
  • 。 。 。次に、http リクエスト操作を実行します。

このことから判断すると、フレームワークの権限検証でブロックされています。その後、この問題を開発部門に伝えてください。


問題の原因:

性能テストはシステムAの処理能力を検証するものですが、ストレステストプログラムではシステムAが許可検証システムを呼び出しますが、許可検証システムの処理能力は300程度しかないため、システムAの処理能力が低下してしまいます。システム全体。

したがって、ストレステスト中は、システム A のみにストレスを与える許可検証システムコールをオフにし、システム A の真の処理能力をストレステストできるようにする必要があります。

画像


解決

B システムへの呼び出しを削除します。つまり、権限の検証を削除します。

@Api(auth=true) 改为 @Api(auth=false)

ケーススタディ: ロギングフレームワークの不適切な使用

システムがログを出力するために LOGBACK ログ フレームワークを追加した後 (ログ レベルは INFO)、TPS は 1000 から 200 以上に低下しました。

画像

JVISUALVM ツールから、多数のビジネス スレッドが BLOCKED 状態にあることがわかります。

画像


最適化:

ログをダウングレードし、警告するログ レベルを変更して、ログ出力の量を減らします。

フォローアップの提案:

  1. ログ レベルを適切に設定し、ログ出力を効率化します。

  2. ログのフラッシュ方法 (同期または非同期) を適切に設定します。

  3. DEBUG および INFO ログを出力するには、最初にログ レベルを決定する必要があります。if(LOGGER.isDebugEnabled()){do log} 。

OSのメモリオーバーフロー

問題の症状:

あるシステムでオンライン障害が発生し、システムがアニメーションを一時停止してサービスを提供できなくなり、サーバーにsshでログインできなくなりました。

問題の根本原因:

システムはオフヒープ メモリを使用しており、オペレーティング システムのカーネルがキャッシュ メモリを占有しているため、キャッシュ メモリがいっぱいになると解放できず、物理メモリの OOM (Out Of Memory) が発生します。

OOM を使用する理由
 
記憶がないのはなぜですか?理由は次の 2 点にすぎません。

  1. 割り当てが少ない: たとえば、仮想マシン自体で使用できるメモリ (通常は起動時に JVM パラメータによって指定されます) が少なすぎます。

  2. アプリは使いすぎて使っても出ないのでもったいないです。これにより、メモリ リークまたはメモリ オーバーフローが発生します。

最適化:

Linux オペレーティング システムのカーネル パラメータを最適化することにより: min_free_kbytes

    自動テストに関連する推奨チュートリアル:

2023 年最新の自動テスト独習チュートリアルは、初心者向けに 26 日間で始められる最も詳細なチュートリアルで、現在、このチュートリアルを学習して大手企業に入社した人が 300 名を超えています。 ! _bilibili_ビリビリ

Python自動テスト開発フレームワークの2023年最新集【フルスタック/実践/チュートリアル】集エッセンス、学習後の年収40W+_bilibili_bilibili

テスト開発に関連する推奨チュートリアル

2023 年にネットワーク全体で最高の Byte テスト開発責任者が現場で指導し、ゼロから年収 100 万のテスト開発エンジニアになれるよう指導します_bilibili_bilibili

postman/jmeter/fiddler テスト ツールのチュートリアルの推奨事項

JMeter インターフェイス テスト/インターフェイス自動テスト プロジェクトに関する実践的なチュートリアルの最も詳細なコレクション。jmeter インターフェイス テストを学習するには、一連のチュートリアルで十分です。 ! _bilibili_ビリビリ

2023 年に Fiddler でパケットをキャプチャする方法を独学するには、インターネット上で最も詳細なビデオ チュートリアル [Fiddler で 1 日でパケットをキャプチャする方法を学ぶ方法] を必ずご覧ください。 ! _bilibili_ビリビリ

2023 年には、ネットワーク全体が表彰されます。ステーション B でのポストマン インターフェイス テストの最も詳細な実践的な指導は、novices_bilibili_bilibili で学ぶことができます。

  要約:

 光学理論は役に立ちません。学んだことを実際に適用するには、それに従って練習する必要があります。このとき、いくつかの実際の事例から学ぶことができます。

お役にたてましたら、いいね、保存していただけると作者の励みになります。次回から素早く検索することも容易になります。

理解できない場合は、下の小さなカードを参照してください。ブロガーは、同じ考えを持つテスターと一緒に学び、改善することも望んでいます。

適切な年齢で、適切なポジションを選択し、自分の長所を最大限に発揮するように努めてください。

私は計画と要約が好きなので、自動テスト開発への道は各段階の計画と切り離すことができません。

テスト開発ビデオチュートリアルと学習ノート収集ポータル! !

おすすめ

転載: blog.csdn.net/m0_70618214/article/details/134915374