先决条件
- 请参阅 MSAL 浏览器中的性能 ,其中概述了应用程序可用于提高使用 MSAL 获取令牌的性能的技术。
- Node.js
测量性能
想要测量 MSAL Node 中身份验证流性能的应用程序可以使用 Node 的性能度量 API 或类似方式手动执行此操作。 下面是可收集的一些值得注意的数据点的列表:
| Data | Meaning | 建议 |
|---|---|---|
authType |
acquireToken* 用于令牌请求的 API |
用于标识使用情况。 |
correlationId |
用于令牌请求的相关性 ID。 可以通过 correlationId 中的属性获取此值 |
用于标识使用情况。 |
durationTotalInMs |
MSAL 中花费的总时间,包括网络调用和缓存访问 | 对总体高延迟(> 1 秒)发出警报。 值取决于令牌源。 来自缓存:一次缓存访问。 来自网络:两次缓存访问,外加两次 HTTP 调用。 |
durationInCacheInMs |
加载或保存令牌缓存持久性(例如 Redis)所花费的时间。 | 出现峰值时发出警报。 |
durationInHttpInMs |
对 IdP 进行 HTTP 调用所用的时间(例如Microsoft Entra ID)。 可以使用自定义网络客户端进行更精细的监视。 有关详细信息,请参阅配置和自定义网络示例 | 出现峰值时发出警报。 |
tokenSource |
令牌的源(即缓存与网络)。 可以通过 fromCache 中的属性获取此值 |
从缓存中检索令牌的速度快得多(例如,约 100 毫秒,而不是约 700 毫秒)。 可用于监视和报警缓存命中率。 与 durationTotalInMs 一起使用。 |
例如:
const { PerformanceObserver, performance } = require('node:perf_hooks');
const perfObserver = new PerformanceObserver((items) => {
items.getEntries().forEach((entry) => {
console.log(entry);
})
});
perfObserver.observe({ entryTypes: ["measure"], buffered: true });
// ...
performance.mark("acquireTokenByClientCredential-start");
const tokenResponse = await msalInstance.acquireTokenByClientCredential({
scopes: ["User.Read.All"],
});
performance.mark("acquireTokenByClientCredential-end");
performance.measure("acquireTokenByClientCredential", {
start: "acquireTokenByClientCredential-start"
end: "acquireTokenByClientCredential-end"
detail: {
tokenSource: tokenResponse.fromCache
correlationId: tokenResponse.correlationId
}
});
机密客户端应用程序的性能注意事项
由于机密客户端应用程序主要用于涉及并发处理请求的服务器端方案,因此我们建议将 MSAL ConfidenticalClientApplication (CCA) 实例的范围限定为每个用户、请求或会话。
每个请求都会创建一个全新的 CCA 实例,这意味着其默认的内存缓存起初不包含任何令牌,也不包含关于如何获取令牌的元数据。 因此,你创建的 CCA 实例应在令牌请求之前准备好,以避免性能不佳。
import {
ConfidentialClientApplication,
AuthenticationResult,
CryptoProvider,
OnBehalfOfRequest
} from "@azure/msal-node";
function getMsalInstance(partitionKey: string): ConfidentialClientApplication {
return new ConfidentialClientApplication({
auth: {
clientId: "ENTER_CLIENT_ID",
authority: "http://login.microsoftonline.com/ENTER_TENANT_ID"
cloudDiscoveryMetadata: "PROVIDE_STRINGIFIED_DISCOVERY_METADATA"
authorityMetadata: "PROVIDE_STRINGIFIED_AUTHORITY_METADATA"
},
cache: {
cachePlugin: new CustomCachePlugin(
this.cacheClientWrapper,
partitionKey
)
}
});
};
async function getToken(tokenRequest: OnBehalfOfRequest): Promise<AuthenticationResult | null> {
const partitionKey = await this.cryptoProvider.hashString(tokenRequest.oboAssertion);
const cca = getMsalInstance(partitionKey);
let tokenResponse = null;
try {
await cca.getTokenCache().getAllAccounts(); // required for cache read
tokenResponse = await cca.acquireTokenOnBehalfOf(tokenRequest);
} catch (error) {
throw error;
}
return tokenResponse;
};
更多信息,请参阅使用自定义分布式缓存插件的 (CCA) Web API。