tech.guitarrapc.cóm

Technical updates

NewRelicで特定のアプリケーションプールをプロファイルしないようにする

NewRelic は、PHP や Ruby、Javaだけでなく .NET のプロファイリングも優れています。

今回は、ASP.NET のアプリケーションの前段に ARR を使ったリバースプロキシを置いた時に、アプリケーション本体のみをプロファイルさせるための方法について説明します。

目次

事前に読んでおくといいもの

  • そもそも NewRelic Agent のコンフィグをどこでやるか把握しましょう

https://docs.newrelic.com/docs/agents/net-agent/installation-configuration/net-agent-configuration

  • .NET でできないことも把握しましょう

https://docs.newrelic.com/docs/agents/net-agent/installation-configuration/known-issues-net

やりたいこと

IIS 上に、ASP.NET MVC なアプリをホスティングしているとしましょう。

ここで、前段に ARR(Application Request Routing) を利用した リバースプロキシを置いているとします。よくある nginx を前段において、アプリをバックエンドをIISで組んでいるケースと思ってください。

つまり以下のような構成です。

f:id:guitarrapc_tech:20150120053644p:plain

さて、NewRelic にやらせたいことの1つはアプリケーションのモニタリング・監視ですね。この辺がピンとこない方は、@IT で id:kkamegawa さんが簡潔にきっちりまとめられている記事が参考になるでしょう。

このNewRelic による監視をもう少し実用面で考えます。

.NET Agent の副作用は凄まじい

さて、このまま .NET Agent を入れて問題ないでしょうか?

NewRelic .NET Agent は、Ruby や PHP の Agent と同様にプロファイルします。さて、どこでというと、このケースでは IIS に dll を突っ込んでです。

結果どうなるかというと、アプリケーションのパフォーマンスが低下します。アプリの構成にもよりますが、30%~50%弱影響を受けるケースもざらにあります。

監視はしたいけど、パフォーマンスをむやみに下げたくないですよね?特に IIS 上で、複数のWebサイトを同居させていている場合は顕著です。

アプリケーション と リバースプロキシではプロファイル制御したい

さらに今回の構成のようなリバースプロキシのサイトでもプロファイルが走ると、アプリケーションのThroughputだけ見たくても リバースプロキシサイト分が追加されて2倍になります。これは良くない。大変良くない。

リバースプロキシは単純にリダイレクト書けるだけなので、NewRelic .NET Agent を走らせる意味が(ほぼ)皆無です。無駄といえます。

とすると、同じIIS 上で プロファイルを走らせるサイトと走らせないサイトが出てきますね?これをどうやるかが本題です。

つまりこれを目指します。

f:id:guitarrapc_tech:20150120061814p:plain

NewRelic のプロファイラを制御する

IIS 上の設定

Webサイトごとにアプリケーションプールは分離させよう

IIS の WebSite は、WorkerProcess(w3wp.exe) を アプリケーションプール単位で動作させています。

NewRelic .NET Agent は、WebSite単位でプロファイルをしているのですが、その対象はアプリケーションプールです。Webサイトごとにアプリケーションプールを分離させて置くことは大事です。

アプリケーションプールの実行ユーザーが問題となる

WorkerProcess を何で動かしているかは NewRelic .NET Agent の設定に関して影響します。

ふつーは ApplicationPoolIdentity でしょう。しかし、アクセス制御をしたいなど多くのシーンではSpecific Userにしていることが多いと思います。このSpecific Userの時に困ったことになります。

いずれのパターンでも対応可能ですし後述しますが、自分がなぜそのアプリケーション実行ユーザーにしているかは把握しておくことを推奨します。

newrelic.config は罠

さて、NewRelic Agent は、newrelic.config で制御可能と NewRelic doc には書いてあります。セクションとしては instrumentation Section の Applications element (instrumentation)がいかにもそれっぽいでしょう。

https://docs.newrelic.com/docs/agents/net-agent/installation-configuration/net-agent-configuration

f:id:guitarrapc_tech:20150120054749p:plain

結論からいうと、これではアプリケーションプール単位での制御ができないケースがあります。

どういうことかというと、ApplicationPool を ApplicationPoolIdentity ではなく、Specific User で動かしていると NewRelic Agent がアプリケーションプール名を取得できません。なんてこった!

NewRelic agent は、IISRESET でプロファイルが再開された時にログを吐くのですが、そこで ApplicationPool 名をとれているか確認できます。

This application pool () is not explicitly configured to be
アプリケーションプールが誰で実行されていてもプロファイルを制御する

newrelic.config でアプリケーションプール単位の制御ができないことがわかりました。

ではどうするか。そのヒントはここにあります。(何と答えが NewRelic doc上にない)

https://docs.newrelic.com/docs/agents/net-agent/instrumentation/instrumenting-non-iis-apps

f:id:guitarrapc_tech:20150120055909p:plain

これがポイントです。

<add key="NewRelic.AgentEnabled" value="true" />

では、IIS のWebサイト単位でどうやって制御するかといえば web.config です。(user.config で転換している場合はそっちでok)

プロファイルを取りたくないサイトに対して、アプリケーション名を明示して、プロファイルの実行を false とすれば ok です。(プロファイルを取りたい場合は、true にしましょう。)

<appSettings>
  <add key="NewRelic.AppName" value="my_web_app" />
  <add key="NewRelic.AgentEnabled" value="false" />
</appSettings>

あとは、ASP.NET アプリをデプロイした際に NewRelicのプロファイルはこの web.configに従ってプロファイルを停止します。

まとめ

NewRelic Profiler の制御は大事です。現在 NewRelic.config は使わない方向に NewRelic は移行しており、Online で大体設定可能になっています。つまりNewRelic.config オワコン。

ASP.NET に限らず、プロファイルの制御は アプリサイドのコンフィグで可能なので web.config.exe.config で制御してください。

特にリバースプロキシを持っている IIS の場合は必須ですよ。お気を付けて。

ずっと書こうと思っていながら1か月以上放置していました*1

*1:いつも通り