web服务器和cache服务器,高并发下,socket最大联接数限制调整:
1,更改用户进程可打开最大文件数限制。
即时生效:ulimit-nxxx
永久生效:
echo”ulimit-HSn65536″>>/etc/rc.local
echo”ulimit-HSn65536″>>/root/.bash_profile
ulimit-HSn65536
2,更改网路内核对最大tcp联接数限制。
/etc/sysctl.conf
一、
在Linux平台上,无论编撰顾客端程序还是服务端程序,在进列宽并发TCP联接处理时,最高的并发数目都要遭到系统对用户单一进程同时可打开文件数目的限制(这是由于系统为每位TCP联接都要创建一个socket句柄,每位socket句柄同时也是一个文件句柄)。诸如:一个redis程序,只启动一个进程,则只能打开1024个文件(默认1024)(1024个tcp联接=1024个socket联接句柄=1024个文件句柄),
可使用ulimit命令查看系统容许当前用户进程打开的文件数限制:
$ulimit-n
1024
这表示当前用户的每位进程最多容许同时打开1024个文件,这1024个文件中还得去除每位进程必然打开的标准输入,标准输出,标准错误,服务器窃听socket,进程间通信的unix域socket等文件,这么剩下的可用于顾客端socket联接的文件数就只有大约1024-10=1014个左右。也就是说缺省情况下,基于Linux的通信程序最多容许同时1014个TCP并发联接。
对于想支持更高数目的TCP并发联接的通信处理程序,就必须更改Linux对当前用户的进程同时打开的文件数目:
软限制(softlimit):是指Linux在当前系统还能承受的范围内进一步限制用户同时打开的文件数;
硬限制(hardlimit):是依据系统硬件资源状况(主要是系统显存)估算下来的系统最多可同时打开的文件数目。
一般软限制大于或等于硬限制
更改单个进程打开最大文件数限制的最简单的办法就是使用ulimit命令:
[speng@as4~]$ulimit-n
上述命令中,在手指定要设置的单一进程容许打开的最大文件数。假如系统回显类似于”Operationnotpermitted”之类的话嵌入式linux培训,说明上述限制更改失败,实际上是由于在手指定的数值超过了Linux系统对该用户打开文件数的软限制或硬限制。因而,就须要更改Linux系统对用户的关于打开文件数的软限制和硬限制。
第一步,更改/etc/security/limits.conf文件,在文件中添加如下行:
spengsoftnofile10240
spenghardnofile10240
其中speng指定了要更改那个用户的打开文件数限制,可用’*’号表示更改所有用户的限制;
soft或hard指定要更改软限制还是硬限制;10240则指定了想要更改的新的限制值,即最大打开文件数(请注意软限制值要大于或等于硬限制)。更改完后保存文件。
第二步,更改/etc/pam.d/login文件,在文件中添加如下行:
sessionrequired/lib/security/pam_limits.so这是告诉Linux在用户完成系统登陆后,应当调用pam_limits.so模块来设置系统对该用户可使用的各类资源数目的最大限制(包括用户可打开的最大文件数限制),而pam_limits.so模块都会从/etc/security/limits.conf文件中读取配置来设置这种限制值。更改完后保存此文件。
第三步,查看Linux系统级的最大打开文件数限制,使用如下命令:
[speng@as4~]$cat/proc/sys/fs/file-max
12158
这表明这台Linux系统最多容许同时打开(即包含所有用户打开文件数总和)12158个文件,是Linux系统级硬限制,所有用户级的打开文件数限制都不应超过这个数值。一般这个系统级硬限制是Linux系统在启动时按照系统硬件资源状况估算下来的最佳的最大同时打开文件数限制,假如没有特殊须要,不应当更改此限制,除非想为用户级打开文件数限制设置超过此限制的值。
更改此硬限制的方式是更改/etc/rc.local脚本,在脚本中添加如下行:
echo22158>/proc/sys/fs/file-max
这是让Linux在启动完成后强行将系统级打开文件数硬限制设置为22158.更改完后保存此文件。
完成上述步骤后重启系统,通常情况下就可以将Linux系统对指定用户的单一进程容许同时打开的最大文件数限制设为指定的数值。假如重启后用ulimit-n命令查看用户可打开文件数限制始终高于上述步骤中设置的最大值,这可能是由于在用户登入脚本/etc/profile中使用ulimit-n命令早已将用户可同时打开的文件数做了限制。因为通过ulimit-n更改系统对用户可同时打开文件的最大数限制时,新更改的值只能大于或等于先前ulimit-n设置的值,因而想用此命令减小这个限制值是不可能的。
所以,假若有上述问题存在,就只能去打开/etc/profile脚本文件,在文件中查找是否使用了ulimit-n限制了用户可同时打开的最大文件数目,假若找到,则删掉这行命令,或则将其设置的值改为合适的值,之后保存文件,用户退出并重新登入系统即可。通过上述步骤,就为支持高并发TCP联接处理的通信处理程序解除关于打开文件数目方面的系统限制。
二、修改网路内核对TCP联接的有关限制
在Linux上编撰支持高并发TCP联接的顾客端通信处理程序时,有时会发觉虽然早已解除了系统对用户同时打开文件数的限制,但仍会出现并发TCP联接数降低到一定数目时,再也未能成功构建新的TCP联接的现象。出现这些现今的缘由有多种。
第一种诱因可能是由于Linux网路内核对本地端标语范围有限制。此时,进一步剖析为何未能完善TCP联接,会发觉问题出在connect()调用返回失败,查看系统错误提示消息是”Can’tassignrequestedaddress”.同时,假如在此时用tcpdump工具监视网路,会发觉根本没有TCP联接时顾客端发SYN包的网路流量。这种情况说明问题在于本地Linux系统内核中有限制。
虽然,问题的根本缘由在于Linux内核的TCP/IP合同实现模块对系统中所有的顾客端TCP联接对应的本地端标语的范围进行了限制(比如,内核限制本地端标语的范围为1024~32768之间)。当系统中某一时刻同时存在太多的TCP顾客端联接时,因为每位TCP顾客端联接都要占用一个惟一的本地端标语(此端标语在系统的本地端标语范围限制中),假如现有的TCP顾客端联接已将所有的本地端标语占满,则此时就难以为新的TCP顾客端联接分配一个本地端标语了,为此系统会在这些情况下在connect()调用中返回失败,并将错误提示消息设为”Can’tassignrequestedaddress”.
有关这种控制逻辑可以查看Linux内核源代码,以linux2.6内核为例,可以查看tcp_ipv4.c文件中如下函数:
staticinttcp_v4_hash_connect(structsock*sk)
请注意上述函数中对变量sysctl_local_port_range的访问控制。变量sysctl_local_port_range的初始化则是在tcp.c文件中的如下函数中设置:
void__inittcp_init(void)
内核编译时默认设置的本地端标语范围可能太小,因而须要更改此本地端口范围限制。
第一步,更改/etc/sysctl.conf文件linux系统镜像下载,在文件中添加如下行:
net.ipv4.ip_local_port_range=102465000
这表明将系统对本地端口范围限制设置为1024~65000之间。请注意,本地端口范围的最小值必须小于或等于1024;而端口范围的最大值则应大于或等于65535.更改完后保存此文件。
第二步,执行sysctl命令:
[speng@as4~]$sysctl-p
假如系统没有错误提示,就表明新的本地端口范围设置成功。假如按上述端口范围进行设置,则理论上单独一个进程最多可以同时完善60000多个TCP顾客端联接。
第二种未能完善TCP联接的诱因可能是由于Linux网路内核的防火墙对最大跟踪的TCP联接数有限制。此时程序会表现为在connect()调用中阻塞,就像关机,假如用tcpdump工具监视网路,也会发觉根本没有TCP联接时顾客端发SYN包的网路流量。因为防火墙在内核中会对每位TCP联接的状态进行跟踪,跟踪信息将会置于坐落内核显存中的conntrackdatabase中,这个数据库的大小有限,当系统中存在过多的TCP联接时,数据库容量不足,IP_TABLE未能为新的TCP联接构建跟踪信息,于是表现为在connect()调用中阻塞。此时就必须更改内核对最大跟踪的TCP联接数的限制,技巧同更改内核对本地端标语范围的限制是类似的:
第一步,更改/etc/sysctl.conf文件,在文件中添加如下行:
net.ipv4.ip_conntrack_max=10240
这表明将系统对最大跟踪的TCP联接数限制设置为10240.请注意,此限制值要尽量小,以节约对内核显存的占用。
第二步,执行sysctl命令:
[speng@as4~]$sysctl-p
假如系统没有错误提示,就表明系统对新的最大跟踪的TCP联接数限制更改成功。假如按上述参数进行设置,则理论上单独一个进程最多可以同时完善10000多个TCP顾客端联接。
三、
使用支持高并发网路I/O的编程技术在Linux上编撰高并发TCP联接应用程序时,必须使用合适的网路I/O技术和I/O风波分派机制。可用的I/O技术有同步I/O,非阻塞式同步I/O(亦称反应式I/O),以及异步I/O.在高TCP并发的情形下,假如使用同步I/O,这会严重阻塞程序的运转,除非为每位TCP联接的I/O创建一个线程。
然而linux tcp连接数限制,过多的线程又会因系统对线程的调度引起巨大开支。为此,在高TCP并发的情形下使用同步I/O是不可取的,这时可以考虑使用非阻塞式同步I/O或异步I/O.非阻塞式同步I/O的技术包括使用select(),poll(),epoll等机制。异步I/O的技术就是使用AIO.
从I/O风波分派机制来看,使用select()是不合适的,由于它所支持的并发联接数有限(一般在1024个以内)。假如考虑性能,poll()也是不合适的linux tcp连接数限制,虽然它可以支持的较高的TCP并发数,并且因为其采用”协程”机制,当并发数较高时,其运行效率相当低,并可能存在I/O风波分派不均,引起部份TCP联接上的I/O出现”饥饿”现象。而假如使用epoll或AIO,则没有上述问题(初期Linux内核的AIO技术实现是通过在内核中为每位I/O恳求创建一个线程来实现的,这些实现机制在高并发TCP联接的情形下使用似乎也有严重的性能问题。但在最新的Linux内核中,AIO的实现早已得到改进)。
综上所述,在开发支持高并发TCP联接的Linux应用程序时,应尽量使用epoll或AIO技术来实现并发的TCP联接上的I/O控制,这将为提高程序对高并发TCP联接的支持提供有效的I/O保证。
内核参数sysctl.conf的优化
/etc/sysctl.conf是拿来控制linux网路的配置文件,对于依赖网路的程序(如web服务器和cache服务器)十分重要,RHEL默认提供的最好调整。
推荐配置(把原/etc/sysctl.conf内容清掉,把下边内容复制进去):
cp/etc/sysctl.conf/etc/sysctl.conf.bak
echo””>/etc/sysctl.conf
vim/etc/sysctl.conf
net.ipv4.ip_local_port_range=102465535
net.core.rmem_max=16777216
net.core.wmem_max=16777216
net.ipv4.tcp_rmem=40968738016777216
net.ipv4.tcp_wmem=40966553616777216
net.ipv4.tcp_fin_timeout=10
net.ipv4.tcp_tw_recycle=1
net.ipv4.tcp_timestamps=0
net.ipv4.tcp_window_scaling=0
net.ipv4.tcp_sack=0
dev_max_backlog=30000
net.ipv4.tcp_no_metrics_save=1
net.core.somaxconn=10240
net.ipv4.tcp_syncookies=0
net.ipv4.tcp_max_orphans=262144
net.ipv4.tcp_max_syn_backlog=262144
net.ipv4.tcp_synack_retries=2
net.ipv4.tcp_syn_retries=2
这个配置参考于cache服务器varnish的推荐配置和SunOne服务器系统优化的推荐配置。
不过varnish推荐的配置是有问题的,实际运行表明”net.ipv4.tcp_fin_timeout=3″的配置会造成页面常常打不开;而且当网友使用的是IE6浏览器时,访问网站一段时间后,所有网页就会打不开,重启浏览器后正常。可能是美国的网速快吧,我们国情决定须要调整”net.ipv4.tcp_fin_timeout=10″,在10s的情况下,一切正常(实际运行推论)。
更改完毕后,执行:
sysctl-p/etc/sysctl.conf
sysctl-wnet.ipv4.route.flush=1
命令生效。为了保险起见,也可以reboot系统。
调整打开最大文件句柄数(单个进程最大tcp联接数=单个进程最大socket联接数):
linux系统优化完网路必须调高系统容许打开的文件数能够支持大的并发,默认1024是远远不够的。
执行命令:
Shell代码
echo”ulimit-HSn65536″>>/etc/rc.local
echo”ulimit-HSn65536″>>/root/.bash_profile
ulimit-HSn65535
以上就是高并发下 web 服务器和 cache 服务器 socket 最大连接数限制调整方法的详细内容,更多请关注小闻网其它相关文章!
评论(0)