Identity Server 4内存持续增长未释放问题求助(.NET Core 3.1+Azure)
我之前处理过类似的生产场景,给你几个实用的排查方向,应该能帮你定位到问题:
检查令牌存储方式:如果你的Identity Server用的是默认的
AddInMemoryPersistedGrants(),那这大概率是问题根源!InMemory存储不会自动清理过期的授权码、刷新令牌等条目,哪怕令牌已经失效,这些对象还是会一直留在内存里,日积月累导致内存持续上涨。解决办法是换成持久化存储,比如AddSqlServerPersistedGrantStore()或者AddRedisPersistedGrantStore(),这类存储会自动清理过期的令牌数据。排查Identity Server 4版本的已知Bug:3.1.3版本确实存在一些内存泄漏的已知问题,比如特定场景下刷新令牌的处理逻辑会导致对象无法被GC回收。你可以去官方GitHub仓库查看这个版本的issues,有没有和你场景匹配的案例。如果业务允许,尽量升级到Identity Server 4的同分支最新补丁版(注意和.NET Core 3.1的兼容性)。
用Azure诊断工具分析内存快照:Azure App Service自带了诊断工具,你可以在门户的「诊断和解决问题」模块里启用内存分析,或者抓取内存转储文件。也可以通过Application Insights跟踪内存使用趋势,查看哪些类型的对象占用了大量内存。如果本地能复现问题,用dotMemory或者Visual Studio的内存诊断工具分析快照,重点看是不是有大量
PersistedGrant对象或自定义业务对象没被回收。检查自定义代码的资源泄漏:看看你实现的
IResourceOwnerPasswordValidator或IClaimsPrincipalFactory有没有泄漏资源,比如数据库连接未释放、静态变量持有大对象(比如无过期策略的缓存集合)。另外检查依赖注入的生命周期配置,有没有把Scoped/Transient服务错误注册成Singleton,导致对象一直被容器持有无法回收。调整刷新令牌的配置:检查
AddIdentityServer()中的刷新令牌设置:如果RefreshTokenUsage是TokenUsage.ReUse,每次刷新都会保留旧令牌,导致存储条目越来越多;如果是TokenUsage.OneTimeOnly,旧令牌应被作废,但如果存储未正确清理也会有问题。另外RefreshTokenExpiration设为TokenExpiration.Absolute会让令牌到点失效,而Sliding可能导致令牌不断延长有效期,增加内存留存时间。排查.NET Core 3.1中间件问题:某些第三方中间件或.NET Core 3.1本身的中间件存在内存泄漏情况,比如日志组件、认证中间件的特定配置。你可以尝试逐步禁用自定义中间件,观察内存增长情况是否变化,以此定位问题点。
内容的提问来源于stack exchange,提问作者Rakshit

