====================================================
当linux下Nginx达到并发数很高,TCP TIME_WAIT套接字数量经常达到两、三万,这样服务器很容易被拖死。
事实上,我们可以简单的通过修改Linux内核参数,可以减少Nginx服务器的TIME_WAIT套接字数量,进而提高Nginx服务器并发性能。
vi /etc/sysctl.conf增加以下几行:net.ipv4.tcp_fin_timeout = 30net.ipv4.tcp_keepalive_time = 1200net.ipv4.tcp_syncookies = 1net.ipv4.tcp_tw_reuse = 1net.ipv4.tcp_tw_recycle = 1net.ipv4.ip_local_port_range = 1024 65000net.ipv4.tcp_max_syn_backlog = 8192net.ipv4.tcp_max_tw_buckets = 5000简单说明:net.ipv4.tcp_syncookies = 1 表示开启SYN Cookies。当出现SYN等待队列溢出时,启用cookies来处理,可防范少量SYN攻击,默认为0,表示关闭;net.ipv4.tcp_tw_reuse = 1 表示开启重用。允许将TIME-WAIT sockets重新用于新的TCP连接,默认为0,表示关闭;net.ipv4.tcp_tw_recycle = 1 表示开启TCP连接中TIME-WAIT sockets的快速回收,默认为0,表示关闭。net.ipv4.tcp_fin_timeout = 30 表示如果套接字由本端要求关闭,这个参数决定了它保持在FIN-WAIT-2状态的时间。net.ipv4.tcp_keepalive_time = 1200 表示当keepalive起用的时候,TCP发送keepalive消息的频度。缺省是2小时,改为20分钟。net.ipv4.ip_local_port_range = 1024 65000 表示用于向外连接的端口范围。缺省情况下很小:32768到61000,改为1024到65000。net.ipv4.tcp_max_syn_backlog = 8192 表示SYN队列的长度,默认为1024,加大队列长度为8192,可以容纳更多等待连接的网络连接数。net.ipv4.tcp_max_tw_buckets = 5000 表示系统同时保持TIME_WAIT套接字的最大数量,如果超过这个数字,TIME_WAIT套接字将立刻被清除并打印警告信息。默认为180000,改 为5000。对于Apache、Nginx等服务器,上几行的参数可以很好地减少TIME_WAIT套接字数量,但是对于Squid,效果却不大。此项参 数可以控制TIME_WAIT套接字的最大数量,避免Squid服务器被大量的TIME_WAIT套接字拖死。 echo “====================== 执行以下命令使配置生效:=========================”#更改linux内核参数后,立即生效的命令! /sbin/sysctl -p Nginx优化 使用FastCGI 缓存fastcgi_cache TEST开启FastCGI 缓存并且为其制定一个名称。个人感觉开启缓存非常有用,可以有效降低CPU 负载,并且防止502 错误。 fastcgi_cache_path /usr/local/nginx/fastcgi_cache levels=1:2keys_zone=TEST:10minactive=5m;这个指令为FastCGI 缓存指定一个路径,目录结构等级,关键字区域存储时间和非活动删除时间其它说明Nginx 是由 Igor Sysoev 为俄罗斯访问量第二的 Rambler.ru 站点开发的,它已经在该站点运行超过两年半了。Igor 将源代码以类BSD许可证的形式发布。在高并发连接的情况下,Nginx是Apache服务器不错的替代品。Nginx同时也可以作为7层负载均衡服务器来使用。根据我的测试结 果,Nginx 0.6.31 + PHP 5.2.6 (FastCGI) 可以承受3万以上的并发连接数,相当于同等环境下Apache的10倍。 根据我的经验,4GB内存的服务器+Apache(prefork模式)一般只能处理3000个并发连接,因为它们将占用3GB以上的内存,还 得为系统预留1GB的内存。我曾经就有两台Apache服务器,因为在配置文件中设置的MaxClients为4000,当Apache并发连接数达到 3800时,导致服务器内存和Swap空间用满而崩溃。 而这台 Nginx 0.6.31 + PHP 5.2.6 (FastCGI) 服务器在3万并发连接下,开启的10个Nginx进程消耗150M内存(15M*10=150M),开启的64个php-cgi进程消耗1280M内存 (20M*64=1280M),加上系统自身消耗的内存,总共消耗不到2GB内存。如果服务器内存较小,完全可以只开启25个php-cgi进程,这样 php-cgi消耗的总内存数才500M。========================================
服务端调整系统的参数,在/etc/sysctl.conf中:
net.core.somaxconn = 2048
net.core.rmem_default = 262144net.core.wmem_default = 262144net.core.rmem_max = 16777216net.core.wmem_max = 16777216net.ipv4.tcp_rmem = 4096 4096 16777216net.ipv4.tcp_wmem = 4096 4096 16777216net.ipv4.tcp_mem = 786432 2097152 3145728net.ipv4.tcp_max_syn_backlog = 16384net.core.netdev_max_backlog = 20000net.ipv4.tcp_fin_timeout = 15net.ipv4.tcp_max_syn_backlog = 16384net.ipv4.tcp_tw_reuse = 1net.ipv4.tcp_tw_recycle = 1net.ipv4.tcp_max_orphans = 131072/sbin/sysctl -p 生效
主要看这几项:
net.ipv4.tcp_rmem 用来配置读缓冲的大小,三个值,第一个是这个读缓冲的最小值,第三个是最大值,中间的是默认值。我们可以在程序中修改读缓冲的大小,但是不能超过最小与最大。为了使每个socket所使用的内存数最小,我这里设置默认值为4096。net.ipv4.tcp_wmem 用来配置写缓冲的大小。读缓冲与写缓冲在大小,直接影响到socket在内核中内存的占用。而net.ipv4.tcp_mem则是配置tcp的内存大小,其单位是页,而不是字节。当超过第二个值时,TCP进入pressure模式,此时TCP尝试稳定其内存的使用,当小于第一个值时,就退出pressure模式。当内存占用超过第三个值时,TCP就拒绝分配socket了,查看dmesg,会打出很多的日志“TCP: too many of orphaned sockets”。另外net.ipv4.tcp_max_orphans这个值也要设置一下,这个值表示系统所能处理不属于任何进程的socket数量,当我们需要快速建立大量连接时,就需要关注下这个值了。当不属于任何进程的socket的数量大于这个值时,dmesg就会看到”too many of orphaned sockets”。
=======================================