Lua コードが原因で Nginx や OpenResty サーバーの CPU 使用率が高くなった場合、最も早い解決方法は、稼働中のワーカープロセスをリアルタイムでプロファイリングし、最もホットな Lua コードパスを特定することです。このチュートリアルでは、OpenResty XRay が CPU の 97% を消費するワーカープロセスの原因を、processor.lua の 29 行目、gen_order_md5 関数内でループ実行されている MD5 計算まで特定します。プロセスの変更や再起動は一切不要です。

症状:Nginx ワーカープロセスが CPU をほぼ 100% 使用

まず、top コマンドを実行して、対象サーバーの CPU 使用状況を確認します。ご覧のように、1 つの Nginx ワーカープロセスが CPU コアリソースのほぼ 100% を消費しています。

top コマンドの出力。Nginx ワーカープロセスの CPU 使用率が 1 コアのほぼ 100% に達している

「Guided Analysis」で最もホットな Lua コードパスを特定する

OpenResty XRay を使用して、一切手を加えていないこのプロセスを検査してみましょう。リアルタイムで分析して、その原因を明確にします。

OpenResty XRay の Web コンソールを開いてログインし、分析対象のサーバーが正しいことを確認したら、「Guided Analysis」ページに移動します。ここでは、システムが分析可能な様々な種類の問題を確認できます。「High CPU」を選択します。

OpenResty XRay の Guided Analysis ページに診断可能な問題タイプが一覧表示され、Lua CPU 診断のために High CPU を選択

アプリケーションを選択し、CPU リソースの 97% を消費しているプロセスを選択します。

OpenResty XRay の Guided Analysis で CPU を 97% 消費している Nginx ワーカープロセスを選択

アプリケーションのタイプが正しいことを確認します。通常はデフォルト値のままで問題ありません。OpenResty XRay は、複数の言語レベルを同時に分析できます。ここでは Lua と C の両方を選択したままにします。

OpenResty XRay の言語レベル選択画面。CPU 分析のために Lua と C の両方のレベルが有効

最大分析時間を設定することもできます。ここではデフォルトの 300 秒のままにして、分析を開始します。システムは複数回の分析を継続的に実行しますが、この例では初回の分析で十分ですので、分析を停止します。自動生成された分析レポートが表示されます。

レポートには、最も多くの CPU 時間を消費している Lua コードパスが表示されます。

最も多くの CPU 時間を消費している Lua コードパスを表示する OpenResty XRay の分析レポート

詳細を確認するには、こちらをクリックしてください。

CPU 時間で最上位となる #1 の最もホットな Lua コードパスの完全な呼び出しチェーンを表示する、展開されたレポート詳細

Lua CPU フレームグラフを読み解く

レポートには Lua CPU フレームグラフもあり、最もホットなコードパスが赤色で表示されています。

OpenResty XRay の Lua CPU フレームグラフ。最もホットな Lua コードパスが赤色で表示されている

最もホットな Lua コードパスには、MD5 計算関数の呼び出しが含まれています。

Lua CPU 時間の大半を占める MD5 計算関数呼び出しを示すフレームグラフのフレーム

その後の呼び出し元関数は、すべて対象アプリケーションの業務ロジックのコードからのものです。

レポート内の #1 の最もホットな Lua コードパスの呼び出しチェーン。gen_order_md5 より後の関数はすべて業務ロジックのコードからのもの

該当する Lua ソースコード行へジャンプする

gen_order_md5 Lua 関数から始めて、アプリケーションの業務ロジックのコード内で正確なソースコード行を特定します。

業務ロジックのコード内の正確なソース行を特定する起点として、レポート内で gen_order_md5 のフレームがハイライトされている

関数の緑色のボックスにマウスカーソルを合わせると、表示されるツールチップで Lua ソースファイル processor.lua の完全なパスを確認できます。

gen_order_md5 のフレームにマウスカーソルを合わせると、ツールチップに Lua ソースファイル processor.lua の完全なパスが表示される

