Linux集群技术 -- Web集群 负载均衡解决方案 -- 会话保持

一、基础概念

1、什么是Session ?

Session在网络中应该被称之为“会话”,借助它可提供服务器端与客户端系统之间必要的交互。因为HTTP协议本身是无状态的,所以经常需要通过Session来提供服务端和浏览端的保持状态的解决方案。Session是由应用服务器维持的一个服务器端的存储空间,用户在连接服务器时,会由服务器生成一个唯一的SessionlD,该SessionID作为标识符来存取服务器端的 Session存储空间。
SessionID这一数据是用Cookie保存到客户端的,用户提交页面时,会将这一SessionID提交到服务器端,以此存取Session数据。服务器也通过URL重写的方式来传递SessionID的值,因此它不是完全依赖于Cookie的。如果客户端Cookie禁用,则服务器可以自动通过重写URL的方式来保存Session的值,并且这个过程对程序员是透明的。

2、什么是Session共享 ?

当网站业务规模和访问量逐步增大,原本由单台服务器、单个域名组成的迷你网站架构可能已经无法满足发展需要。
此时,我们可能会购买更多的服务器,并且以频道化的方式启用多个二级子域名,然后根据业务功能将网站分别部署在独立的服务器上,或者通过负载均衡技术(如 Haproxy,Nginx))让多个频道共享一组服务器。
如果我们把网站程序分别部署到多台服务器上,并且独立为几个二级域名,由于Session存在实现原理上的局限性(PHP中Session默认以文件的形式保存在本地服务器的硬盘上),这使得网站用户不得不经常在几个频道间来回输入用户名和密码登录,导致用户体验大打折扣。另外,原本程序可以直接从用户Session变量中读取的资料(如:昵称、积分、登入时间等),因为无法跨服务器同步更新Session变量,迫使开发人员必须实时读写数据库,从而增加了数据库的负担。于是,解决网站跨服务器的Session共享问题的需求变得越来越迫切,最终催生了多种解决方案,下面列举4种较为可行的方案进行对比和探讨。

1.基于Cookie 的 Session共享

读者可能对这个方案比较陌生,但它在大型网站中已被普遍使用。其原理是将全站用户的Session信息加密,序列化后以Cookie的方式统一种植在根域名下(如:.host.com)。
当浏览器访问该根域名下的所有二级域名站点时,将与域名相对应的所有Cookie内容的特性传递给它,从而实现用户的Cookie 化 Session在多服务间的共享访问。
这个方案的优点是无须额外的服务器资源,缺点是由于受HTTP协议头长度的限制,仅能存储小部分的用户信息,同时Cookie化的Session内容需要进行安全加解密(如:采用DES、RSA等进行明文加解密;再由MD5、SHA-1等算法进行防伪认证)。另外,它也会占用一定的带宽资源,因为浏览器会在请求当前域名下的任何资源时将本地Cookie附加在HTTP头中传递到服务器上。

2.基于数据库的Session共享

首选的当然是MySQL数据库,并且建议使用内存表Heap,以提高Session操作的读写效率。这个方案的实用性较强,已得到大家的普遍使用,但它的缺点在于Session 的并发读写能力取决于MySQL数据库的性能,同时需要我们自己实现Session淘汰逻辑,以便定时从数据表中更新、删除Session记录,当并发过高时容易出现表锁,虽然我们可以选择行级锁的表引擎,但不得不承认使用数据库存储Session还是有些大材小用了。

3.Session复制

熟悉Tomcat或 Weblogic 的朋友应该对Session复制也非常了解了。顾名思义,Session复制就是将用户的Session 复制到Web 渠开内政n具的增,加网络负相成指数级上升,带了这种处理机制。但其缺点也非常明显:随着机器数量的增加,网络负担成指数级上升,性能随着服务器数量的增加而急剧下降,而且很容易引起网络风暴。

4.基于Memcache/Redis的 Session共享

Memcache是一款基于Libevent的多路异步IO技术的内存共享系统,简单的Key +Value数据存储模式使其代码逻辑小巧高效,因此在并发处理能力上占据了绝对优势。
另外值得一提的是 Memcace P这就降低了删除过期Session数据的代码复杂度。但对好和 Session的过期机制不谋而合,这就降低了删除过期Session数据的比“基于数据库的存储方案”,仅逻辑这块就给数据表带来了巨大的查询压力。
Redis 作为NoSQL的后起之秀,经常被拿来与memcached做对比。Redis作为NoSQL的后起之秀,经常被拿来与memcached做对比。redis作为一种缓存,或者干脆称之为NoSQL数据库,提供了丰富的数据类型(list、set等),可以将大量数据的排序从单机内存释放到redis集群中处理,并可以用于实现轻量级消息中间件。在memcached和 redis的性能比较上,redis在小于:100k的数据读写上速度优于memcached。在我们的系统中,redis已经取代了memcached来存放Session数据。

3、什么是会话保持 ?

