您的位置:首页 > 数据库 > Redis

彻底解决twemproxy半连接问题

2016-12-02 14:28 351 查看
LVS+TWEMPROXY+REDIS的这种方式会产生很多半连接,在我的http://blog.csdn.net/a13805667702/article/details/53411576这篇文章中已经讲过

生产事故回顾(血泪史):

首先是应公司安全要求对核心交换机做升级,升级期间公司网络是不可用的!但网络异常会导致web应用和redis的proxy会产生大量的半连接,应用的半连接过多会把连接池的连接占满,会产生程序异常报无法get 到resource from pool,而对于redis集群proxy来说,会有很多的半连接,我们现在的物理机一台是不是30左右个实例,会有大量的半连接把机器的文件句柄吃满,导致正常的连接进不来!我们是以root账号起的twemproxy,最大每个proxy支撑65352个连接!而开源twemproxy是不支持释放半连接的功能,我们也测试了git上最新的开源的版本,加入了这个功能但他们的代码里没有实现,还是无法解决!为了避免半连接过多,我们proxy每天晚上都会做重启操作来释放半连接,但是过多的重启对应用来说就是有伤害的,我们控制了下正常半夜一个小时重启一次释放!但是网络异常半连接的量太大了,网络问题反复创建、然后异常变成半连接!以至于所有的连接都是半连接,新的连接连不进去(属于极端情况,正常是不会有这个问题)

为了彻底解决这个问题,可以在proxy上从操作系统层次来做TCP保活探测,我们用的是centos6.5,操作系统默认对半连接的处理方式

net.ipv4.tcp_keepalive_time = 7200 默认对空闲两个小时的连接进行探测

net.ipv4.tcp_keepalive_probes = 9   重复探测9次

net.ipv4.tcp_keepalive_intvl = 75      每次探测间隔75s

对上面参数的理解如下:

在proxy的服务器上,对于半连接的处理默认是两小时没有任何数据包的空闲连接,发起tcp保活探测,默认一个探测占用是60B的数据包,反复探测9次,每次间隔75秒!如果client有回包,这个空闲连接的时间就会重新计时。对应正常的连接,无论是空闲还是活跃的都是没问题的,不会出现kill正常连接的!

那它会kill什么样的连接呢?

由于是做保活探测的,对于半连接,没有回包的肯定会被kill掉。但还有一种特殊情况,比如应用到proxy的连接两小时没发包,但是这个时候应用机器异常,proxy的tcp开始探测,发了个探测包到client,client由于异常处理不过来来不及回包到proxy,这个时候反复探测几次后都没得到client的反馈,keepalive会认为这个连接是空闲异常的,会把这个连接给kill掉!这个时候应用本来是正常的连接,就这么被kill了

那设置多少合理呢?

lvs默认5分钟会reset空闲的client过来的连接!我们这边设置三分钟空闲,然后向client心跳包,间隔10秒,发三次都没回应,说明这个连接是异常的!就可以干掉了!如果设置超过5分钟探测的话相当于收尸,3分钟都是空闲这个连接探测没回应肯定是有问题的!

下面是设置过后的结果:



从图中可以看出,这台物理机上30个proxy实例,从10w的连接瞬间降到了8k个,效果很明显。这个数字和从lvs的hash表里的连接数是一致的!

综上可以看出,通过OS的tcp保活探测机制可以完美的解决目前twemproxy的半连接问题,当然这个设置是OS全局的,如果能做到进程级别就更好了,希望twemproxy能早点开源出这个功能。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息