首页 > 解决方案 > ASP.NET Core + Redis + nginx 的会话 id 总是在变化

问题描述

示例项目https://github.com/xingyu217/Redis-nginx-aspnetcore-session nginx.config:

upstream study_server{
        server localhost:8011 weight=1;
        server localhost:8013 weight=1;
    #server localhost:8014 weight=1;
    #server 172.17.16.147:8012 weight=2;
    #server 172.17.16.147:8011 weight=2;
    }
    server {
        listen       80;
        server_name  localhost;

        #charset koi8-r;

        #access_log  logs/host.access.log  main;

        location / {
            #root   html;
            #index  index.html index.htm;
        proxy_pass http://study_server/;
            proxy_cookie_path ~*^/.* /;
        proxy_redirect off;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
        }

获取会话 id:ViewBag.seId= HttpContext.Session.Id ;

启动.cs:

public void ConfigureServices(IServiceCollection services)
        {
            services.Configure<CookiePolicyOptions>(options =>
            {
                // This lambda determines whether user consent for non-essential cookies is needed for a given request.
                options.CheckConsentNeeded = context => true;
                options.MinimumSameSitePolicy = SameSiteMode.None;
            });

            //services.AddDistributedMemoryCache();

            services.AddDistributedRedisCache(options =>
            {
                options.Configuration = Configuration.GetConnectionString("RedisConnection");
                options.InstanceName = "master";
            });
            services.AddSession(options =>
            {
                options.IdleTimeout = TimeSpan.FromSeconds(100);
                //options.Cookie.HttpOnly = true;
            });
            //services.AddSession();
            services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                app.UseExceptionHandler("/Home/Error");
                app.UseHsts();
            }

            //app.UseDeveloperExceptionPage();
            //app.UseHttpsRedirection();
            app.UseStaticFiles();
            app.UseCookiePolicy();
            app.UseSession();
            app.UseMvc(routes =>
            {
                routes.MapRoute(
                    name: "default",
                    template: "{controller=Home}/{action=Index}/{id?}");
            });
        }

访问 URL:localhost 并反复刷新,会话 id 会一直在变化。

我检查了 redis 服务器中的密钥,它总是在刷新页面时生成新密钥。(例如masterdef69307-fbd3-c6ed-91d2-009b2306f902)

如果我只使用服务器(本地主机:8011):

upstream study_server{
        server localhost:8011 weight=1;
        #server localhost:8013 weight=1;
    #server localhost:8014 weight=1;
    #server 172.17.16.147:8012 weight=2;
    #server 172.17.16.147:8011 weight=2;
    }

会话 ID 不会更改。

任何人都知道这将不胜感激。

谢谢

标签: nginxredisasp.net-core-mvc

解决方案


我实际上无法在具有配置的 mac 上重现该问题(2 个本地服务器通过 nginx 负载平衡并连接到相同的本地 redis 分布式缓存)

无论如何,如果适用,您是否尝试过ip_hash在 nginx 上游模块中启用?

nginx 文档中的会话持久性部分:

如果需要将客户端绑定到特定的应用程序服务器——换句话说,使客户端的会话“粘性”或“持久”,总是试图选择特定的服务器——ip-hash 负载平衡机制可以是用过的。

upstream study_server{
    ip_hash;
    server localhost:8011 weight=1;
    server localhost:8013 weight=1;
    #server localhost:8014 weight=1;
    #server 172.17.16.147:8012 weight=2;
    #server 172.17.16.147:8011 weight=2;
}

如果这不能解决您的问题,请查看堆栈交换上的类似问题:


推荐阅读