众所周知,Linux在默认参数下对高并发的支持并不好,主要受制于单进程最大打开文件数限制、内核TCP参数、和IO事件分发机制。下面从几个方面进行调整,使Linux系统能够支持高并发环境。如果不需要iptables,关闭或卸载iptables防火墙,防止内核加载iptables模块。这些模块影响并发性能。单个进程打开文件的最大数量是有限制的。一般release版本限制单进程最大打开文件数为1024,远远不能满足高并发的要求。调整过程如下:在提示符下输入#ulimit–n65535设置root启动的单个进程最多可以打开的文件数为65535。如果系统显示类似“Operationnotpermitted”的信息,则表示修改上述限制失败。实际上,指定的值超过了Linux系统对用户打开文件数的软限制或硬限制。因此,需要修改Linux系统对用户打开文件数的软限制和硬限制。第一步修改limits.conf文件,加入:#vim/etc/security/limits.conf*softnofile65535*hardnofile65535其中'*'表示修改所有用户的限制;soft或hard指定修改软nofile限制仍然是硬限制;65536指定要修改的新限制值,即最大打开文件数(请注意软限制值应小于或等于硬限制)。修改后保存文件。第二步,修改/etc/pam.d/login文件,在文件中加入如下一行:#vim/etc/pam.d/loginsessionrequired/lib/security/pam_limits.so这个是告诉Linux登录在用户完成系统后,应该调用pam_limits.so模块来设置系统对用户可以使用的各种资源的最大数量限制(包括用户可以打开的最大文件数量),pam_limits.so模块将来自/etc/security/limits。conf文件来设置这些限制。修改后保存此文件。第三步,查看linux系统级别的最大打开文件数,使用命令如下:#cat/proc/sys/fs/file-max32568这表示这个linux系统允许最大打开文件数同时(即包括所有用户的打开文件数之和)32568个文件,这是Linux系统级别的硬限制,所有用户级别的打开文件数限制不能超过这个价值。通常,这个系统级硬限制是Linux系统在启动时根据系统硬件资源情况计算出的最大同时打开文件数的最佳限制。如果没有特殊需要,这个限制不要修改,除非你想限制用户级别的打开文件数。设置一个高于此限制的值。修改这个硬限制的方法是修改/etc/sysctl.conf文件中的fs.file-max=131072。这是为了让Linux在启动完成后强制将系统级别的打开文件数硬限制设置为131072。修改后保存此文件。完成以上步骤后,重启系统。一般情况下,可以将Linux系统允许指定用户的单个进程同时打开的最大文件数限制为指定值。如果重启后使用ulimit-n命令限制用户可打开的文件数仍然低于上述步骤设置的最大值,可能是因为ulimit-n命令已经被使用用户登录脚本/etc/profile允许用户同时打开文件。文件数量有限。因为在通过ulimit-n修改系统限制用户同时打开的最大文件数时,新修改的值只能小于或等于上次ulimit-n设置的值,所以无法使用此命令增加的限制值。因此,如果存在以上问题,只能打开/etc/profile脚本文件,查看文件中是否使用了ulimit-n来限制用户同时打开的最大文件数。如果找到,删除这行命令。或者将其设置的值更改为合适的值,然后保存文件,用户可以注销并重新登录系统。通过以上步骤,对于支持高并发TCP连接处理的通信处理程序,解除了系统打开文件数的限制。在内核TCP参数方面,在Linux系统下,TCP连接断开后,会保持一定时间的TIME_WAIT状态,然后释放端口。当并发请求过多时,会产生大量TIME_WAIT状态的连接。如果不能及时断开连接,将会占用大量的端口资源和服务器资源。这时候我们可以优化TCP的内核参数,及时清理处于TIME_WAIT状态的端口。下面介绍的方法只对大量TIME_WAIT状态的连接造成的系统资源消耗有效。如果不是这样,效果可能不明显。可以使用netstat命令查看TIME_WAIT状态的连接状态,输入以下组合命令查看当前TCP连接状态和对应的连接数:#netstat-n|awk'/^tcp/{++S[$NF]}END{for(ainS)printa,S[a]}'会输出类似下面的结果:LAST_ACK16SYN_RECV348ESTABLISHED70FIN_WAIT1229FIN_WAIT230CLOSING33TIME_WAIT18098,可以看到这里有18000多个TIME_WAIT,所以18000多个端口被占用了。要知道端口数只有65535个,如果少占用一个,会严重影响后续新建连接。这种情况下,我们就需要调整Linux的TCP内核参数,让系统更快的释放TIME_WAIT连接。编辑配置文件:/etc/sysctl.conf,在该文件中添加如下几行:#vim/etc/sysctl.confnet.ipv4.tcp_syncookies=1net.ipv4.tcp_tw_reuse=1net.ipv4.tcp_tw_recycle=1net.ipv4.tcp_fin_timeout=30输入以下命令使内核参数生效:#sysctl-p简单解释一下以上参数的含义:net.ipv4.tcp_syncookies=1表示启用SYNCookies。当SYN等待队列溢出时,启用cookies进行处理,可以防止少量的SYN攻击。默认值为0,表示关闭;net.ipv4.tcp_tw_reuse=1表示启用重用。允许TIME-WAITsockets被重新用于新的TCP连接,默认为0,表示关闭;net.ipv4.tcp_tw_recycle=1表示开启TCP连接中TIME-WAITsockets的快速回收,默认为0,表示关闭;net.ipv4。tcp_fin_timeout修改系统默认的TIMEOUT时间。经过这样的调整,除了可以进一步提高服务器的负载能力外,还可以防御小流量级别的DoS、CC和SYN攻击。另外,如果你的连接很多,我们可以优化TCP的可用端口范围,进一步提高服务器的并发能力。仍然在上述参数文件中添加如下配置:net.ipv4.tcp_keepalive_time=1200net.ipv4.ip_local_port_range=102465535net.ipv4.tcp_max_syn_backlog=8192net.ipv4.tcp_max_tw_buckets=5000在大型服务器上开启会有一个显着的效果。在流量小的服务器上,不需要设置这些参数。net.ipv4.tcp_keepalive_time=1200表示启用keepalive时TCP发送keepalive报文的频率。默认为2小时,将其更改为20分钟。ip_local_port_range=102465535表示出站连接的端口范围。默认小,改成1024到65535。net.ipv4.tcp_max_syn_backlog=8192表示SYN队列的长度,默认是1024,增加队列长度到8192可以容纳更多等待连接的网络连接。net.ipv4.tcp_max_tw_buckets=5000表示系统同时维持TIME_WAIT的最大数量。如果超过这个数字,TIME_WAIT将被立即清除并打印一条警告信息。默认是180000,改成5000。这个参数可以控制TIME_WAIT的最大次数,只要超过就可以了。内核的其他TCP参数说明net.ipv4.tcp_max_syn_backlog=65535记录了那些没有收到客户端确认信息的连接请求的最大值。对于128M内存的系统,默认值为1024,对于内存较小的系统,为128。net.core.netdev_max_backlog=32768每个网络接口接收数据包速度更快时允许发送到队列的最大数据包数比内核可以处理它们。net.core.somaxconn=32768比如web应用中listen函数的backlog默认会将我们内核参数的net.core.somaxconn限制为128,而nginx定义的NGX_LISTEN_BACKLOG默认值为511,所以它有必要调整这个值。net.core.wmem_default=8388608net.core.rmem_default=8388608net.core.rmem_max=16777216#最大socket读缓冲区,参考优化值:873200net.core.wmem_max=16777216#最大socket写缓冲区,参考优化值:873200net.ipv4.tcp_timestsmps=0时间戳可以避免序列号回绕。一个1Gbps的链接肯定会遇到以前使用过的序列号。时间戳使内核能够接受这种“异常”数据包。这里需要关掉。net.ipv4.tcp_synack_retries=2要打开与对等方的连接,内核需要发送一个SYN,然后发送一个ACK??以响应前一个SYN。这是所谓的三次握手中的第二次握手。此设置确定在内核放弃连接之前发送的SYN+ACK数据包的数量。net.ipv4.tcp_syn_retries=2内核放弃建立连接前发送的SYN包数。#net.ipv4.tcp_tw_len=1net.ipv4.tcp_tw_reuse=1启用重用。允许TIME-WAIT套接字重新用于新的TCP连接。net.ipv4.tcp_wmem=8192436600873200TCP写缓冲区,可可参考的:8192436600873200NET.IPV4.TCP_RMEM=32768436600436600873200TCPPPPPPPPPPPPPPPPPPPPPPPPPPPP读173273334333.319319.333.33.13.可有3个值,意思是:net.ipv4.tcp_mem[0]:低于这个值,TCP没有内存压力。net.ipv4.tcp_mem[1]:在此值下,进入内存压力阶段。net.ipv4.tcp_mem[2]:超过这个值,TCP拒绝分配套接字。上面的内存单位是页,不是字节。参考优化值为:78643210485761572864net.ipv4.tcp_max_orphans=3276800系统最大TCP套接字数,不关联任何用户文件句柄。如果超过这个数字,连接将立即重置,并打印一条警告消息。这个限制只是为了防止简单的DoS攻击,不能过分依赖或者人为的降低这个值,应该增加这个值(如果增加内存的话)。net.ipv4.tcp_fin_timeout=30如果socket被本端关闭,这个参数决定了它保持在FIN-WAIT-2状态的时间。对等方可能会出错而永远不会关闭连接,甚至会意外崩溃。默认值为60秒。2.2kernel的通常值是180秒,可以按这个设置,但是要记住,即使你的机器是轻载的WEB服务器,也有大量deadsockets导致内存溢出的风险,FIN-WAIT-2没有FIN-WAIT-1危险,因为它最多只能吃掉1.5K的内存,但它们的生命周期更长。同时,还涉及到一个TCP拥塞算法的问题。可以使用如下命令查看本机提供的拥塞算法控制模块:sysctlnet.ipv4.tcp_available_congestion_control几种算法的分析,具体可以参考以下:TCP拥塞控制算法的缺点、适用环境、性能分析,比如高延迟可以试试hybla,中等延迟可以试试htcp算法等。如果要设置TCP拥塞算法为hyblanet.ipv4.tcp_congestion_control=hyblaextra,对于3.7.1以上的内核版本,我们可以开启tcp_fastopen:net.ipv4.tcp_fastopen=3IO事件分发机制在Linux上启用高并发TCP连接,需要确认应用程序是否使用了合适的网络I/O技术和I/O事件分发机制。可用的I/O技术有同步I/O、非阻塞同步I/O和异步I/O。在高TCP并发的情况下,如果使用同步I/O,这会严重阻塞程序的运行,除非为每个TCP连接的I/O创建一个线程。但是过多的线程会由于系统对线程的调度而造成巨大的开销。因此,在TCP并发较高的情况下,不建议使用同步I/O。这时候可以考虑非阻塞同步I/O或者异步I/O。非阻塞同步I/O技术包括使用select()、poll()、epoll等机制。异步I/O的技术就是使用AIO。从I/O事件派发机制来看,使用select()是不合适的,因为它支持的并发连接数是有限的(一般在1024以内)。如果考虑性能,poll()也不合适。虽然它可以支持很高的TCP并发数,但是由于它的“轮询”机制,当并发数很高的时候,它的运行效率是相当低的,并且可能会出现I/O事件分布不均导致“饥饿”"一些TCP连接上的I/O。而如果使用epoll或者AIO,就没有上述问题(早期Linux内核的AIO技术实现是通过在内核中为每个I/O请求创建一个线程来实现的,这种实现机制是在高负载的情况下并发TCP连接使用AIO也存在严重的性能问题。但在最新的Linux内核中,AIO的实现得到了改进)。综上所述,在开发支持高并发TCP连接的Linux应用程序时,应尽可能使用epoll或AIO技术实现对并发TCP连接的I/O控制,这将为提高程序对高并发TCP连接的支持提供高效I/O保证。经过这样的优化配置后,服务器的TCP并发处理能力将得到显着提升。以上配置仅供参考,生产环境使用请根据自己的实际情况调整、观察、调整。以上就是良序教程网为各位小伙伴分享的Linux服务器高并发调优实战操作。以上就是良序教程网为各位小伙伴们分享的Linux相关知识。