会话保持并非Session共享。
在大多数的电子商务应用系统中,或者需要进行用户身份认证的在线系统中,一个客户与服务器经常会经过好几次的交互过程才能完成一笔交易或一个请求。由于这几次交互过程是密切相关的,服务器在进行这些交互的过程中,要完成某一个交互步骤往往需要了解上一次交互的处理结果,或者前几步的交互结果,这就要求所有相关的交互过程都由一台服务器完成,而不能被负载均衡器分散到不同的服务器上。
而这一系列相关的交互过程可能是由客户到服务器的一个连接的多次会话完成的,也可能是在客户与服务器之间的多个不同连接里的多次会话完成的。关于不同连接的多次会话,最典型的例子就是基于HTTP的访问,一个客户完成一笔交易可能需要多次点击,而一个新的点击产生的请求,可能会重用上一次点击建立起来的连接,也可能是一个新建的连接。
会话保持就是指在负载均衡器上有这么一种机制,可以识别客户与服务器之间交互过程的关联性,在做负载均衡的同时,还能保证一系列相关联的访问请求被分配到同一台服务器上。

二、负载均衡器的会话保持机制(面试重点)

会话保持机制的目的是保证在一定时间内某一个用户与系统会话只交给同一台服务器处理,这一点在满足网银、网购等应用场景的需求时格外重要。负载均衡器实现会话保持—般会有如下几种方案:

1、基于源IP地址的持续性保持。主要用于四层负载均衡,这种方案应该是大家最为熟悉的,LVS/HAProxy、Nginx都有类似的处理机制,如Nginx中的ip_hash算法,HAProxy中的source算法等。

2、基于Cookie数据的持续性保持。主要用于七层负载均衡,用于确保同一会话的报文能够被分配到同一台服务器中。其中,根据服务器的应答报文中是否携带含有服务器信息的Set Cookie字段,又可以分为cookie插入保持和 cookie截取保持。

3、基于HTTP报文头的持续性保持。主要用于七层负载均衡,当负载均衡器接收到某一个客户端的首次请求时,会根据HTTP报文头关键字建立持续性表项,记录为该客户端分配的服务器情况,在会话表项的生存期内,后续具有相同HTTP报文头信息的连接都将发往该服务器处理。

三、LvS的会话保持机制 案例实战(面试重点)

LVS的会话保持机制

LVS是利用配置文件里的==persistence(单位为秒)==设置来设定会话保持时间的,这个选项对于电子商务网站来说尤其重要:当用户从远程用账号登录网站时,通过这个会话保持功能就能把用户的请求转发给同一个应用服务器了。我们在这里做一个假设,假定现在有一个LVS环境,使用LVS/DR转发模式,真实的Web服务器有2个,LVS负载均衡器不启用会话保持功能。当用户第一次访问的时候,他的访问请求被负载均衡器转给某个真实服务器,随后他将看到一个登录页面,第一次访问完毕。接着他在登录框里填写用户名和密码,然后提交,这时候,问题可能就会出现了——登录不成功。因为没有会话保持,负载均衡器可能会把第2次的请求转发到其他的服务器上,这样浏览器又会提醒客户需要再次

案例实战

基于主机持久连接

当每次客户端持久;将来自于同一个客户端的所有请求统统定向至此前选定的 RS;也就是只要 IP
相同,分配的服务器始终相同

ipvsadm -A -t 172.16.0.8:0 -s wlc -p 120
# 添加一个 tcp 负载集群,集群地址为 172.16.0.8 ,算法为 wlc,持久化时间为 120s

基于端口持久连接

当每次端口持久;将来自于同一个客户端对同一个服务(端口)的请求,始终定向至此前选定的RS

ipvsadm -A -t 172.16.0.8:80 -s rr -p 120
# 添加一个 tcp 负载集群,集群地址为 172.16.0.8:80 ,算法为 wlc,持久化时间为 120s

基于防火墙持久连接

将来自于同一客户端对指定服务(端口)的请求,始终定向至此选定的 RS;不过它可以将两个毫不相干的端口定义为一个集群服务

iptables -t mangle -A PREROUTING -d 172.16.0.8 -p tcp --dport 80 -j MARK --
set-mark 10 # 添加一个防火墙规则,当目标地址为 172.16.0.8 并且 目标端口为 80 时给数据包打一个标记,设置mark 值为 10
iptables -t mangle -A PREROUTING -d 172.16.0.8 -p tcp --dport 443 -j MARK --
set-mark 10
# 添加一个防火墙规则,当目标地址为 172.16.0.8 并且 目标端口为 443 时给数据包打一个标记,设置mark 值为 10
service iptables save # 保存防火墙规则持久化生效
ipvsadm -A -f 10 -s wlc -p 120 # 添加一个负载调度器,当 mark 值为 10 时进行负载均衡使用wlc 算法,持久化生效时间为 120s

猜你喜欢

转载自blog.csdn.net/XY0918ZWQ/article/details/113898288
今日推荐