会话保持是ADC(应用交付控制器)的基本特性,绝大多数的应用环境下都涉及到该功能的配置,如果选择的会话保持方式不恰当,可能带来业务处理的不均衡甚至异常,因此能否根据不同的应用环境选择合适的会话保持方式,就涉及到工程师对应用环境的理解,进而还涉及到客户对ADC产品运行效果的评价。
绝大多数的负载均衡产品都支持两类基本的会话保持方式:源/目的地址会话保持和cookie会话保持,另外像hash,URL Persist等也是比较常用的方式,但不是所有设备都支持。
在应用交付环境中我们面临的常见应用主要有如下几大类: 基于C/S结构的应用,基于B/S结构(包括三层架构中间件平台)的应用,基于UDP协议的应用,链路负载均衡,以及某些特殊的应用等,下面我们具体分析在不同的环境下怎样选择合适的会话保持。
基于C/S结构的应用
该类应用一般选择(对于某些负载均衡产品来说也是唯一选择)源地址会话保持。在绝大多数情况下,源地址会话保持工作应该是正常的,但是源地址会话保持有如下弱点:
- 如果客户端地址是做了NAT,可能会引起服务器分发的不均衡。
- 如果客户端出口有多条链路轮询分发并做了NAT的,一方面会引起服务器分发的不均衡,另一方面可能因为源地址的改变导致会话不能保持,从而引起访问的不正常。
为了保证服务器分发的均衡性和处理的正确性,必须通过别的方式来实现会话保持, A10公司的AX产品支持基于TCL语言的aFlex脚本,可以灵活地分析四七层的数据包,比如说针对做了NAT的客户端,aFlex脚本可以不根据源地址做会话保持,而是提取客户端数据包的某个独一的字段,用这个字段来为每个客户端实现会话保持。
基于B/S结构的应用
对于普通B/S结构的应用内容,例如网站的静态页面,可以不用配置任何的会话保持,但是对于一个基于B/S结构尤其是中间件平台的业务系统来说,必须配置会话保持,一般情况下,我们配置源地址会话保持可以满足需求,但是考虑到客户端可能有上述不利于源地址会话保持的环境,采用Cookie会话保持是一个更好的方式。Cookie会话保持会把负载均衡设备选择的Server信息保存在Cookie中发送到客户端,客户端持续访问时,会把该Cookie带来,负载均衡器通过分析Cookie把会话保持到之前选定的服务器。Cookie分为文件Cookie和内存cookie,文件cookie保存在客户端计算机硬盘上,只要该cookie文件不过期,则无论是否重复关闭开放浏览器都能保持到同一台服务器。内存Cookie则是把Cookie信息保存在内存中,Cookie的生存时间从打开浏览器访问开始,关闭浏览器结束。另外该Cookie的会话保持还跟不同版本的浏览器有关,IE6之前的浏览器如果在打开一个浏览器实例的同时再打开一个新的实例访问相关的内容,新的浏览器不会传递该Cookie,因此新浏览器的请求会被当作新的会话来分发。IE6以后的浏览器如果打开新的实例访问相关的内容,则Cookie会话保持会被延续。由于现在的浏览器对Cookie都有一定默认的安全设置,有些客户端可能规定不准使用文件Cookie,所以现在的应用程序开发多使用内存Cookie。
然而,内存Cookie也不是万能的,第一,基于它分发的颗粒度仍然不够细,第二,浏览器为了安全可能会完全禁用Cookie,这样Cookie会话保持就失去了作用。怎么办?对于普通的只简单支持Cookie会话保持的负载均衡设备确实是束手无策。但是如果结合应用程序的开发我们有别的办法,大家都知道,某些应用平台特别是中间件平台的开发中常用到Session-id来保持和同步会话,针对禁用Cookie的环境,我们可以通过Session-id来实现会话保持,很不幸,这要求分析处理HTTP包中的Url才能实现,这是让很多厂家的负载均衡器为难的原因,而这对A10公司的aFlex脚本没有任何障碍,该脚本可以获得客户端Url中的Session-id信息,并以该Session-id作为判断会话是否应该保持的依据。如下是aFlex脚本的实现(该脚本同时支持Cookie和Url两种方式的分析):
rule sessionid_persist
when HTTP_REQUEST {
set session_id [findstr [HTTP::uri] “JSESSIONID=” 11 “;”]
if { ( session_id eq “” ) and ( [HTTP::cookie exists JSESSIONID] ) } { set session_id [HTTP::cookie JSESSIONID] } if {session_id ne “” } {
persist uie session_id } } when HTTP_RESPONSE { set session_id [HTTP::cookie JSESSIONID] if {session_id ne “” } {
persist add uie $session_id
}
}
基于UDP协议的应用
基于UDP协议的应用最常见的是DNS和Radius负载均衡。DNS应用基本上不涉及到会话保持,Radius应用稍微有点复杂,由于Bras设备和Radius服务器会形成长连接,一种需求是要求负载均衡设备能够随着每个请求关闭之前会话并重新选择会话,A10设备针对Radius负载均衡专门支持Stateless Per-Packet Round Robin的负载均衡策略,可以让非常均衡地把不同数据包分发到不同的服务器。实现以上需求要求每台Radius Server都可以处理任意的请求包,例如认证请求到达Server1, 计费请求到达Server2这种处理是没问题的,另外是多台Radius Server之间能够共享同步Bras传递过来的用户状态。由于以上要求可能原来的Radius系统无法实现,那么可能客户会要求基于单个用户的请求和计费来实现会话保持,这就必须在数据包中分离每个用户并实现会话保持,A10设备同样是通过aFlex来实现的。
链路负载均衡中的会话保持
链路负载均衡的会话保持常用的是基于源地址和目的地址的会话保持,基于源地址选择链路来分发数据包时常采用源地址会话保持,而基于目的地址选择链路来分发数据包时可以选择源地址会话保持也可以选择目的地址会话保持,采用何种会话保持方式还需要考虑用户内部网络的结构,例如用户内网不同的部门分别做了NAT,选择会话保持方式的不同,可能导致NAT地址和链路的压力大不相同。保证链路负载均衡会话保持正常工作的一个非常重要的因素是NAT地址的保持,假设用户是在访问网银,不同的链接访问出去的时候虽然走的是同一条链路,但用的不是同一个NAT地址,那么网银系统会拒绝处理该用户的请求。这跟做服务器负载均衡时,由于客户端NAT地址变化引起的访问异常是一样的,当然不排除网银还有一些安全性方面的措施。A10设备通常是通过Hash的方式来实现NAT地址的保持和唯一性:
when CLIENT_ACCEPTED {
set remote_addr [IP::local_addr]
set bwfile_group_id [ POLICY::bwlist id remote_addr chinall ] scanremote_addr "%d.%d.%d.%d" a b c d
set number of CNC/CTC NATs
set ctc_nat_num 5
set cnc_nat_num 5
set ctc_hash [ expr { 1+d%ctc_nat_num} ]
set cnc_hash [ expr { 1+d%cnc_nat_num} ]
set cnc_nat "cnc_nats_cnc_hash" set ctc_nat "ctc_nats_ctc_hash"
if { (bwfile_group_id equals 2) and ( [LB::status node 1.1.1.1 ] == "up") } { snatpoolcnc_nat
pool netcom_gw
} else {
snatpool $ctc_nat
pool telecom_gw
}
}
其他应用中的会话保持
A10设备对于某些专门的应用还提供专门的会话保持方法,比如对于SSL协议的应用,支持基于SSL Session-ID的会话保持,对于SIP协议的应用支持基于SIP的会话保持等,由于需求不够广泛,这里不做一一讨论。
网友评论