ソースコードの行番号は 29 です。

ホットな gen_order_md5 Lua 関数のソースコード行番号 29 を示すフレームグラフのツールチップ

アイコンをクリックして、この関数の完全な Lua ソースファイルパスをコピーします。

gen_order_md5 関数の完全な Lua ソースファイルパスを取得するためにコピーアイコンをクリックする

VI エディタを使用して、先ほどコピーしたコードパスをここに貼り付け、対応する業務ロジックの Lua コードを確認します。お好みのエディタを使用していただいて構いません。

ターミナルで VI を使い、コピーした Lua ソースファイル /app/or-order-service/service/order/processor.lua を開く

先ほどのレポートから、コードが 29 行目にあることがわかっています。

VI で開いた processor.lua。レポートが示した 29 行目がハイライトされている

この Lua ソースコード行には、実際にループ内の md5 計算が含まれていることがわかります。

VI で開いた Lua ソースファイル processor.lua。29 行目にループ内の md5 計算が表示されている

これは、レポートに表示されていた gen_order_md5 関数内にあります。

processor.lua 内の gen_order_md5 関数定義がハイライトされ、レポートのホットな関数と一致している

Insights レポートで Lua CPU 使用率を自動監視する

OpenResty XRay はオンラインプロセスを自動的に監視し、分析レポートを生成することができます。「Insights」ページでは、日次および週次のレポートを確認できます。

自動生成された日次・週次の Lua CPU 分析レポートが並ぶ OpenResty XRay の Insights ページ

したがって、「Guided Analysis」機能を必ずしも使用する必要はありません。「Guided Analysis」はアプリケーションの開発やデモンストレーションの際に有用です。

OpenResty XRay は、弊社独自の動的トレーシング技術に基づく非侵入型の診断システムです。パフォーマンスの問題、動作の問題、セキュリティ脆弱性をリアルタイムに監視・スキャンできます。

実行中のアプリケーションを非侵入型で診断する OpenResty XRay のイメージ図

このチュートリアルが役に立ちましたら、当ブログや弊社の YouTube チャンネルへのご登録をぜひお願いいたします。ありがとうございます!

よくある質問

Nginx ワーカープロセスの CPU 使用率が 100% 近くになるのはなぜですか?

この事例では、アプリケーションの業務ロジックのコード内でループ実行されていた MD5 計算というホットな Lua コードパスが原因で、Nginx ワーカープロセスが CPU コアをほぼ使い切っていました。ご自身のサーバーでどの Lua コードパスが原因かを突き止めるには、稼働中のプロセスをリアルタイムでプロファイリングする必要があります。

どの Lua コードが CPU を消費しているかを特定するには?

OpenResty XRay の「Guided Analysis」機能を使用します。「High CPU」問題タイプを選択し、CPU 使用率の高いワーカープロセスを選び、Lua と C の両方の言語レベルを選択したままにします。生成されるレポートには、最もホットな Lua コードパス、ホットパスが赤色で表示された Lua CPU フレームグラフ、そして正確なソースファイルと行番号(このチュートリアルでは processor.lua の 29 行目)が表示されます。

Nginx を再起動せずに Lua の CPU 使用率をプロファイリングできますか?

できます。OpenResty XRay は、一切手を加えていないこの Nginx プロセスを、再起動もコード変更も行わずに、リアルタイムで分析しました。動的トレーシング技術に基づく非侵入型の診断システムであり、オンラインプロセスを自動的に監視して、「Insights」ページに日次・週次のレポートを生成することもできます。

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、LuaJITGDBSystemTapLLVM、Perl など、複数のオープンソースプロジェクトに累計 100 万行以上のコードを寄与し、60 以上のオープンソースソフトウェアライブラリを執筆しております。

翻訳

英語版の原文と日本語訳版(本文)をご用意しております。読者の皆様による他の言語への翻訳版も歓迎いたします。全文翻訳で省略がなければ、採用を検討させていただきます。心より感謝申し上げます!