Linux 文件描述符

最近在复习tcp/ip知识,其中有关的一个问题 "一台服务器做多支持多少个TCP链接" 和Linux下的文件描述符有关,学习一下。

Linux中,一切设备都是文件,对文件的操作都是通过文件描述符来进行的。

文件描述符的定义:

文件描述符在形式上是一个非负整数。实际上,它是一个索引值,指向内核为每一个进程所维护的该进程打开文件的记录表。当程序打开一个现有文件或者创建一个新文件时,内核向进程返回一个文件描述符。在程序设计中,一些涉及底层的程序编写往往会围绕着文件描述符展开。

Linux中有7种文件类型:

文件类型 描述 符号
普通文件 最常使用的一类文件,其特点是不包含有文件系统信息的结构信息。这种类型的文件是按照其内部结构又可分为纯文本文件(ASCII)、二进制文件(binary)、数据格式的文件(data)、各种压缩文件。 REG (-)
目录文件 用于存放文件名以及其相关信息的文件,是内核组织文件系统的基本节点。 DIR (d)
块设备 块设备文件 : 就是存储数据以供系统存取的接口设备,简单而言就是硬盘。 BLK (b)
字符设备 字符设备文件:即串行端口的接口设备,例如键盘、鼠标等等。 CHR (c)
套接字 这类文件通常用在网络数据连接。可以启动一个程序来监听客户端的要求,客户端就可以通过套接字来进行数据通信。 SOCK(s)
管道 一种很特殊的文件,主要用于不同进程的信息传递。 FIFO (p)
链接 一种特殊文件,指向一个真实存在的文件链接,类似于Windows下的快捷方式,链接文件的不同,又可分为硬链接和软链接。 LNK (l)

最大文件描述符数量

用户级限制: ulimit -n 可以查看结果

[root@jay ~]# ulimit -n
65535

系统级限制: cat /proc/sys/fs/file-max

[root@jay ~]# cat /proc/sys/fs/file-max
363326

临时修改最大数量:

ulimit -n 20000 将最大值改为20000

  需要注意的是普通用户首次使用该命令修改最大数量后再次使用ulimit -n只能越改越小,否则报错。假设用户还没使用ulimit -n:

#第一次可以设不大于/etc/security/limits.conf的任意大小
#如果/etc/security/limits.conf没有限制该用户的大小那么第一次可以设置成任意数量
ulimit -n 2000
 
#报错 bash: ulimit: open files: cannot modify limit: Operation not permitted
ulimit -n 2000
 
#可以设为更小的
ulimit -n 1998
 
#设完更小的值之后也改不回2000了
ulimit -n 2000
#报错bash: ulimit: open files: cannot modify limit: Operation not permitted

root用户不受此限制,可以改大或改小。且root每次修改都可以比/etc/security/limits.conf里的内容大。后面内容会讲到修改/etc/security/limits.conf里的值

        此法修改大小仅对当前进程生效。重新登陆或另开进程就失效了。

永久修改文件描述符数量:

vi /etc/security/limits.conf,如果有下面两行就修改数值,没有就添加下面两行:

root hard nofile 65536
root soft nofile 65536

上述语句其实只加了root的,如果没有加用户的限制那么用户首次使用ulimit是可以打开任意数量的,可以比root的限制还要大。假定用户是user,向该文件加如下内容:

user hard nofile 2048
user soft nofile 2048

此时user首次使用ulimit修改大小就不能比2048大了。可以理解为系统自动执行一次ulimit -n 2048,因此不能比上次修改的大。 

/proc/sys/fs/file-max系统级限制:

  虽然名字叫系统级限制,但是它无法限制最大文件描述符设置的值。这个值只是系统根据内存等资源信息计算出的一个建议值。我们查看以下这个值,我这边是1603892,如果在 /etc/security/limits.conf里进行如下修改:

root hard nofile 2000000
root soft nofile 2000000

重新登陆会发现变成200万

常见误区:

综上常见误区有以下几点:

        1.虽然普通用户ulimit -n设置只能越来越小,但是root用户不受限。

        2.普通用户如果没有在limits.conf配置最大值,虽然默认是1024,但是首次使用ulimit -n可以设置任意值,即便比root配置值还大。

        3.设置完limits.conf不用重启,重新登陆该用户就行。不过重启也可以。

        4./proc/sys/fs/file-max只是一个建议值,限制不了文件描述符最大数量

回到最上面的问题

TCP四元组可以确定一个连接:

其中源地址和源端口是确定的(服务器通常固定在某个本地端口上监听,等待客户端的连接请求。)

所以连接数量的最大理论值计算公式即为:

对 IPv4,客户端的 IP 数最多为 2 的 32 次方,客户端的端口数最多为 2 的 16 次方,也就是服务端单机最大 TCP 连接数,约为 2 的 48 次方。

会受到以下因素影响:

1、本文所说的文件描述符,每个tcp连接本质上也是一个文件,如果文件描述符别占满了,会有too many open files的报错。

2、内存限制,每个tcp连接都要占用一定的内存,操作系统的内存是有限的,如果内存资源占满后,会发生OOM。

posted @ 2023-05-21 19:11  zed99  阅读(86)  评论(0编辑  收藏  举报