【问题标题】:Session lost after app restart with Redis + ASP.NET Core 3.1 + Ubuntu 18.04使用 Redis + ASP.NET Core 3.1 + Ubuntu 18.04 重新启动应用程序后会话丢失
【发布时间】:2021-01-05 17:01:35
【问题描述】:

我正在尝试使用 Redis 缓存来维护 ASP.NET Core MVC 3.1 网站上应用重新启动之间的会话状态。但是,当应用重新启动时,所有会话信息都会丢失。

在我的本地 (Mac) 机器上的开发环境中一切正常,但是当部署到 Ubuntu 18.04 服务器时,所有会话信息在重新启动之间都会丢失。

我的Startup.cs 文件中的相关代码看起来像(删除了很​​多不相关的东西):

        public void ConfigureServices(IServiceCollection services)
        {
            services.AddHttpContextAccessor();          
            services.AddStackExchangeRedisCache(options =>
            {
                options.Configuration = "localhost";
                options.InstanceName = "sessionState";
            });
            
            services.AddSession(options =>
            {
                // Set a short timeout for easy testing.
                options.IdleTimeout = TimeSpan.FromMinutes(600);
            });

            var mvc = services.AddControllersWithViews();
            #if (DEBUG)
            mvc.AddRazorRuntimeCompilation();
            #endif
            
            services.AddMvc(option => option.EnableEndpointRouting = false);
        }

        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            app.UseSession();
            app.UseRouting();
            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllers();
            });
        }
    }           

服务器是 Ubuntu 18.04 服务器,运行 ASP.NET Core 3.1 运行时。

Redis 已安装并正在运行,我可以看到使用 redis-clikeys * 的会话密钥列表。运行sudo systemctl status redis 输出:

● redis-server.service - Advanced key-value store
   Loaded: loaded (/lib/systemd/system/redis-server.service; enabled; vendor preset: enabled)
   Active: active (running) since Tue 2021-01-05 03:36:30 UTC; 1h 10min ago
     Docs: http://redis.io/documentation,
           man:redis-server(1)
  Process: 8916 ExecStop=/bin/kill -s TERM $MAINPID (code=exited, status=0/SUCCESS)
  Process: 8920 ExecStart=/usr/bin/redis-server /etc/redis/redis.conf (code=exited, status=0/SUCCESS)
 Main PID: 8950 (redis-server)
    Tasks: 4 (limit: 1115)
   CGroup: /system.slice/redis-server.service
           └─8950 /usr/bin/redis-server 127.0.0.1:6379

我已经尝试了各种方法来让会话在应用重新启动之间保持活跃,但我觉得我错过了一些明显的东西。提前感谢您的帮助。

【问题讨论】:

    标签: asp.net-core redis


    【解决方案1】:

    我正在回答我自己的问题,主要是希望这将在未来对其他人有所帮助。这是一个非常棘手的问题,并且与数据保护功能在 Linux 服务器上的工作方式有关。

    解决方案的症结在 dotnetcore GitHub 上的这个问题中表达得非常巧妙(参见 https://github.com/dotnet/aspnetcore/issues/25801#issuecomment-715440092):

    您在 Linux 上。数据保护无法在没有配置的情况下在 linux 上保留密钥,因此它使用内存来保存密钥环,当应用程序重新启动时,或者您点击另一个应用程序实例时,密钥环是不同的。您的日志将在开始时出现警告。

    您需要决定密钥环的存储位置(文件系统、redis、Azure 数据存储,完全是其他东西)并在您的应用中配置数据保护以使用它。

    在我的情况下,实际的解决方案是将数据保护密钥与会话一起存储在 Redis 缓存中(我认为将其存储在任何地方,但默认值会起作用)。我在ConfigureServices 方法中添加了以下内容:

    var redis = ConnectionMultiplexer.Connect("localhost");
    services.AddDataProtection().PersistKeysToStackExchangeRedis(redis, "DataProtectionKeys");
    

    您还需要添加Microsoft.AspNetCore.DataProtection.StackExchangeRedis nuget

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-09-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-07-24
      • 2011-04-02
      • 1970-01-01
      相关资源
      最近更新 更多