session保持与负载均衡

首先介绍一下负载均衡和session,并且以Nginx和session为例:

1.负载均衡

目的是通过反向代理服务器(Nginx)使得后端的服务器负载保持均衡,尽量避免某一个后端服务器过负载,从而影响服务。
Nginx提供的负载均衡策略:
(1)加权轮询(静态加权)
(2)当前最小连接数
(3)ip_hash
(4)url_hash(第三方模块)
其中:ip_hash也有不好的地方就是,假如其中的一台服务器down掉的话,映射到这台的服务器的用户就无法获得服务了,并且很难做到负载均衡。

2.Session保持

可以发现一个问题:
通过轮询的方式,不能保证同一个用户的或者同一个ip的用户能够固定的访问的某个后端服务器上;但是ip_hash很难做到像轮询那样的负载均衡。

先说一下session和cookie为何物:
session 是一个抽象概念,开发者为了实现中断和继续等操作,将 user agent 和 server 之间一对一的交互,抽象为“会话”,进而衍生出“会话状态”,也就是 session 的概念。而 cookie 是一个实际存在的东西,http 协议中定义在 header 中的字段。
而我们今天常说的 “session”,是为了绕开 cookie 的各种限制,通常借助 cookie 本身和后端存储实现的,一种更高级的会话状态实现。具体到实现,session 因为 session id 的存在,通常要借助 cookie 实现,但这并非必要,只能说是通用性较好的一种实现方案。并且session真的是什么对象都可以保存的。

负载均衡进行请求分发的时候保证每个客户端固定的访问到后端的同一台应用服务器。例如:从登录=》拍得东西=》添加地址=》付款,这是一个一系列的过程,也可以理解成一次操作过程,所有这一系列的操作过程都应当由一台服务器完成,而不能被负载均衡器分配到不同的服务器上。
会话保持都会有时间的限制(映射到固定某一台的服务器除外,如:ip_hash);这样可以减少需要同步session的情况,但是不能杜绝。所以session同步/共享还是要做的。

3.Session同步/共享

在做了web集群后,首先考虑session同步问题,因为通过负载均衡后,同一个IP访问同一个页面会被分配到不同的服务器上,如果session不同步的话,一个登录用户,一会是登录状态,一会又不是登录状态。所以本文就根据这种情况给出三种不同的方法来解决这个问题:

1.粘性session

通过会话标识是应用层的信息,那么负载均衡设备要将同一个会话请求都保存到同一个web服务器上。
缺点
(1)就要进行应用层的解析,这个开销比在传输层大。
(2)此时,负载均衡器变成了一个有状态的节点,要将会话保存到具体web服务器的映射,和无状态的节点相比,内存更大,容灾更麻烦。

2.服务器之间做同步:

如果做过数据库读写分离的都该知道,读写分离的时候,其实读的是从库,写的是主库,但是主库的信息会更新到从库,不考虑读写时间,我们可以认为从库和主库的数据是一致的,这个一致性主要靠同步来实现的。
在处理session的时候,我们同样可以采用这样的策略,在负载均衡设备上,无需动任何手脚,只进行无状态分发,反正分发到哪个服务器上,我之前的session都有,木事。
缺点
(1)同步session造成了网络带宽的开销,只要session数据有变化,就需要将数据同步到其他服务器上,机器越多,同步带来的网络开销就越大。
(2)每台web服务器都要保存所有的session信息,如果整个集群的session数据很多,每台应用服务器就会保存非常多的session数据,严重占用内存。

3.利用redis共享session

既然嫌弃同步麻烦,那就把所有的session数据都拿出来,放到单独的地方,可以是单独数据库,或其他分布式存储系统,前面负载均衡器还是无状态转发,应用服务器每次读写session,都到相同的地方来取。
他可以把web服务器中的内存组合起来,成为一个大内存,不管是哪个服务器产生的sessoin都可以放到这个”大内存”中,所有其他服务器的都可以使用。
优点
以这种方式来同步session,不会加大数据库的负担,并且安全性比用cookie大大的提高,把session放到内存里面,比从文件中读取要快很多。
缺点
(1)读写session数据引入了网络操作,这相对于本机的数据读取来说,问题就在于存在延时不稳定性,但是考虑到应用服务器跟session存储设备的通信均发生在内容,so,take it easy!
(2)如果集中进行session存储,就要考虑到当session服务器发生问题的时候,会影响我们整个链条的使用。

4.利用cookie同步session :

就是把用户访问页面产生的session放到cookie里面,就是以cookie为中转站。你访问web服务器A,产生了session把它放到cookie里面了,你访问被分配到web服务器B,这个时候,web服务器B先判断服务器有没有这个session,如果没有,在去看看客户端的cookie里面有没有这个session,如果也没有,说明session真的不存,如果cookie里面有,就把cookie里面的sessoin同步到web服务器B,这样就可以实现session的同步了。
缺点
cookies长度限制:因为cookie可以携带的数据长度是有限制的;
安全性:可以加密,但是还是可以伪造;
带宽消耗;
性能:每次http的请求跟响应都带有session数据,影响并发性能;因为对web服务器来说,在同样的情况下,响应的结果输出越少,支持的并发请求越多。

猜你喜欢

转载自blog.csdn.net/qiangzhenyi1207/article/details/80037494