You need to enable JavaScript to run this app. .NET Core 2.2下IMemoryCache在服务器端无法命中、反复触发SQL查询的问题排查
优惠活动
大模型
产品
解决方案
定价
更多

.NET Core 2.2下IMemoryCache在服务器端无法命中、反复触发SQL查询的问题排查

.NET Core 2.2 下IMemoryCache服务器端失效的常见原因

核心前提:IMemoryCache是进程内缓存,缓存数据存储在当前应用进程的私有内存空间,不跨进程、不跨服务器、不跨应用实例共享


高概率直接触发问题的原因

  • 多进程/多实例部署导致缓存隔离
    如果服务器端部署时存在以下配置,会直接导致缓存看似完全失效:

    • IIS应用程序池开启Web Garden(最大工作进程数>1),多个w3wp.exe进程并行处理请求,每个进程的内存空间完全隔离,各自维护独立的MemoryCache实例。请求被负载分发到不同进程时,会因为其他进程没有缓存值直接触发数据库查询
    • 多服务器负载均衡、容器化多Pod/多实例部署时,每个实例的进程内存独立,单实例写入的缓存对其他实例不可见

    这类场景下本地单进程调试运行时不会触发,部署后因为多实例分流,从数据库监控视角就会看到SQL被反复执行,表现为缓存完全不生效

  • 应用进程频繁重启/回收导致缓存清空
    IMemoryCache的生命周期完全依附于当前应用进程,进程销毁后所有缓存值会被清空。如果服务器端存在以下配置,会导致缓存反复丢失:

    • IIS应用程序池配置了空闲超时(默认20分钟无请求即回收进程),如果站点访问量低、请求间隔大于空闲超时时间,每次请求到达时进程已经被回收,缓存早已清空,会直接触发查库
    • 应用程序池配置了固定时间间隔回收、内存阈值触发回收,或程序未捕获的异常导致进程崩溃重启,都会清空所有缓存值

    本地Debug调试时进程会一直保持运行,不会自动回收,因此能正常命中缓存

  • 依赖注入配置错误导致缓存实例非单例
    .NET Core 内置的AddMemoryCache()方法默认会将IMemoryCache注册为单例服务。如果服务器端的依赖注入配置被修改为非单例生命周期,例如:

    // 错误的注册方式,会导致每次解析拿到新的缓存实例
    services.AddScoped<IMemoryCache, MemoryCache>();
    services.AddTransient<IMemoryCache, MemoryCache>();
    

    跨请求时每次解析得到的都是全新的MemoryCache对象,之前写入的缓存值完全无法被后续请求读取,表现为缓存完全不生效。本地Debug时因为请求量小、服务解析频率低,可能短时间内复用同一个实例不会暴露问题。


代码实现层面的潜在隐患

  • 当前实现中使用new Task(() => {...}).Start()实现的后台刷新逻辑是未被宿主托管的裸任务:
    • 这类任务不受ASP.NET Core生命周期管理,请求结束后可能被线程池提前终止,或在进程回收时直接丢失,导致缓存无法按时刷新
    • 任务内部使用.Result同步等待异步请求,存在线程阻塞、死锁的风险,一旦抛异常会被静默吞掉,导致缓存刷新失败
  • 异常处理逻辑缺失:当前代码只写了try块未展示catch分支的处理逻辑,如果写缓存、拉取数据的过程中抛出异常,异常被静默捕获后会导致缓存值永远无法写入,后续每次请求都会触发查库

内容的提问来源于stack exchange,提问作者tknkrtl

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.11.11 22:15:05