`

通讯系统经验谈【二】解读内核参数 - socket/文件句柄资源限制参数

 
阅读更多

在本系列的第一篇(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

 

 

下一篇继续讨论其他内核参数。

分享到:
评论
1 楼 qwe1234567890 2014-06-23  

相关推荐

    使用 socket 传递文件句柄源码

     执行 makefile后,会生成两个可执行文件 fdtrans -- unix socket server fdtranc --unix socket client 先运行 fdtrans 建立监听, 然后 运行fdtranc fdtranc 连接fdtrans并得到 文件 fdtrans.cpp的句柄。...

    linux系统级别的能够打开的文件句柄的数file-max命令.docx

    Linux 系统中,file-max 命令用于设置系统级别的能够打开的文件句柄的数量,这个值决定了 Linux 内核可以分配的文件句柄的最大数量。当系统中的文件句柄数量达到这个值时,系统将不能再打开新的文件句柄,从而导致...

    linux内核 0.11版本源码 带中文注释

    #define ORIG_ROOT_DEV (*(unsigned short *)0x901FC) // 根文件系统所在设备号。 /* * Yeah, yeah, it's ugly, but I cannot find how to do this correctly * and this seems to work. I anybody has more ...

    易语言根据文件句柄取文件路径源码

    文件句柄是操作系统为了标识和访问文件而分配的一个唯一数值,它是进程内部用来识别打开文件的一种抽象表示。在易语言中,我们可以通过系统提供的函数来获取或操作文件句柄,从而进行一系列的文件操作,比如读取、...

    Linux内核调优

    然而,Linux系统默认对每个进程可打开的文件句柄数量进行了限制,这通常是基于安全性和资源管理的考虑。 #### 三、查看当前文件句柄限制 在Linux中,可以通过`ulimit -n`命令来查看当前用户的进程可打开文件句柄的...

    centos64安装oracle11g详文图解

    根据提供的文件内容,我们将详细解读在CentOS 64位系统上安装Oracle 11g的步骤,以下知识点涵盖了从准备工作到安装配置的所有要点: 1. 清空原有yum信息和更新yum: - 使用yum clean all命令清空yum缓存。 - 使用...

    易语言根据文件句柄取文件路径

    这通常涉及到Windows内部的文件系统操作,因此需要对Windows API有深入理解。 `WToM`函数是易语言中的字符串转换函数,它的作用是将宽字符(Unicode)字符串转换为多字节字符串。由于Windows API中的一些函数接受的...

    oracle11g设置内核参数和limit的增强

    传统的Oracle数据库安装过程中,数据库管理员(DBA)需要手动编辑`/etc/sysctl.conf`和`/etc/security/limits.conf`这两个关键文件来调整操作系统级别的内核参数和资源限制。这种做法不仅耗时费力,而且容易出现人为...

    易语言枚举内核对象句柄

    这些对象包括进程、线程、信号量、事件、互斥体、文件系统对象等。它们代表了系统中的一些状态和资源,通过句柄来引用和操作。 句柄是操作系统分配给这些内核对象的一个唯一标识符,它不是一个直接的内存地址,而是...

    vb源码--已知窗口句柄获得其EXE应用程序路径

    窗口句柄(HWND)是Windows操作系统用来唯一标识一个窗口的对象句柄,而获取其EXE路径则可以帮助我们了解该窗口所属的应用程序信息。 首先,我们需要理解窗口句柄(HWND)。在Windows系统中,每个窗口都有一个...

    DBA不可不知的操作系统内核参数.pdf

    在Linux系统中,尤其是一些高性能计算(HPC)或配置高端的环境,优化内核参数能确保数据库系统充分利用硬件资源并避免可能出现的问题。 1. **fs.aio-max-nr** 参数: 此参数定义了系统可以并发处理的最大异步I/O...

    MFC枚举进程内核句柄

    在Windows操作系统中,内核句柄是系统用来管理和保护资源的一种机制。内核句柄是进程间通信(IPC)和访问系统对象(如文件、进程、线程、内存区域等)的关键元素。MFC(Microsoft Foundation Classes)是微软提供的...

    演示ClientSocket反复连接进程句柄数不变

    如果不加以控制,句柄数会不断增长,直到达到系统的句柄限制,从而导致性能下降,甚至可能使整个系统崩溃,也就是所谓的“系统资源耗尽”。 为了解决这个问题,我们需要采取以下策略: 1. **异常处理**:在尝试...

    linux的最大进程句柄数设置

    在 Linux 系统中,进程句柄数设置是一个重要的参数,它决定了单个进程能够打开的最大文件句柄数量,包括 socket 连接。系统默认值为 1024,这对于一般的应用来说已经足够使用。但是,对于需要处理大量请求的应用,如...

    ZwQuerySystemInformation查找进程文件句柄

    在Windows操作系统中,开发者可以通过系统调用`ZwQuerySystemInformation`来获取系统的各种信息,其中包括查找进程中的文件句柄。这一功能对于系统监控、调试以及安全分析具有重要的实用价值。 `...

    易语言文件号和文件句柄互转模块

    易语言文件号和文件句柄互转模块源码则提供了具体实现这些功能的方法,它可以帮助开发者更好地理解和操作文件系统,特别是在进行系统级编程时。通过学习和使用这个模块,开发者可以提高其在易语言环境下的文件操作...

    【推荐】SocketTool去广告单文件版-支持TCP/UDP的Server/Client

    ★ 支持多Socket并行测试, 采用树状Socket可视化界面,所有Socket句柄一目了然 ★ 在一个程序内可进行多句柄/多类型的Socket的创建/删除/以及数据收发等操作 ★ 支持16进制的发送和16进制接收显示,支持汉字以及文本...

    linux 学习--句柄学习

    句柄的概念在很多不同的上下文中都有应用,但在这里我们主要关注它在Linux文件系统中的使用。在这个“Linux学习--句柄学习”的主题中,我们将深入探讨Linux句柄的定义、作用以及如何使用它们。 首先,理解什么是...

    易语言 取进程PID/进程句柄/进程模块句柄纯代码源码

    易语言纯代码取 进程PID 进程句柄 进程模块句柄(CE查找的进程名加偏移就相当于模块句柄加偏移)

    C++基础辅助类库,比如异步进行-Thread,安全句柄-CHandle,资源守卫-Guard,XML解析-rapidxml,以

    高级功能如文件权限管理、文件系统遍历等可能需要使用系统特定的API。 在实际开发中,理解和熟练使用这些工具和概念对于编写高效、安全的C++代码至关重要。`CPPHelper-master`可能是一个包含这些功能的开源项目,供...

Global site tag (gtag.js) - Google Analytics