ASP.NET Core部署GCP CloudRun后Session变量随机返回null问题排查
以下是几个最可能导致该问题的核心原因:
Cloud Run实例扩缩容+内存Session的局限性
ASP.NET Core默认的Session存储是内存存储,每个Cloud Run容器实例都有独立的内存空间。当Cloud Run根据流量自动扩缩容时,新启动的实例不会共享已有实例的内存Session数据。如果后续请求被路由到新实例,就会读取不到之前存在旧实例里的CurrentProject值,返回null。另外,Cloud Run会自动回收空闲实例,当请求重新分配到刚启动的实例时也会出现同样问题。Session Cookie的SameSite与Secure配置不匹配
你设置了SameSiteMode.None,但现代浏览器要求使用SameSite=None的Cookie必须同时设置Secure=true(仅在HTTPS下发送)。Cloud Run默认提供HTTPS访问,但如果你的Session Cookie没有显式开启Secure属性,部分浏览器可能会在某些场景下拒绝发送Cookie,导致Session无法被识别,最终返回null。缺少会话亲和性(粘性会话)配置
Cloud Run默认不启用会话亲和性(Sticky Sessions),同一用户的请求可能被分发到不同的实例。即使你在某个实例中写入了Session,后续请求打到其他实例时就无法读取到该Session数据。不过即使开启粘性会话,也无法解决实例回收后的Session丢失问题,只是能减少这种情况的发生。Session过期时间的影响
ASP.NET Core Session默认过期时间是20分钟,如果用户的操作间隔刚好超过这个时间,Session会被自动清除。不过这种情况通常是固定间隔出现,和你描述的"随机连续多次为空"不太匹配,但也可以排查下是否有调整过过期时间。
建议的解决方向
- 替换Session的存储方式:使用分布式缓存(比如GCP Memorystore Redis)来存储Session数据,这样所有Cloud Run实例都能共享Session数据,从根本上解决多实例的Session隔离问题。
- 修正Cookie配置:在
AddSession时显式配置Cookie的Secure属性,同时确保SameSite和Secure的匹配:builder.Services.AddSession(options => { options.Cookie.SecurePolicy = CookieSecurePolicy.Always; options.Cookie.SameSite = SameSiteMode.None; // 可根据需求调整过期时间 options.IdleTimeout = TimeSpan.FromMinutes(30); }); - (可选)启用Cloud Run的会话亲和性:在Cloud Run服务配置中开启粘性会话,让同一用户的请求尽量路由到同一个实例,但这只是临时缓解方案,不能替代分布式存储。
内容的提问来源于stack exchange,提问作者niks

