最近、通常の Windows ストア アプリの運用展開を行いました。数日間は問題なく動作していましたが、数日後にはパフォーマンスが非常に遅くなります。私たちのアプリケーションは、ストアアプリがゲートキーパーとゲートキーパーにヒットしてサービスを停止し、データベースにサービスを停止するゲートキーパーパターンに従います (すべてクラウドでホストされます)。
分析した結果、Gatekeeper Web アプリの応答に時間がかかっていることがわかりました。Web アプリのメモリ ダンプを取得し、WinDbg を使用して分析したところ、ロック カウントが 2 と測定される AAD アクセス トークンの問題が見つかりました。メモリ ダンプから取得した結果を添付します。
アクセストークンを取得するための実際のコードは次のとおりです(証明書ベースの認証を使用しています)
public static void GetCert()
{
try
{
var clientAssertionCertPfx = Helper.FindCertificateByThumbprint(WebConfigurationManager.AppSettings["CertificateThumbPrint"]);
AssertionCert = new ClientAssertionCertificate(WebConfigurationManager.AppSettings["ida:ClientID"], clientAssertionCertPfx);
}
catch (Exception ex)
{
throw ex;
}
}
public static async Task<string> GetAccessToken(string authority, string resource, string scope)
{
try
{
string userName = "";
GetCert();
var context = new AuthenticationContext(authority, TokenCache.DefaultShared);
AuthenticationResult result = null;
var bootstrapContext = ClaimsPrincipal.Current.Identities.First().BootstrapContext as System.IdentityModel.Tokens.BootstrapContext;
if (bootstrapContext != null)
{
userName = ClaimsPrincipal.Current.FindFirst(ClaimTypes.Upn) != null ? ClaimsPrincipal.Current.FindFirst(ClaimTypes.Upn).Value : ClaimsPrincipal.Current.FindFirst(ClaimTypes.Email).Value;
if (!string.IsNullOrEmpty(bootstrapContext.Token))
{
UserAssertion userAssertion = new UserAssertion(bootstrapContext.Token, "urn:ietf:params:oauth:grant-type:jwt-bearer", userName);
AuthenticationContext authContext = new AuthenticationContext(authority);
result = await authContext.AcquireTokenAsync(resource, AssertionCert, userAssertion);
return result != null ? result.AccessToken : null;
}
return null;
}
else
{
return null;
}
}
catch (Exception ex)
{
LogErrorDetails objLogDetails = new LogErrorDetails();
ErrorLog objErrorLog = new ErrorLog();
objLogDetails.ErrorDescription = ex.Message;
objLogDetails.ErrorNumber = ex.HResult;
objLogDetails.strErrorContext = "Helper";
objLogDetails.strErrorContextArea = "GetAccessToken";
objLogDetails.strTrace = ex.StackTrace;
await objErrorLog.InsertErrorLog(objLogDetails);
return null;
}
}
このコードをローカルで実行している間、アクセス トークンに問題はなく、高速です。実稼働環境でのみパフォーマンスが非常に遅く、アクセス トークンやその他のパラメーターが原因かどうかはわかりません。
私たちのコードで何が問題だったのかを分析するのを手伝ってくれませんか。