Asp.net core AspNetCore.Session-Distributed Cache在分布式服务器上保持超时

Asp.net core AspNetCore.Session-Distributed Cache在分布式服务器上保持超时,asp.net-core,distributed-caching,web-farm-framework,Asp.net Core,Distributed Caching,Web Farm Framework,我有一个AspNetCore(core 2.1)web应用程序,它在任何单服务器环境中都可以正常工作,但在有两个负载平衡web服务器的环境中几秒钟后就会超时 这是我的startup.cs和其他类,以及我的AppSessionState表的屏幕截图。我希望有人能给我指出正确的道路。我花了2天的时间在这上面,找不到任何需要设置的东西,也找不到我正在做的有什么问题 以下代码的一些解释: 如图所示,我已按照以下步骤配置应用程序以使用分布式SQL Server缓存,并拥有一个helper静态类HttpSe

我有一个AspNetCore(core 2.1)web应用程序,它在任何单服务器环境中都可以正常工作,但在有两个负载平衡web服务器的环境中几秒钟后就会超时

这是我的
startup.cs
和其他类,以及我的
AppSessionState
表的屏幕截图。我希望有人能给我指出正确的道路。我花了2天的时间在这上面,找不到任何需要设置的东西,也找不到我正在做的有什么问题

以下代码的一些解释:

如图所示,我已按照以下步骤配置应用程序以使用分布式SQL Server缓存,并拥有一个helper静态类
HttpSessionService
,该类处理从会话状态添加/获取值的操作。此外,我还有一个会话超时属性,我对每个控制器进行注释,以控制会话超时。几秒钟后或在应用程序中单击后,当每个控制器动作发出此呼叫时

HttpSessionService.Redirect()

Redirect()
方法从此行获取空用户会话,这会导致应用程序超时

var userSession=GetValues(SessionKeys.User)

我在两台服务器上都安装了两个VS调试器,我注意到,即使所有会话都连接到其中一个调试器实例(一台服务器),AspNet会话仍然为上述
userSession
值返回NULL

同样,这只发生在分布式环境中,也就是说,如果我停止其中一个web服务器上的一个站点,一切正常

我已经在不同的页面中查看并使用SQLServer实现了会话状态分布式缓存,如下所述(相同)

我确实看到会话被写入我创建的
AppSessionState
表中,但应用程序在有2台负载平衡服务器的环境中继续超时

Startup.cs:

public void配置服务(IServiceCollection服务)
{
//针对SQLServer的会话状态分布式缓存配置。
var aspStateConnStr=ConfigurationManager.ConnectionString[“ASPState”].ConnectionString;
var aspSessionStateSchemaName=_config.GetValue(“AppSettings:aspSessionStateSchemaName”);
var aspSessionStateTbl=_config.GetValue(“AppSettings:AspSessionStateTable”);
services.AddDistributedSqlServerCache(选项=>
{
options.ConnectionString=aspStateConnStr;
options.SchemaName=aspSessionStateSchemaName;
options.TableName=aspSessionStateTbl;
});
....
services.AddSession(选项=>
{
options.IdleTimeout=1200;
options.Cookie.HttpOnly=true;
options.Cookie.IsEssential=true;
});
services.AddSingleton();
...
services.AddMvc().AddJsonOptions(opt=>opt.SerializerSettings.ContractResolver=new CamelCasePropertyNamesContractResolver());
}
public void Configure(IApplicationBuilder应用程序、IHostingEnvironment环境、IApplicationLifetime生存期、IDistributedCache distCache)
{
var distCacheOptions=new DistributedCacheEntryOptions()
.SetSlidingExpiration(时间跨度从分钟(5));
//会话状态分布式缓存配置。
lifetime.ApplicationStarted.Register(()=>
{
var currentTimeUTC=DateTime.UtcNow.ToString();
byte[]encodedCurrentTimeUTC=Encoding.UTF8.GetBytes(currentTimeUTC);
Set(“cachedTimeUTC”,encodedCurrentTimeUTC,distCacheOptions);
});
if(env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseDatabaseErrorPage();
}
其他的
{
app.UseExceptionHandler(“/Home/Error”);
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseSession();//必须在app.UseMvc()之前调用此函数
app.UseMvc(路由=>
{
routes.MapRoute(
名称:“默认”,
模板:“{controller=Home}/{action=Index}/{id?}”);
});
HttpSessionService.Configure(app.ApplicationServices.GetRequiredService(),distCache,distCacheOptions);
}
HttpSessionService(助手类):

公共类HttpSessionService
{
专用静态IHttpContextAccessor\u httpContextAccessor;
私有静态IDistributedCache _distributedCache;
私有静态会话_session=>httpContextAccessor.HttpContext.session;
公共静态无效配置(IHttpContextAccessor httpContextAccessor,IDistributedCache distCache)
{
_httpContextAccessor=httpContextAccessor;
_distributedCache=distCache;
}
公共静态无效设置值(字符串键,T值)
{
_session.Set(键、值);
}
公共静态GetValues(字符串键)
{
var sessionValue=\u session.Get(键);
return sessionValue==null?默认值(T):sessionValue;
}
公共静态bool重定向()
{
var结果=假;
var userSession=GetValues(SessionKeys.User);
if(userSession==null | | userSession?.IsAuthenticated==false)
{
结果=真;
}
返回结果;
}
}
SessionTimeoutAttribute:

公共类SessionTimeoutAttribute:ActionFilterAttribute
{
公共重写无效OnActionExecuting(ActionExecutingContext上下文)
{
var redirect=HttpSessionService.redirect();
如果(重定向)
{
context.Result=新的重定向结果(“~/Account/SessionTimeOut”);
返回;
}
基地组织
services.AddDistributedSqlServerCache(options =>
{
    options.ConnectionString = aspStateConnStr;
    options.SchemaName = aspSessionStateSchemaName;
    options.TableName = aspSessionStateTbl;
    options.ExpiredItemsDeletionInterval = null;
});