• 第三节:解决Nginx负载均衡的Session共享问题【未完】


    一. 简介

    学习本节必须有以下几个基础:

    (1). Cookie和Session原理:https://www.cnblogs.com/yaopengfei/p/8057176.html

    (2). 进程外Session的概念和解决方案:https://www.cnblogs.com/yaopengfei/p/9583168.html

    (3). Core MVC中进程外Session的实现:https://www.cnblogs.com/yaopengfei/p/11270816.html

    1. 背景 

      当服务服务器有多台的,用nginx做负载均衡,这样同一个IP访问同一个页面会被分配到不同的服务器上,如果session不同步的话,就会出现很多问题,比如说登录成功后续操作拿不到Session里存的权限。

    2. 常用解决方案

    (1). IP-hash 策略

    (2). 借助Cookie来解决

    (3). 状态服务器Session,也是进程外Session中的一种,即所有的Session都存放在一台服务器中的内存里,其它应用服务器都访问这一台。

    (4). 基于SqlServer的进程外Session

    (5). 基于Redis的进程外Session 

    二. IP-Hash策略

       该技术能够将某个ip的请求定向到同一台后端,这样一来这个ip下的某个客户端和某个后端就能建立起稳固的session,仅需要在修改Nginx的配置,如下图:

     该方案有诸多的限制:

    (1). ip_hash要求nginx一定是最前端的服务器,否则nginx得不到正确ip,就不能根据ip作hash,比如:使用的是squid为最前端,那么nginx取ip时只能得到squid的服务器ip地址,用这个地址来作分流是肯定错乱的。

    (2). 如果nginx后端又有其它负载均衡,将请求又通过另外的方式分流了,那么某个客户端的请求肯定不能定位到同一台session应用服务器上。nginx后端只能直接指向应用服务器,或者再搭一个squid,然后指向应用服务器。

     

    三. Cookie替代策略 

     1. 原理

      session是存放在服务器端的,cookie是存放在客户端的,可以把用户访问页面产生的需要存在session里的信息,存放到cookie里面,就是以cookie为中转站。

      访问web服务器A,产生了session然后把它放到cookie里面,当你的请求被分配到B服务器时,服务器B先判断服务器有没有这个session,如果没有,再去看看客户端的cookie里面有没有这个session,如果也没有,说明session真的不存,如果cookie里面有,就把cookie里面的sessoin同步到服务器B,这样就可以实现session的同步了。

    2. 分析

      这种方法实现起来简单,方便,也不会加大数据库的负担,但是如果客户端把cookie禁掉了的话,那么session就无从同步了,这样会给网站带来损失。

      cookie的安全性不高,虽然它已经加了密,但是还是可以伪造的。

      这样会导致同一个用户的Session在多个服务器上存储,造成不必要的资源浪费。

    四. 状态服务器存储

     1. 说明

      比默认的进程内Session稍慢一点,比数据库Session快很多,存储空间比进程内的稍大一些, 但毕竟还是存储在内存中的,空间是有限,也会容易被挤爆。即所有的Session都存放在一台服务器中的内存里,其它应用服务器使用Session的时候都访问这一台。

    2. 步骤 (以MVC项目为例)

    (1). 以win10为例,运行services.msc,打开服务列表,找到【ASP.NET State Service】,右键启动即可。

     

    (2). 相关配置 

    在<system.Web>节点下加上下面一句话 <sessionState stateConnectionString="tcpip=127.0.0.1:42424" mode="StateServer">

    PS:状态服务器端口默认为:42424,在负载均衡下,需要把上述的ip改为一台业务服务器的ip,即其他业务服务器获取Session的时候都上这台上取,同时要把下面注册表中的  AllowRemoteConnection参数改为1,代表其他服务器也可以使用。

    如何修改默认端口?

       打开注册表 [HKEY_LOCAL_MACHINE/SYSTEM/ControlSet001/Services/aspnet_state/Parameters],其中:Port为端口号,十进制,默认即为42424; AllowRemoteConnection的值  0 代表仅能本机使用,1 代表供其他机器使用.

     

    五. 基于SQLServer 或 Redis

    1. 说明

      无论是基于SQLServer还是Redis,都是进程外Session,相比进程内Session,基于数据库的Session要慢一些, 但就SQLServer 和 Redis而言,肯定Redis要更快一些,二者的原理是一样的,都是把Session存放到数据库里,当有负载均衡的时候,无论把客户端的请求转发到哪台服务器,最终都是根据SessionId到数据库里取,从而解决了Session共享问题。

      下面重点介绍负载均衡下基于Redis的Session共享,以Core MVC为基础事先。(基于SQLServer的详见 https://www.cnblogs.com/yaopengfei/p/9583168.html  https://www.cnblogs.com/yaopengfei/p/11270816.html)

    2. 基于Redis的案例测试

    !

    • 作       者 : Yaopengfei(姚鹏飞)
    • 博客地址 : http://www.cnblogs.com/yaopengfei/
    • 声     明1 : 如有错误,欢迎讨论,请勿谩骂^_^。
    • 声     明2 : 原创博客请在转载时保留原文链接或在文章开头加上本人博客地址,否则保留追究法律责任的权利。
     
  • 相关阅读:
    *洛谷P1858 多人背包
    ZOJ3469 Food Delivery
    Hdu5115 Dire Wolf
    Codevs 2765 隐形的翅膀
    Hdu4055 Number String
    Codevs 1300 文件排版
    洛谷 P1412 经营与开发
    Codevs 4357 不等数列
    codevs 3333 高级打字机
    Bzoj 1086: [SCOI2005]王室联邦
  • 原文地址:https://www.cnblogs.com/yaopengfei/p/12518819.html
Copyright © 2020-2023  润新知