会话保持是负载均衡的一个基本功能,也是我们在很多负载均衡项目实施中经常遇到的一个功能。为了确保与某个客户相关的所有应用请求能够由同一台服务器进行处理,我们需要在负载均衡上启用会话保持(Session Persistence)功能,以确保负载均衡的部署不会影响到正常的业务处理。
有关会话保持功能的细节,大家可以参考我以前的文章:
 
 
我们知道,常见的会话保持有两种:Cookie会话保持和源地址会话保持,对A10来说还可以用aFleX脚本来实现会话保持功能。但是,我在最近碰到的一个案例中却发现,这三种会话保持功能都失灵了。最终,我通过仔细的分析,发现了这几种会话保持功能失效的原因,并帮助用户实现了会话保持功能。让我们还是像侦探一样,看看到底发生了什么问题。
 

事情的由来

话说某一天上午,销售说有个用户那边需要上负载均衡产品,但是部署了某知名负载均衡品牌的设备后,发现客户端登录之后,切回到主页面发现客户端仍然显示为未登录状态。各位看官应该明白,这是典型的没有启用会话保持或者会话保持机制没有生效的原因。销售说代理商那边折腾了两天没解决问题,问我们是否有解决方案。
我想,我们的机会来了。
说实话,会话保持无外乎那几种解决方式,正在测试的这个知名品牌在这方面的功能也比较完善,但为啥这个功能运行起来就一直有问题呢?我也不太了解。废话少说,大家随我一起去探查一番吧。
 

抽丝剥茧

带着设备到现场之后,发现某知名厂商的工程师还在现场调试。打开应用页面测试了一下,发现果然会话保持有问题。与现场的工程师聊了一下,发现常见的几种会话保持功能都已经试过了,但是结果都一样:用户登录后,切换回主页面,仍然显示未登录状态。
看起来情况的确比较诡异,先了解一下整个应用场景的拓扑吧。

 

客户端要访问应用服务器,中间需要经过两个重要的环节:
1)       用户购买了专业的CDN服务,用来缓解应用服务器压力。客户端的所有请求,都会发送到CDN,CDN会根据请求的类型来决定是从本地缓存中直接返回还是送往源站点。
2)       CDN送往源站点的请求,实际是送给负载均衡设备,由负载均衡设备分发至多台应用服务器。
最为重要的是,在这两个环节中,都启用了源地址转换(Source NAT),也就是说:应用服务器看到的源地址是负载均衡的,而负载均衡看到的源地址是CDN的。
了解到这个信息,我已经基本确定,源地址会话保持在这种场景下是无效的。原因很简单:
1)     CDN的缓存服务器肯定不止1台
2)     CDN的缓存服务器前端也会部署负载均衡
3)     同一客户端的请求会分发到不同的缓存服务器
基于以上三个原因,在负载均衡上开启源地址会话保持根本无法保证同一客户端的请求都转发至后端相同的应用服务器。
好吧,在没有进行配置,只是纸上推演,就已经毙掉了源地址会话保持,我们还有Cookie会话保持,以及aFleX脚本会话保持。
 
穷途末路
 
接下来,便是与应用开发的人员讨论A10负载均衡部署的问题。但讨论的结果却让我也陷入了绝境,我终于体会到为什么“著名负载均衡厂商”也搞不定的原因了。
好吧,不难为大家了,直接说明应用开发人员的要求:
1)       在客户端与服务器的交互过程中,需要使用两种协议:商品的浏览挑选使用HTTP,而用户登录以及下单需要使用加密的HTTPS。
2)       由于这两个应用协议之间是有交互的,因此需要将同一客户端的所有HTTP和HTTPS请求,都转发到同一台服务器进行处理
3)       由于后端服务器的开发组件的限制,后端服务器不接受HTTP请求类型,也就是说,如果客户端请求的是加密的HTTPS类型,那么负载均衡向后端服务器转发的也必须是加密的HTTPS请求。
如果不考虑CDN进行了源地址转换的问题,对于第1)和2)两点要求,无论是Cookie会话保持还是源地址会话保持,在AX上只要在会话保持模板中设置match-type为Server,即可保证客户端发往同一VIP,但是在不同端口的应用,都会会话保持到同一台服务器。
因此,我们决定采用SSL卸载并启用Cookie会话保持功能来实现用户的要求。但是,当完成配置进行测试时,我们发现客户端的HTTPS请求会发生302重定向环路问题,访问仍然是不正常的。经过分析并且与应用开发人员进行沟通,我们最终发现在本项目部署中还隐藏了上面的要求3)。
在发现这种情况时,“某著名厂商”的工程师提出,应用有问题,让应用开发人员去检查应用是否有问题。但我没有这么武断,而是和应用开发人员进行了一些沟通,然后,就发现了产生环路的原因。其实很简单:
1)       当用户需要进行登录认证时,点击登录,会发送一个HTTPS的URL到服务器;
2)       当客户端的请求到达负载均衡后,进行SSL卸载,请求被转换成HTTP,然后转发至服务器;
3)       服务器检测到请求是HTTP的,而不是HTTPS,就会对当前请求的URL做重定向,由HTTP重定向到HTTPS;
4)       客户端收到重定向请求,发送HTTPS请求至服务器;
5)       然后回到上面的第2)步,产生环路。
 
好吧,我们汇总一下:
1)     由于CDN的存在,导致源地址会话保持无法使用;
2)     通常情况下,当后端服务器上采用HTTPS加密,而不需要负载均衡做SSL卸载时,我们把这些应用直接作为TCP协议类型进行处理,但在这种情况下,Cookie会话保持也会失效;
3)     当然,aFleX脚本也需要检测到实际的HTTP/HTTPS请求,所以,在这里脚本也无法使用。
 
柳暗花明
测试到这里,已经是临晨3点多了,大家都是疲惫不堪。我又开始调整部署方案。最终的解决方案则是在前面的方案中又增加了服务器端SSL加密。

 

如上图所示:
1)       客户端仍然是发送经过SSL加密的HTTPS请求,当请求到达AX时,由AX进行SSL卸载;
2)       经过SSL卸载后请求,由AX进行处理,AX可以检查HTTP头部的cookie,来判断请求是否需要进行Cookie会话保持处理;
3)       当HTTP请求离开AX之间,由AX对请求再次进行加密,并转发至应用服务器。
由于应用服务器收到的请求仍然是经过SSL加密的,因此,302重定向环路的问题解决了,会话保持的问题也解决了。
 
到此,故事讲完了。其实,
产品并不重要,重要的是你如何去使用。
配置也不重要,重要的是你要了解其中的原理。
 
E.S.