最近的一次POC测试,获得了一些有意思的经验,分享给大家。客户目前的需求和问题大致是这样的:

1、首先,应用服务器端需要保持TCP长连接,客户端关闭TCP连接后,服务器端连接不能关闭;

2、其次,登陆应用系统需要做源IP地址鉴权,就是要除了验证登陆用户名和密码以外,还需要验证登陆请求来源的IP地址;

3、目前的问题是客户端向系统发送请求的差异很大!客户端与服务器建立TCP长连接后,有一部分客户端会在一个TCP连接里发送大量的HTTP请求,这些是合法的正常请求,因此,会造成与部分应用服务器访问压力比较大,甚至会造成服务器Web进程瘫痪的现象;

了解了客户的需求和问题以后,按照以往的经验和做法,看到服务器端需要保持TCP长连接,首先想到的就是利用TCP连接复用,刚好可以满足客户的第一个需求,ADC(应用交付控制器)和服务器保持TCP长连接,当客户端完成请求并获得应答后,ADC正常关闭客户端的TCP连接,OK第一个需求可以满足。

让我们再看看第二个需求,按照这个需求,应用系统需要获得客户端的源IP地址。很不幸,按照TCP连接复用的工作机制,ADC设备需要改变客户端的源IP地址,或者复用部分客户的源地址(类似F5的One-Connect做法)。这样的话,应用系统就无法完成源IP地址的鉴权。分析到这里,矛盾出来了,客户第一个和第二个需求似乎是相互排斥的!怎么办呢?一个折中的办法,由于应用系统是基于HTTP协议做的,是不是可以在ADC设备上启用客户端IP地址的插入功能,将客户端地址插入到HTTP Header中,发送到应用服务器。很不幸,由于对应用系统改动比较大,所以客户不能接受这个折中的解决办法,那怎么办?让我们暂时搁置这个问题,再看看目前客户的第三个问题。

按照第三个问题的描述,可以看到基于连接的负载分担算法是无法真正解决目前的问题,如果能够按照请求进行负载分担可能会解决这个问题。ADC在七层工作模式下,如果能把来自同一个客户端TCP连接的不同HTTP请求,按照预定的负载分担算法分配到不同的应用服务器上就可以解决请求分发的问题。让我们再进一步预想一下,如果ADC产品为每个客户端请求,与应用服务器都建立一个TCP短连接,是不是会造成服务器频繁的开启/关闭连接,无形中反而增加了服务器的压力?那么如果ADC产品能够与服务器端保持TCP长连接,只要客户端有请求过来,就利用原有的服务器长连接去转发客户端请求,那不是刚好也可以解决第一个和第二个需求!如果是这样的工作机制,那么就太理想了!一举三得的事情!

那么应该启用什么功能可以实现呢?让我们在HTTP应用相关的功能模板里寻找一下,不难发现有一个小的feature从字面理解看,也许就是我们要找的解决问题的Key,是什么呢?Strict Transaction Switching:严格事务交换,那何为Transaction呢?不就是一个request请求嘛,在手册中这个功能的描述是这样的,缺省情况下,AX设备会为客户端会话的第一个request选择一个服务器,来建立服务器端的连接,之后在这个会话里所有的客户端requests,AX都会自动的把这些reuqests发送到同一台服务器上。当开启了STS(Strict Transaction Switching)功能,AX设备就会改变缺省的机制,对每个会话中的所有requests都会按照负载算法选择一个最佳的服务器。到这里我们已经可以基本确认STS就是我们要的解决办法。那会不会出现AX设备为每个request去和服务器建立一个短连接呢?这个手册中没有提及,OK让我们搭建一个环境试一试,或者直接在客户测试环境中尝试一下,并在AX设备上开启debug,验证一下从客户端~AX~服务器端完整的TCP连接建立过程,以及连接关闭过程,就可以确认我们的解决办法是可行的!

经过验证,没有问题!客户端同一个会话中不同的requests会负载到不同的服务器上,服务器应答后,AX也不会关闭与服务器的连接。即使客户端关闭了连接,用新的TCP连接发送后续的requests,AX设备依然可以利用原有的服务器连接传递这些requests。至此,客户那边的需求和问题都可以解决了!另外,在测试过程中,负载均衡算法,经过不同算法的验证,在AX上采用“严格轮询”算法,服务器负载非常均衡,相对比较不推荐使用“最少连接”或者“最少请求”的算法,这些算法会造成处理请求快的服务器负载稍高些。

同样的如果我们遇到了个别类似CC***情况,一个会话中发送大量HTTP请求,除了制定一些速率限制和安全限制策略(PBSLB)外,也可以尝试开启STS功能,将这些请求分散到不同的服务器上去。

 

S.G