問題
.NET エージェントが高スループットの.NET Frameworkアプリケーションに接続されている場合、一部の顧客からスレッドの競合が頻繁に発生するという報告がありました。 プロセス ダンプとスタックトレースを確認すると、多くのスレッドが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でエージェントが同じように機能するように環境変数を公開することにしました。フレームワークアプリケーション。