July 20, 2015, 7:24 p.m.
都知道TCP建立连接的时候会有个SYN握手。这件事情在LVS的fullnat模式下由于引入了一个“中间人”, 建立连接时会有两种策略。
1. 客户端与服务端的包全部经过中间人的转手, 原样递给双方。
2. 客户端与服务端的TCP连接时不会立即直接和服务端建立, 而是中间人单独和客户端建立连接,然后中间人再去和服务端建立连接。这种方式也就是syn_proxy这个功能的意义了。
从这两个方式本身来看, 正常的情况应该是用第一种了, 第二种有个明显的问题是,客户端认为连接建立好的时候其实并没有。。那么客户端接着发的内容就会被“阻挡”在中间人或者中间人满了有拒绝可能,这样的好处是流量超大时,前端请求不会把服务端压跪。
那么, 有件事情是最近遇到的。现象是客户端建立连接(应用层连接)速度异常缓慢(比如建100个连接的话, 平均1~2秒才能建好一个连接),而tcp连接的建立则表现出毫无压力的迹象,超级蛋疼。
抓包发现tcp win 的值会被LVS给从14600压制到115,这个窗口大小从TCP知识上来说是服务端告诉客户端自己只能接受xx大,多的受不了,那么客户机就会乖乖地把窗口改成115了。
于是试着投机取巧用sysctl将客户机的tcp window关了。。 改了下客户端的net.ipv4.tcp_window_scaling。 然后出现了神奇的一幕,客户机不再理会LVS设置tcp窗口的请求了,全部一口气发过去, 建100个连接倒是秒建了,然而QPS下降一半。。
果然还是不行的。最后联系了负责LVS的兄弟,他一看果然是syn_proxy给打开了。
另外,除了建连接慢,另一个比较奇怪的现象是一条消息,超过一定大小就会变得很慢,从1ms变为2s。。这个目前怀疑也和这个tcp win太小有点关系, 暂时还没想明白具体的机制(有想法了会更新)
所以LVS的这个syn_proxy虽然在防攻击上面挺好,但导致的一些诡异的问题真是很蛋碎。。