分布式之Session共享

在上一篇博文中我们通过Nginx+IIS实现了一个简单的负载均衡,那么随之而来的问题就是多个站点在切换时如何共享Session信息,本篇介绍在.net中通过Redis实现分布式站点的Session共享,并且无需修改原项目的Session读取方式。

ASP.Net session存储方式

首先我们看下asp.net中session能采用的存储方式及优缺点。如下:

  1. InProc模式(进程内模式) ,为默认设置。优点是性能高无需跨进程读取,缺点是依赖asp.net进程,当进程崩溃重启时会丢失,并且在分布式的情况下无法多个站点共享。
  2. StateServer模式(状态服务器模式)。会话状态存储在一个名为ASP.Net状态服务的单独进程中,这确保了在重新启动Web应用程序时会保留会话状态,并让会话状态可用于网络中的多个Web服务器。
  3. SQL Server模式。会话状态存储到一个SQL Server数据库中。这确保了在重新启动Web应用程序时会保留会话状态,并让会话状态可用于网络中的多个Web服务器。
  4. Custom模式。此模式允许您指定自定义存储提供程序,例如分布式中常采用自定义模式将站点Session存储在Redis或Memcached中。
    本篇即采用Custom模式自定义存储提供程序将Session存储在Redis中。

Redis存储Session

采用Custom模块需要修改web.config配置文件中网站的sessionState节点的mode属性为Custom,另外我们需要写一个类实现SessionStateStoreProviderBase抽象类,通过实现抽象类的方法可以对Session自定义增删查改,目前微软已经有Redis存储的实现版本了,直接nuget安装RedisSessionStateProvider包即可,如下:
RedisSessionStateProvider
asp.net session共享
sessionState中将redis配置改为Redis服务器连接配置,然后我们新建一个mvc视图来测试多个站点下的Session读取和共享。Controler代码如下:

    public class HomeController : Controller
    {
        public ActionResult Index()
        {
            if (this.HttpContext.Session["MySessionTest"] == null)
            {
                this.HttpContext.Session["MySessionTest"] = string.Format("站点{0}创建的Session", Request.ServerVariables.Get("Server_Port").ToString());
            }
            return View();
        }
    
        public JsonResult GetSession()
        {
            var result = this.HttpContext.Session["MySessionTest"].ToString();
            return Json(new { isok = true, result = result }, JsonRequestBehavior.AllowGet);
        }

        public ActionResult About()
        {
            ViewBag.Message = "Your application description page.";

            return View();
        }

        public ActionResult Contact()
        {
            ViewBag.Message = "Your contact page.";

            return View();
        }
       
    }

在index action中我们写入了一个key=MySessionTest的session信息,并且将站点端口信息写入到了值中,然后提供了一个接口方法用来读取并返回session[“MySession”]。然后我们看下视图页面代码:

<div class="jumbotron">
    <h1>ASP.NET</h1>
    <p class="lead">ASP.NET is a free web framework for building great Web sites and Web applications using HTML, CSS and JavaScript.</p>
    <h3>
        服务器地址:@Request.ServerVariables.Get("Server_Name").ToString()
    </h3>
    <h3>
        服务器端口:@Request.ServerVariables.Get("Server_Port").ToString()
    </h3>
    <div>
        <input id="sessiontxt" /> <button onclick="GetSession()">读取Session["MySessionTest"]</button>
    </div>
</div>
    function GetSession() {
        $.ajax({
            type: "GET",
            url: "/Home/GetSession",
            xhrFields: { withCredentials: true },
            success: function (data) {
                if (data.isok == true) {
                    $("#sessiontxt").val(data.result);
                }
            }
        });

    }

功能很简单,显示当前站点的地址及端口信息,点击按钮会调用接口读取session信息并输出到文本框中。现在我们做一个测试,我们在IIS上新建三个站点8010/8020/8030都指向这个网站,然后我们分别访问三个网站查看session获取结果如下:
负载均衡下的Session共享
Redis共享SessIon
可以看到我们先访问的8010网站,session在进入8010网站的时候创建了session,在访问8020网站点击按钮获取session时获取到的session和8010是相同的,至此我们已经实现了多个站点的Session共享。配合我在上一篇博文中讲的负载均衡就实现了分布式系统各个web站点之间的session共享了。

上一篇:Nginx+IIS实现负载均衡

分布式前端session共享是一种实现分布式系统中实现前端用户会话的机制。在传统的单体应用中,前端会话通常可以直接存储在后端服务器的内存或数据库中,但在分布式系统中,由于涉及多个前端实例和后端服务实例,需要实现前端会话的共享,以保证用户在不同的前端实例间的状态一致性和无缝切换。 实现分布式前端session共享的常用方案包括: 1. 使用缓存中间件:可以通过使用像Redis或Memcached等缓存中间件,将前端会话数据存储在缓存中,实现多个前端实例之间的共享。前端实例可以通过访问同一个缓存中间件,来读取和写入会话数据。 2. 使用数据库存储:将前端会话数据存储在数据库中,通过数据库实现数据的共享。前端实例可以访问同一个数据库,来读取和写入会话数据。 3. 使用分布式协议:通过一致性哈希算法或其他分布式算法,将前端会话数据进行分片,然后分散存储在多个前端实例中。每个前端实例只需存储自己负责的会话数据,实现数据的共享与分布。 4. 使用共享存储:可使用像NFS(Network File System)这样的共享文件系统,将前端会话数据存储共享文件中,实现多个前端实例之间的数据访问共享。 无论选择哪种方案,需要注意的是要解决会话数据的一致性和并发访问的问题。可以采用同步策略、加锁机制或乐观锁等方法来保证会话数据的一致性。同时,还需要考虑到共享会话数据的性能要求,确保能够支持高并发和低延迟的访问。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值