問題
.NETエージェントが高スループットの.NETFrameworkアプリケーションに接続されている場合、少数の顧客が高いスレッド競合を観察していると報告しました。プロセスダンプとスタックトレースを確認すると、 AppDomain.GetData()
の呼び出しによって多くのスレッドがブロックされる可能性があります。
考えられる解決策
.NETエージェントのバージョン9.7では、.NETエージェントによるAppDomain
ストレージの使用を無効にする新しい環境変数が導入されました。
NEW_RELIC_DISABLE_APPDOMAIN_CACHING=true
注意
この環境変数は、 AppDomain.GetData()
へのエージェント呼び出しからのロック競合を排除しますが、この環境変数を有効にすると、.NETエージェントの合計オーバーヘッドが増加します。私たちのテストでは、これによりロックは少なくなりましたが、テストアプリケーションに接続された.NETエージェントでは最大アプリケーションスループットが低下しました。
この新しい構成オプションを試して、この問題が発生しているお客様からのフィードバックに非常に関心があります。この構成オプションを試してみる場合は、 GitHubリポジトリに.NETの問題を作成して、経験を説明してください。
原因
.NETエージェントは、メソッドを計測するためのメソッドシグネチャ情報にアクセスする必要があります。 .NET Frameworkアプリケーションのデフォルトでは、エージェントはリフレクションを介してこのメソッド情報をロードし、将来の使用のためにAppDomain
にキャッシュします。これは一般的な最適化を目的としていますが、この動作を取り巻くスレッドロックの競合が多く、サービスが遅くなったり応答しなくなったりする根本的な原因であると考えているお客様もいます。
Microsoftのソースコードを調べた後、 AppDomain.GetData()
を呼び出すと、実際にはグローバルロックが発生します。
.NETエージェントは.NETCoreアプリケーションに対してメソッド情報キャッシュスキームをまったく使用せず、同様のスレッドロック競合の問題を報告した顧客はいないため、.NETでエージェントが同じように機能するように環境変数を公開することにしました。フレームワークアプリケーション。