Perl プロセスの CPU 使用率が 13% のまま:off-CPU フレームグラフでブロッキング HTTP 呼び出しを特定
Perl プロセスにリクエストが届き続けているのに CPU 使用率が低いまま(本例では約 13%)の場合、何らかのコードパスが OS スレッドをブロックしています。典型的なのは select で応答を待つ HTTP 呼び出しのような同期 I/O です。本記事では、OpenResty XRay の off-CPU フレームグラフを使い、ブロッキングしている Perl コードパスをソースファイルと行番号まで特定する方法を紹介します。コード変更もプロセス再起動も不要です。
症状:リクエストが殺到しても Perl プロセスの CPU 使用率が上がらない
まず top コマンドを実行して、CPU の使用状況を確認します。
こちらの Perl プロセスに注目してください。CPU の使用率は約 13% です。多くのリクエストが入ってきても、CPU の使用量は上昇しません。
次に ps コマンドを実行して、このプロセスの詳細を確認しましょう。
ここでは、Linux ディストリビューションに標準で付属している Perl のバイナリ実行ファイルであることがわかります。
次に、この Perl アプリケーションのアクセスログを見てみましょう。
多くのクライアントリクエストが来ているのが見えますが、CPU 使用率は依然として低いです。これは、何かが Perl コードの効率的な実行をブロックしていることを意味します。その原因はどのように特定すればよいのでしょうか。
OpenResty XRay の off-CPU フレームグラフでブロッキング Perl コードパスを特定する
OpenResty XRay を使用して、この未修正のプロセスを検査することができます。リアルタイムで分析を行い、原因を特定できます。
ブラウザで OpenResty XRay の Web コンソールを開き、分析対象のマシンが正しいことを確認してから、「Guided Analysis」ページに移動します。
分析可能な問題タイプの中から「Low CPU usage and cannot go up」を選択します。
あとはウィザードに従って進めます。先ほどの Perl アプリケーションを選び、14% の CPU を消費しているプロセス(先ほど top で確認したもの)を選択し、残りのステップはデフォルトのままにします。アプリケーションのタイプ、Perl と C/C++ の両言語レベル、最大分析時間の 300 秒です。
分析を開始します。システムは複数回の分析を継続的に実行しますが、この例では 1 回で十分なので、そこで停止します。
自動生成された分析レポートが表示されます。
これは分析対象の問題タイプである off-CPU です。
これは、オペレーティングシステムスレッドを最も深刻にブロックしている C コードパスです。
最初の関数は select というシステムコール関数です。
Perl_pp_select は、Perl の select 関数を処理するための組み込み関数です。これは Perl 内部の一部で、socket や他のファイル上の I/O イベントを監視し、待機するために使用されます。
この C 関数から、現在 Perl コードが実行されていることがわかります。
次に、OS スレッドを最も強くブロックしている Perl コードパスを確認しましょう。
最上部の C 関数 select は、先ほど見た C コードパスのブロッキングポイントです。
Net::HTTP::Methods モジュールの can_read Perl 関数は、ソケットが読み取り可能な新しいデータを受信するまで待機します。
呼び出しチェーンに沿って、read_response_headers 関数でレスポンスヘッダーを読み取っているときにブロッキングが発生していることがわかります。
remote_fetch は業務ロジックのコードにある関数で、弊社独自の Perl モジュール Service::Processor に属しています。
最も顕著なブロッキングコードパスは、この Perl 言語レベルの off-CPU フレームグラフから自動的に導き出されています。このような off-CPU 分析はレイテンシ問題の診断にも標準的な手法です——50万 QPS の OpenResty ゲートウェイで 244ms の遅延を特定した事例もご覧ください。
ここでは、現在の問題に関する詳細な説明と提案が示されています。
前に見た select 関数が言及されています。
Net::HTTP::Methods::can_read 関数がデータに基づいて次のステップを選択するために select を呼び出していることが述べられています。
これも、以前見た remote_fetch 関数の参照です。
前のホットコードパスに戻りましょう。
remote_fetch という名前の Perl 関数の緑のボックスにマウスカーソルを合わせると、
この関数の Perl ソースファイルの完全なパスが表示されます。
この関数の完全な Perl ソースファイルパスをコピーするためにクリックします。
ターミナルで、先ほどコピーしたパスを貼り付け、vim エディタで該当の Perl 業務コードを開きます。お好みのエディタを使用していただいて構いません。
OpenResty XRay が提案したように、66 行目をチェックします。
HTTP GET リクエストを送信し、その応答を待機していることがわかります。
Perl で HTTP リクエストがブロックされるのを避けるために、Coro のような非ブロッキングフレームワークの使用をご検討ください。同じ off-CPU 分析のアプローチは Go や Python のプロセスにも適用できます。
Insights ページの自動分析とレポート
OpenResty XRay は実行中のプロセスを自動的に監視し、「Insights」ページで日次・週次の分析レポートを生成できます。そのため「Guided Analysis」機能を必ずしも手動で使用する必要はありませんが、アプリケーションの開発やデモンストレーションには引き続き有用です。
OpenResty XRay は弊社独自の動的トレーシング技術に基づく非侵入型の診断システムです。パフォーマンスの問題、動作の問題、セキュリティ脆弱性をリアルタイムで監視・スキャンできます。
FAQ
なぜ Perl プロセスは高負荷でも CPU を使い切れないのですか?
何らかのコードパスが CPU 上で処理を行う代わりに OS スレッドをブロックしているためです。本記事のケースでは、Net::HTTP::Methods モジュールの can_read 関数が select システムコールでソケットの新しいデータを待ち続けており、リクエストが積み上がる一方でプロセスはほぼ待機状態でした。
コードを変更せずに、どの Perl コードがブロッキングしているかを特定するには?
未修正の実行中プロセスに対して OpenResty XRay の「Guided Analysis」を実行し、「Low CPU usage and cannot go up」を選択します。生成されたレポートが最も重要なブロッキングコードパスを自動的に推定し、off-CPU フレームグラフの関数にマウスを重ねればソースファイルと行番号まで確認できます。
本記事の off-CPU フレームグラフは何を示していますか?
OS スレッドが CPU 上で実行される代わりに、ブロックされて待機している時間を費やしたコードパスを示しています。本記事のケースでは、Perl 言語レベルの off-CPU フレームグラフがビジネス関数 remote_fetch を直接指し示しており、この関数は read_response_headers 内の select 呼び出しで HTTP 応答を待つ間ブロックしていました。
OpenResty XRay について
OpenResty XRay は動的トレーシング製品であり、実行中のアプリケーションを自動的に分析して、パフォーマンスの問題、動作の問題、セキュリティの脆弱性のトラブルシューティングを行い、実行可能な提案を提供いたします。基盤となる実装において、OpenResty XRay は弊社の Y 言語によって駆動され、Stap+、eBPF+、GDB、ODB など、様々な環境下で複数の異なるランタイムをサポートしております。
著者について
章亦春(Zhang Yichun)は、オープンソースの OpenResty® プロジェクトの創始者であり、OpenResty Inc. の CEO および創業者です。
章亦春(GitHub ID: agentzh)は中国江蘇省生まれで、現在は米国ベイエリアに在住しております。彼は中国における初期のオープンソース技術と文化の提唱者およびリーダーの一人であり、Cloudflare、Yahoo!、Alibaba など、国際的に有名なハイテク企業に勤務した経験があります。「エッジコンピューティング」、「動的トレーシング」、「機械プログラミング」 の先駆者であり、22 年以上のプログラミング経験と 16 年以上のオープンソース経験を持っております。世界中で 4000 万以上のドメイン名を持つユーザーを抱えるオープンソースプロジェクトのリーダーとして、彼は OpenResty® オープンソースプロジェクトをベースに、米国シリコンバレーの中心部にハイテク企業 OpenResty Inc. を設立いたしました。同社の主力製品である OpenResty XRay(動的トレーシング技術を利用した非侵入型の障害分析および排除ツール)と OpenResty Edge(マイクロサービスおよび分散トラフィックに最適化された多機能ゲートウェイソフトウェア)は、世界中の多くの上場企業および大企業から高い評価を得ております。OpenResty 以外にも、章亦春は Linux カーネル、Nginx、LuaJIT、GDB、SystemTap、LLVM、Perl など、複数のオープンソースプロジェクトに累計 100 万行以上のコードを寄与し、60 以上のオープンソースソフトウェアライブラリを執筆しております。
翻訳
英語版の原文と日本語訳版(本文)をご用意しております。読者の皆様による他の言語への翻訳版も歓迎いたします。全文翻訳で省略がなければ、採用を検討させていただきます。心より感謝申し上げます!


















































