学海无涯 个人blog lnmps.com 新站
分类: LINUX
2013-04-14 22:31:12
环境:
直播web服务器通过nginx+memcache方式提供显示数据的读取,采用的都是短链接模式,每次请求拿到数据后会断开连接。
故障:
cache服务器,不能创建新连接,message日志报错ip_conntrack: table full, dropping packet.
导致直播web出现故障,同样错误ip_conntrack: table full, dropping packet.
故障原因:链接跟踪表满了,导致不能创建新的连接。
以前出现过类似故障,解决办法是
vi /etc/sysctl.conf
net.ipv4.ip_conntrack_max = 65000 加大链接跟踪表大小(加大最大跟踪连接条目)
但是过一段时间又出现上面的问题,这说明一是访问量确实再加大,导致跟踪表full,另外也说明单纯加大这个参数只能解决眼前的问题,必须找出一个彻底解决此问题的办法。
这次故障临时调整
vi /etc/sysctl.conf
net.ipv4.ip_conntrack_max = 855360
net.ipv4.netfilter.ip_conntrack_tcp_timeout_established = 1000 (连接跟踪表超时时间,通过测试这个参数的意义不大,和跟踪表自动清除的时间没有太大关系,但还是先减小,默认值是7天)
vi /etc/modprobe.conf
options ip_conntrack hashsize=855360
设置桶的数量。提高性能,可以减少内核遍历时间。
简单解释:
上面的参数都是iptables涉及的参数,iptables为了处理封包,会对封包做跟踪。
如果关闭iptables,上面的故障不会出现,但是不太可能。
-允许的最大跟踪连接条目,CONNTRACK_MAX
-存储跟踪连接条目列表的哈西表的数量, HASHSIZE,桶的数量
内核要访问一个特定包的跟踪连接条目,内核必须:
针对一个包中的已经定义的一些字符计算哈西值。这是一个不间断的计算。
这个哈西值就会被当作哈西表的索引来使用,而跟踪连接条目的列表就存储在这里。
反复的查看链接列表中的跟踪连接条目以找到匹配的那一个。
这是一个耗资源的操作,依赖于列表的大小(也依赖于列表中被操作的跟踪连接条目的位置)。
这个列表就是一个桶,HASHSIZE就是这些桶的数量,每个桶内的条目数就是 CONNTRACK_MAX/HASHSIZE
如果 CONNTRACK_MAX=HASHSIZE那么列表大小是一,可以减少遍历的数目,提高性能,前提是内存足够大
iptables这个桶的概念和LVS 内核桶的概念类似。
彻底解决:关闭跟踪。
直播web服务器
vi /etc/sysconfig/iptables
*raw
:PREROUTING ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
-A PREROUTING -p tcp -m tcp --dport 80 -j NOTRACK
-A PREROUTING -p tcp -m tcp --dport 10240:65000 -j NOTRACK
-A OUTPUT -p tcp -m tcp --sport 80 -j NOTRACK
-A OUTPUT -p tcp -m tcp --sport 10240:65000 -j NOTRACK
COMMIT
注意 filter 里要加这句
-A RH-Firewall-1-INPUT -m state --state ESTABLISHED,RELATED,UNTRACKED -j ACCEPT
后端cache服务器
vi /etc/sysconfig/iptables
*raw
:PREROUTING ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
-A PREROUTING -p tcp -m tcp --dport 80 -j NOTRACK
-A OUTPUT -p tcp -m tcp --sport 80 -j NOTRACK
-A PREROUTING -p tcp -m tcp --dport 11211 -j NOTRACK
-A OUTPUT -p tcp -m tcp --sport 11211 -j NOTRACK
COMMIT
把80端口和11211端口去掉跟踪。
用apache ab测试 观察 /proc/net/ip_conntrack 效果很明显
如果web端配置
-A PREROUTING -p tcp -m tcp --dport 11211 -j NOTRACK
-A OUTPUT -p tcp -m tcp --sport 11211 -j NOTRACK
是没有意义的,链接跟踪表还是会记录连接后端cache的条目,如果要加上-s之类的源IP地址,那么连接后端11211的出包都会被封,(测试结果)所以规则肯定不是这样定,具体的规则还要研究。
对于cache服务器来说,以上配置是非常完善的。
通过观察研究链接跟踪表(/proc/net/ip_conntrack)的内容,发现内有大量直播web连接后端cache 11211端口的连接条目,源端口是一万以上的端口。而且web服务器也有大量80端口的连接,这些链接不
需要处理,所以不跟需踪这些链接。
由于raw的output优先级高于filter input,所以如果设置成1024:65000 -j NOTRACK,那么这些端口都会被允许访问,所以设置成10240:65000 ,filter的input还是不可以封住的,但是以后启动的应用
服务的端口要注意,必须选择10240以下的端口自行定义。虽然10240:65000这些端口可以在公网上扫到,但是由于没有服务对应,所以不会有问题。
还要研究针对于访问后端的端口如何准确的去掉跟踪。
上面思路比较乱,关键的点想反了,以下是纠正
通过观察研究
cat /proc/net/ip_conntrack
tcp 6 431946 ESTABLISHED
src=192.168.0.18 dst=192.168.0.17 sport=52292 dport=3306 packets=1
bytes=52 src=192.168.0.17 dst=192.168.0.18 sport=3306 dport=52292
packets=1
bytes=52 use=1
tcp 6 431999 ESTABLISHED src=192.168.0.18
dst=192.168.0.165 sport=22 dport=2676 packets=27 bytes=2128
src=192.168.0.165 dst=192.168.0.18 sport=2676 dport=22 packets=26
bytes=1664 [ASSURED] use=1
经过测试研究,并且看了几遍iptables-tutorial后,搞好了准确的去掉跟踪 结果
web服务器
*raw
:PREROUTING ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
-A PREROUTING -p tcp -m tcp --dport 80 -j NOTRACK
-A PREROUTING -p tcp -m tcp --sport 11211 -j NOTRACK 从17的11211端口返回给18的规则
-A OUTPUT -p tcp -m tcp --sport 80 -j NOTRACK
-A OUTPUT -p tcp -m tcp --dport 11211 -j NOTRACK 从18出到17的11211端口规则
COMMIT
测试结果表明:如果OUTPUT设置了相关端口,那么PREROUTING 必须针对OUTPUT设置的端口制定规则,否则封包不能出去。 (其实是回不来)
原因如下
连接跟踪的状态主要在两个地方被触发,一个是PREROUTING,另外一个数OUTPUT,他们分别对应外来报文和本级产生报文。例如我们从本级 发送一个报文,那么在OUTPUT链里面,它的状态会变成NEW,当我们接收到回应报文的时候,连接状态就PREROUTING处更改为 ESTABLISHED,以此类推。加入第一个报文不是我们尝试的,那么在PREROUTING出就设置为NEW,然后我们发送回复的时候,在 OUTPUT设置为ESTABLISHED。