前言
在我们给Web站点使用负载均衡之后,必须面临的一个重要问题就是Session的处理办法,无论是PHP、Python、Ruby还是Java,只要使用服务器保存Session,在做负载均衡时都需要考虑Session的问题。
问题在哪里?如何处理?
会话保持(案例:Nginx、Haproxy)
会话复制(案例:Tomcat)
会话共享(案例:Memcached、Redis)
问题在哪里?
从用户端来解释,就是当一个用户第一次访问被负载均衡代理到后端服务器A
并登录后,服务器A
上保留了用户的登录信息;当用户再次发送请求时,根据负载均衡策略可能被代理到后端不同的服务器,例如服务器B
,由于这台服务器B
没有用户的登录信息,所以导致用户需要重新登录。这对用户来说是不可忍受的。所以,在实施负载均衡的时候,我们必须考虑Session
的问题。
在负载均衡中,针对Session
的处理,我们一般有以下几种方法:
Session 保持
Session 复制
Session 共享
会话保持
Session
保持(会话保持)是我们见到最多的名词之一,通过会话保持,负载均衡进行请求分发的时候保证每个客户端固定的访问到后端的同一台应用服务器。会话保持方案在所有的负载均衡都有对应的实现。而且这是在负载均衡这一层就可以解决Session
问题。
Nginx 做负载均衡的Session****保持
对于Nginx
可以选用Session
保持的方法实行负载均衡,nginx
的upstream
目前支持5
种方式的分配方式,其中有两种比较通用的Session
解决方法,ip_hash
和url_hash
。注意:后者不是官方模块,需要额外安装。
ip_hash
每个请求按访问ip的hash结果分配,这样每个访客固定访问一个后端服务器,达到了Session保持的方法。
例:
upstream bakend ip_hash
server192.168.0.11:80
server192.168.0.12:80
Haproxy做负载均衡的Session保持
Haproxy
作为一个优秀的
反向代理和负载均衡软件,也提供了多种Session
保持的方法,下面列举了两种最常用的:源地址 Hash
haroxy 将用户IP经过hash计算后指定到固定的真实服务器上(类似于nginx 的ip hash 指令)
配置指令:balancesource
**使用cookie ****进行识别 **
也就是Haproxy在用户第一次访问的后在用户浏览器插入了一个Cookie,用户下一次访问的时候浏览器就会带上这个Cookie给Haproxy,Haproxy进行识别。
配置指令:cookie SESSION_COOKIE insert indirect nocache
配置例子如下:
cookie SERVERID insert indirect nocacheserver web01 .56.11:8080 check cookie web01
server web02 .56.12:8080 check cookie web02
会话保持的缺点:
会话保持看似解决了Session
同步的问题,但是却带来的一些其它方面的问题:
负载不均衡了:由于使用了Session保持,很显然就无法保证负载绝对的均衡。
没有彻底解决问题:如果后端有服务器宕机,那么这台服务器的Session丢失,被分配到这台服务请求的用户还是需要重新登录。
会话复制
既然,我们的目标是所有服务器上都要保持用户的Session,那么将每个应用服务器中的Session信息复制到其它服务器节点上是不是就可以呢?这就是Session
的第二中处理办法:会话复制。
会话复制在Tomcat上得到了支持,它是基于IP组播(multicast)来完成Session的复制,Tomcat的会话复制分为两种:
全局会话复制:利用Delta Manager
复制会话中的变更信息到集群中的所有其他节点。
非全局复制:使用Backup Manager
进行复制,它会把Session
复制给一个指定的备份节点。
不过,这里我不准备来解释会话复制的Tomcat
配置,如果有需求可以参考Tomcat
官方文档,主要是因为会话复制不适合大的集群。根据笔者在生产的实践案例,当时是在集群超过6
个节点之后就会出现各种问题,不推荐生产使用。
会话共享
既然会话保持和会话复制都不完美,那么我们为什么不把Session
放在一个统一的地方呢,这样集群中的所有节点都在一个地方进行Session
的存取就可以解决问题。
Session****存放到哪里?
对于Session来说,肯定是频繁使用的,虽然你可以把它存放在数据库中,但是真正生产环境中我更推荐存放在性能更快的分布式KV数据中,例如:Memcached和Redis。
PHP设置Session共享
如果你使用的是PHP那么恭喜你,配置非常的简单。PHP通过两行配置就可以把Session存放在Memcached或者Redis中,当然你要提前配置好他们。修改php.ini:
session.save_handler memcachesession.save_path
还没有评论,来说两句吧...