Linux高并发踩过的坑及性能优化介绍

目录前言Linux应用运行过程中出现Toomanyopenfiles问题分析和解决Linux高并发下time_wait过多的问题分析及解决Linux更多性能优化小结前言Linux操作系统是...

前言

Linux操作系统是现在服务器的首选操作系统,在Linux的默认系统参数下,Linux针对高并发的支持性并不是很好。小编从事Linux下应用程序开发多年,关于Linux系统下的高并发,小编自己踩过的坑,及如何解决踩过的坑下面列上几条,供大家参考,避免再次掉坑。

Linux应用运行过程中出现Too many open files 问题分析和解决

出现这句提示的原因是程序打开的文件socket连接数量超过系统设定值。

查看每个用户最大允许打开的文件数量


ulimit -a

其中 open files (-n) 1024 表示每个用户最大允许打开的文件数量是1024

当前系统文件句柄的最大数目,只用于查看,不能设置修改


cat /proc/sys/fs/file-max

查看某个进程的打开文件限制数


cat /proc/10446(pid)/limits

设置open files 数值方法


ulimit -n 65535 

这种设置方法在重启后会还原为默认值。

永久设置方法:


vim /etc/security/limits.conf

在最后加入


* soft nofile 65535

* hard nofile 65535

生效需要重启系统

这样修改之后,问题得到有效解决。

Linux高并发下 time_wait 过多的问题分析及解决

现象是高并发场景下,服务器运行应用卡顿。

排查方法:查看服务器配置:


netstat -ant|awk '/^tcp/ {++S[$NF]} END {for(a in S) print (a,S[a])}'

发现处于 time_wait 的数量太多,有几万条,应该是大量socket处于TIME_WAIT状态。如果客户端的并发量持续很高,此时部分客户端就会显示连接不上。这个值偏高,可修改为2.这个值仅仅是针对对外的连接,对进来的连接,是由tcp_retries1 决定的)

#net.ipv4.tcp_tw_len = 1

表示开启重用,允许将TIME-WAIT Sockets重新用于新的TCP连接,默认为0,表示关闭。这个对快速重启动某些服务,而启动后提示端口已经被使用的情形非常有帮助。

tcp_mem有3个INTEGER变量:low, pressure, high

low:当TCP使用了低于该值的内存页面数时,TCP没有内存压力,TCP不会考虑释放内存。(理想情况下,这个值应与指定给tcp_wmem的第2个值相匹配。这第2个值表明,最大页面大小乘以最大并发请求数除以页大小 (131072*300/4096)

pressure:当TCP使用了超过该值的内存页面数量时,TCP试图稳定其内存使用,进入pressure模式,当内存消耗低于low值时则退出pressure状态。(理想情况下这个值应该是TCP可以使用的总缓冲区大小的最大值(204800*300/4096)

high:允许所有TCP Sockets用于排队缓冲数据报的页面量。如果超过这个值,TCP连接将被拒绝,这就是为什么不要令其过于保守(512000*300/4096)的原因了。在这种情况下,提供的价值很大,它能处理很多连接,是所预期的2.5倍;或者使现有连接能够传输2.5倍的数据。

一般情况下这些值是在系统启动时根据系统内存数量计算得到的。

系统所能处理不属于任何进程的TCP sockets最大数量。假如超过这个数量﹐那么不属于任何进程的连接会被立即reset,并同时显示警告信息。之所以要设定这个限制﹐纯粹为了抵御那些简单的DoS攻击﹐千万不要依赖这个或是人为的降低这个限制

如果套接字由本端要求关闭,这个参数决定了它保持在FIN-WAIT-2状态的时间。对端可以出错并永远不关闭连接,甚至意外当机。缺省值是60秒。2.2 内核的通常值是180秒,你可以按这个设置,但要记住的是,即使你的机器是一个轻载的WEB服务器,也有因为大量的死套接字而内存溢出的风险,FIN-WAIT-2的危险性比FIN-WAIT-1要小,因为它最多只能吃掉1.5K内存,但是它们的生存期长些。

设置系统对最大跟踪的TCP连接数的限制(CentOS 5.6无此参数)

同时还涉及到一个TCP 拥塞算法的问题,你可以用下面的命令查看本机提供的拥塞算法控制模块:


sysctlnet.ipv4.tcp_available_congestion_control

对于几种算法的分析,详情可以参考下:TCP拥塞控制算法的优缺点、适用环境、性能分析,比如高延时可以试用hybla,中等延时可以试用htcp算法等。

如果想设置TCP 拥塞算法为hybla


#设置TCP 拥塞算法
net.ipv4.tcp_congestion_control=hybla

对于内核版高于于3.7.1的,我们可以开启tcp_fastopen:


#开启tcp_fastopen
net.ipv4.tcp_fastopen= 3

Iptables相关

如非必须,关掉或卸载iptables防火墙,并阻止kernel加载iptables模块。这些模块会影响并发性能。

IO事件分配机制

在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连接的情形下使用其实也有严重的性能问题。但在最新的Linux内核中,AIO的实现已经得到改进)。

小结

综上所述,在开发支持高并发TCP连接的Linux应用程序时,应尽量使用epoll或AIO技术来实现并发的TCP连接上的I/O控制,这将为提升程序对高并发TCP连接的支持提供有效的I/O保证。

经过以上描述的优化配置之后,服务器的TCP并发处理能力会显著提高。上文所述配置仅供参考,用于生产环境请根据自己开发系统所部署的实际情况调整观察再调整。

到此这篇关于Linux高并发踩过的坑及性能优化介绍的文章就介绍到这了,更多相关Linux高并发及性能优化内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

本文标题为:Linux高并发踩过的坑及性能优化介绍

基础教程推荐