スタック
ホーム画面 > プロジェクト選択 > 分析 > スタック
WhaTapモニタリングサービスの初期画面でプロジェクトを選択し、プロジェクトメニュー下の分析 > スタックを選択してください。トップスタックとユニークスタック、アクティブスタックを確認することができます。
スタック分析機能を使用できるアプリケーションはJavaとPython、.NETです。
WhaTapは、10秒(既定値) 間隔で収集したThread Stackを使用して、メソッドレベルの性能遅延を分析します。
例)スタックのトップラインはsocketRead0
です。
java.net.SocketInputStream.socketRead0(Native Method)
トップラインは、ダンプを実行するスレッドがメソッドを実行中であることを意味します。すぐにキャッチされる可能性もありますが、確率的にそのモジュールの処理時間のコンセンサスの比率をスタックに表示します。このトップラインメソッドを計算してメソッドレベルのパフォーマンスを判断することができます。WhaTapは、トップライン頻度統計をトップスタック(Top Stack)と呼びます。
トップスタック分析を使用したメソッドに対して、どのメソッドが呼び出しされた頻度を分析できます。
トップスタックの階層分析では、もともとのアクティブスタックを確認するのが困難でした。しかし、WhaTapは、アクティブスタック(Active Stack)を参照できるように同じスタックを集めてユニークスタック(Unique Stack)と呼ばれる検索機能を提供します。
トップスタック
StackTraceの各Stepを基準に、StepとStep間の呼び出し比率をパーセンテージで分析した情報を提供します。最上位Stepのバックログ頻度をパーセンテージで算出し、降順に並べ替えられた結果を表示します。
各ステップをクリックすると、ステップを呼び出す上位ステップの呼び出し頻度をパーセンテージで算出して提供します。
トップスタック統計は十分なデータで 判断する必要があります。収集したスタックの数が10個未満の少数の場合、統計的な意味を持つには不十分です。
トップスタックはチューニング時に認識しづらい部分のチューニングポイントを見つけるのに役立ちます。最も頻繁に表示されるスタックは、アプリケーションサーバーでもっとも応答遅延が発生しているスタックであると判断できます。左端の割合は、アプリケーションサーバーのパフォーマンスに影響を与える程度です。
安定したアプリケーションサーバーであっても、頻繁なスタックはパフォーマンス低下を引き起こす可能性があるため、これらのクラスに注意深く監視することをお勧め します。
トップスタックをクリックすると、そのトップスタックを呼び出す頻度を確認できます。トップスタックの呼び出し関係は1対1の関係であるため、トップスタックのdepthの深さが下がるにつれて情報の精度が低下する可能性があります。下位depthに関する情報は参考として使用し、チューニングを進めてください。
アプリケーションのパフォーマンスを向上させるには、最上位Stepのバックログ比率が高いモジュールのボトルネックを調べる必要があります。バックログ比率が高いモジュールの場合、パフォーマンスが少し向上しただけでも、アプリケーション全体が大幅に改善される可能性があります。
whatap.util.ThreadUtil.sleep
// jdbc.Control.execの呼び出し比率は40.02%
jdbc.Control.exec
// // jdbc.FakePreparedStatement.executeQuery呼び出し比率は68.06%
whatap.util.ThreadUtil.sleep
← jdbc.Control.exec
← jdbc.FakePreparedStatement.executeQuery
の呼び出し比率が 40.02% * 68.06% を意味するものではありません。jdbc.Control.exec
で他モジュールの呼び出す可能性があるためです。
トップスタックを使用して呼び出し比率を判断する場合、各Step間の呼び出し比率を掛け合わせて全体の呼び出し関係比率を算出してはいけません。Top Stackの呼び出し比率は、Stack Traceに表示される情報のStep間の呼び出し比率の算出した結果であるため、Step間の呼び出し比率から全体的な呼び出し比率を算出すると、歪んだ結果が得られる可能性があります。
トップスタック統計では、時間の経過に伴う比率の変化と収集件数を提供しますす。
-
パーセント
- 検索期間を選択したトップスタックの比率の変化を示します。
- 不具合箇所の状況把握や改善前後の比較に役立ちます。
-
件数
- 収集されるスタックの数は、アクティブトランザクションの数に比例します。
- 特定のセグメントで収集量が増加している場合は、サービスの遅延または急激な流入量の増加があったことが分かります。
次のようなダイヤグラムでも確認できます。
-
Stack Chart
個々のトップスタックの比率をチャートで示します。
ユニークスタック
Stack Trace全体のHash値基準の算出した結果、全体Stepが同じ呼び出し比率 をパーセンテージで分析した情報を提供します。トップスタックは、Step間の呼び出し比率に関する情報を提供します。
ユニークスタックは、Stack Trace全体の正確な呼び出し情報に基づいてデータを提供します。詳細な呼び出し関係を理解する情報を提供します。例えば、バックログ比率の高いStack Traceを特定することができます。
詳細な呼び出しステップレビューにより、呼び出しパス上の異常なモジュールの存在を特定することができます。
アクティブスタック
進行中のトランザクションをアクティブトランザクションと呼びます。アクティブトランザクションから定期的にダンプされるスタックはアクティブスタックと呼ばれます。
WhaTapエージェントは、10秒(オプション)ごとにアクティブトランザクションからアクティブスタックをダンプし、サーバーに送信します。
active_stack_second=10
アクティブスタックメニューを選択すると、収集されたActiveStackをチャートで確認できます。チャートは5分間の単位統計データをActive Transactionの数を棒グラフとして、TPSを折れ線で表示します。
グラフ内の棒をクリックするとアクティブなトランザクションの情報が表示されます。アクティブトランザクションの情報をクリックするとトランザクションのアクティブスタックが表示されます。
アクティブトランザクションの詳細に ついては、次の文書を参照してください。
コンパクトなアクティブスタックの収集
アクティブスタックはスレッドダンプを定期的に実行するため、誤った実装をするとエージェントのオーバーヘッドが増加する可能性があります。WhaTapはエージェント負荷を最小限に抑えながらアクティブスタックを収集するために、様々なオプションがあります。
サイトマップ > スレッド一覧/ダンプメニューのスレッドリストでWhaTap-ActiveStackDumpスレッドのCPU Timeを確認することでオーバーヘッドを判断できます。
アクティブスタックの例
java.lang.StringBuffer.append(StringBuffer.java:309)
java.util.regex.Matcher.appendReplacement(Matcher.java:839)
java.util.regex.Matcher.replaceAll(Matcher.java:906)
java.lang.String.replaceAll(String.java:2162)
core.log.triggers.TriggerRegister.changeNotify(TriggerRegister.java:114)
core.log.aop.handler.DaoInfo.log(DaoInfo.java:141)
core.log.aop.handler.DaoInfo.doAround(DaoInfo.java:102)
core.log.aop.reflection.profiler.AroundProfiler.invoke(AroundProfiler.java:19)
com.sun.proxy.$Proxy39.getUpdateCount(Unknown Source)
org.apache.ibatis.executor.resultset.DefaultResultSetHandler.getNextResultSet(DefaultResultSetHandler.java:256)
org.apache.ibatis.executor.resultset.DefaultResultSetHandler.handleResultSets(DefaultResultSetHandler.java:193)
org.apache.ibatis.executor.statement.PreparedStatementHandler.query(PreparedStatementHandler.java:64)
* * *
sun.reflect.GeneratedMethodAccessor140.invoke(Unknown Source)
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
java.lang.reflect.Method.invoke(Method.java:606)
org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:221)
org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:136)
org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:114)
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:827)
最適化されたデータ収集
-
トランザクションを実行しているスレッドに対して、スタックをダンプします。
-
アクティブスタックダンプの時間間隔を調整できます。
active_stack_second=10
-
アクティブスタックの最大行に制限されます。トップラインから基本の50行を収集します。
trace_active_callstack_depth=50
-
アクティブスタックの各行をハッシュ処理して収集します。テキストは1度だけ収集します。
-
一度に収集される最大のアクティブスタックの数も制限されます。
active_stack_count=100
Background Threadのアクティブスタック
基本的にアクティブスタックは、トランザクションが実行されているスレッドのスタックです。ただし、一部のバックグラウンドスレッドのスタックも分析が必要な場合があります。この場合、オプション設定でバックグラウンドスレッドのアクティブスタックが取得できます。1.6.2以降のバージョンからサポートします。
-
async_stack_enabled
の値をtrue
に設定するとアクティブになります。async_stack_enabled=false
-
スタックダンプの間隔は、フォアグラウンドアクティブスタックの設定に準じます。
active_stack_second=10
-
対象スレッド名を指定する場合は、
*
を使用して文字列パターンを指定します。async_thread_match=http*,abc*
スレッド名でスタックダンプ対象を識別します。
,
を使用して複数の一致を指定できます。 -
スタックの上位メソッドが
async_thread_parking
に登録されたクラス/メソッドの場合、 スレッドがパーキング状態にあると判断してダンプを生成しません。async_thread_parking_class=sun.misc.Unsafe
async_thread_parking_method=park