在本系列的第一篇(http://maoyidao.iteye.com/blog/1744277)中介绍了TCP状态以及服务器上常出现的TIME_WAIT和CLOSE_WAIT状态的成因、影响和解决方法。本篇主要解读在一台并发15万连接的HTTP服务上的系统配置
Linux系统资源限制
1. 最大文件数
查看进程允许打开的最大文件句柄数:ulimit -n
查看进程所占的文件描述符: lsof -p xxx | wc -l
设置进程能打开的最大文件句柄数:ulimit -n xxx
2. ulimit -n vs. file-max ?
简单的说, ulimit -n控制进程级别能够打开的文件句柄的数量, 而max-file表示系统级别的能够打开的文件句柄的数量。
ulimit -n的设置在重启机器后会丢失,因此需要修改limits.conf的限制,limits.conf中有两个值soft和hard,soft代表只警告,hard代表真正的限制
* soft nofile 150000
* hard nofile 150000
这里我们把soft和hard设置成一样的。
“cat /proc/sys/fs/file-max”,或“sysctl -a | grep fs.file-max”查看系统能打开的最大文件数。查看和设置例如:
[root@vm014601 ~]# sysctl -a |grep fs.file-max
fs.file-max = 200592
[root@vm014601 ~]# echo "fs.file-max = 2005920" >> /etc/sysctl.conf
[root@vm014601 ~]# sysctl -p
[root@vm014601 ~]# cat /proc/sys/fs/file-max
2005920
file-nr是只读文件,第一个数代表了目前分配的文件句柄数;第二个数代表了系统分配的最大文件句柄数;比如线上系统查看结果:
# cat /proc/sys/fs/file-max
1106537
# cat /proc/sys/fs/file-nr
1088 0 1106537
# lsof | wc -l
1506
可以看到file-nr和lsof的值不是很一致,但是数量级一致。为什么会不一致?原因如下:
写道
lsof是列出系统所占用的资源,但是这些资源不一定会占用打开文件号的.
比如共享内存,信号量,消息队列,内存映射.等,虽然占用了这些资源,但不占用打开文件号.
我曾经在前端机上很长时间都无法得到lsof | wc -l 的结果,这个时候可以通过file-nr粗略的估算一下打开的文件句柄数。
3. sysckernel.threads-max
指定了内核所能使用的线程(所有进程打开线程之和)的最大数目,通过命令 “cat /proc/sys/kernel/threads-max” 查看当前值。查看和设置例如:
sysctl -a | grep threads
vm.nr_pdflush_threads = 2
kernel.threads-max = 229376
本厂系统配置允许打开的线程数 > 229k
如果此值设小了会导致:-bash: fork: Resource temporarily unavailable
4. 为什么有限制?
为什么Linux内核对文件句柄数、线程和进程的最大打开数进行了限制?以及如果我们把它调的太大,会产生什么样的后果?
原因1 - 资源问题:the operating system needs memory to manage each open file, and memory is a limited resource - especially on embedded systems.
原因2 - 安全问题:if there were no limits, a userland software would be able to create files endlessly until the server goes down.
最主要的是资源问题,为防止某一单一进程打开过多文件描述符而耗尽系统资源,对进程打开文件数做了限制。
5. 设置成多少比较合适?
网上有朋友给了估算公式:file-max number = RAM size/10k;
I am not a kernel expert, but as far as I can see, the default for file-max seems to be RAM size divided by 10k. As the real memory used per file handler should be much smaller (size of struct file plus some driver dependent memory), this seems a quite conservative limit. – jofel Apr 19 at 16:43
那么一个12G RAM 的前端机可以打开接近1M的文件。真的可以打开1百万个文件吗?
为了试验,基于MINA写了一个NIO服务,在一个服务上创建了50万活跃率约为1%的TCP连接。观察内存使用 < 4.5G,可以粗略认为单个socket连接使用内存小于10K。因此可以用上面的公式来简单估算。
6. Orphan socket
不属于任何进程的socket叫orphan socket。这里顺便一下讨论orphan socket,因为很多网络资源不足导致的错误都和“孤儿socket”有关。
6.1 Orphan socket是怎么产生的呢?
网上没有明确的说明,我们做一个线上调查:
[maoyidao@03701 ~]# netstat -nap | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}'
2976/sshd 1
11065/gearman 1
- 2166
32726/java 31455
25554/scribed 4
[maoyidao@03701 ~]# netstat -nap | awk '/^tcp/ {if($NF == "-") {++S[$6]}} END {for(a in S) print a, S[a]}'
TIME_WAIT 451
FIN_WAIT1 655
ESTABLISHED 118
FIN_WAIT2 102
SYN_RECV 249
CLOSING 2
LAST_ACK 619
可以看到任何一个TCP stat情况下都有可能产生“orphan socket”,但多数是在建立过程当中,以及断开连接中的socket。
可以通过以下参数减少orphan socket的产生。
sysctl -a | grep orphan
net.ipv4.tcp_orphan_retries = 0
net.ipv4.tcp_max_orphans = 65536
6.2 Orphan socket要消耗多少系统资源?
网上的说法是一个orphan socket需要占用64K内存,查到该说法的出路来自这里:http://www.kernel.org/doc/man-pages/online/pages/man7/tcp.7.html
tcp_max_orphans (integer; default: see below; since Linux 2.4)
The maximum number of orphaned (not attached to any user file handle)
TCP sockets allowed in the system. When this number is exceeded, the
orphaned connection is reset and a warning is printed. This limit
exists only to prevent simple denial-of-service attacks. Lowering this
limit is not recommended. Network conditions might require you to
increase the number of orphans allowed, but note that each orphan can
eat up to ~64K of unswappable memory. The default initial value is set
equal to the kernel parameter NR_FILE. This initial default is
adjusted depending on the memory in the system.
难道Orphan Socket占用的资源比普通socket多?maoyidao还没有来得及试验,但从理论上讲,占用资源多少和是否是orphan socket是无关的。
7. Out of socket memory
谈到Orphan Socket就需要提一下“Out of socket memory”错误。网上已有很清晰的说明:http://jaseywang.me/2012/05/09/%E5%85%B3%E4%BA%8E-out-of-socket-memory-%E7%9A%84%E8%A7%A3%E9%87%8A-2/
摘录一段:
cat /proc/sys/net/ipv4/tcp_mem
69618 92825 139236
第一个数字表示,当 tcp 使用的 page 少于 69618 时,kernel 不对其进行任何的干预
第二个数字表示,当 tcp 使用了超过 92825 的 pages 时,kernel 会进入 “memory pressure”
第三个数字表示,当 tcp 使用的 pages 超过 139236 时,我们就会看到题目中显示的信息
maoyidao注:tcp_mem里的数字是page数,转换成字节需要看下系统的page size有多大:
getconf PAGESIZE
4096
看看本厂的设置:
cat /proc/sys/net/ipv4/tcp_mem
196608 262144 393216
可以看到我们设置的比较大,这是针对前端机的一些优化。再看一下系统当前的情况
[maoyidao@03701 ~]# cat /proc/net/sockstat
sockets: used 30755
TCP: inuse 31684 orphan 1166 tw 600 alloc 31866 mem 5838
UDP: inuse 4 mem 0
RAW: inuse 0
FRAG: inuse 0 memory 0
下一篇继续讨论其他内核参数。
分享到:
相关推荐
执行 makefile后,会生成两个可执行文件 fdtrans -- unix socket server fdtranc --unix socket client 先运行 fdtrans 建立监听, 然后 运行fdtranc fdtranc 连接fdtrans并得到 文件 fdtrans.cpp的句柄。...
易语言根据文件句柄取文件路径源码,根据文件句柄取文件路径,文件句柄取文件路径名,lopen,ZwQueryObject,WToM,lclose,QueryDosDevice,StrCmpNI
C++基础辅助类库,比如异步进行-Thread,安全句柄-CHandle,资源守卫-Guard,XML解析-rapidxml,以及其他注册表、文件基础操作
★ 支持多Socket并行测试, 采用树状Socket可视化界面,所有Socket句柄一目了然 ★ 在一个程序内可进行多句柄/多类型的Socket的创建/删除/以及数据收发等操作 ★ 支持16进制的发送和16进制接收显示,支持汉字以及文本...
资源名称:网络编程 - Socket内容简介:Socket的英文原义是“孔”或“插座”。作为BSD UNIX的进程通信机制,取后一种意思。通常也称作"套接字",用于描述IP地址和端口,是一个通信链的句柄,可以用来实现不同虚拟机...
易语言纯代码取 进程PID 进程句柄 进程模块句柄(CE查找的进程名加偏移就相当于模块句柄加偏移)
火山PC,dm进阶操作-获取模块-句柄-互斥体可以用来提权,降权,句柄操作,关闭互斥体操作 互斥体一般用来关闭多开限制使用。 包括C++版的dm源码,都在里面。
从打开的文件句柄获得文件的路径.根据HANDLE获得文件路径
行业分类-设备装置-基于文件句柄的数据读写方法、装置及计算设备
枚举内核对象句柄-易语言
170已知窗口句柄获得其EXE应用程序路径
易语言文件号和文件句柄互转模块源码,文件号和文件句柄互转模块,文件号转句柄,句柄转文件号,CopyMemory,ZwClose,ZwQueryInformationFile
在vue开发时需要在页面跳转的时候传递...然后第一个页面跳转的时候不发送emit触发,到第二个页面向第一个页面发送mitt,第一个页面接收之后再由第一个页面把文件句柄发送到第二个页面。这样就完成了在页面之间的传递。
WORD版MATLAB经典入门教程连载4-第九章句柄图形.doc 抱歉的是没有了第六章 但是实用的那几章都有 而且做了目录 方便查询和阅读 希望对大家有点帮助啊 第八 九章 是重中之中重 加起来有20M 所以压缩了
VB获取外部程序的控件句柄,根据句柄,简单实现对外程序控件的操作例程。
ViewWizard-查看窗口句柄
文章目录文件句柄查看用户级别(nofile)单个进程级别(nr_open )系统级别(file-max)修改用户级别(nofile)单个进程级别(nr_open )系统级别(file-max)总结参考 tips: 网上说什么的也有,你抄我的我抄你的...
在服务端不存在或没开启时,clientsocket反复连接服务端会导致程序句柄数急速增加,最后系统资源耗尽出错,本demo较好的解决了这一问题.