优质博文:IT-BLOG-CN
灵感来源
一、什么是文件句柄
文件句柄File Handle
是操作系统中用于访问文件的一种数据结构,通常是一个整数或指针。文件句柄用于标识打开的文件,每个打开的文件都有一个唯一的文件句柄。 它们是对文件、网络套接字或其他输入/输出I/O
对象的直接引用。每当系统进程需要与这些对象进行交互时,内核都会为该进程分配一个唯一的文件句柄,以确保数据流的正确性和安全性。
文件句柄数,定义为单个进程能够同时打开和管理的文件句柄的最大数量。这一限制对于系统资源的合理分配与防止滥用至关重要。
在Linux
系统中,每个进程都有一个文件描述符表,它是一个数组,用来保存该进程打开的文件句柄。每个文件描述符都是一个非负整数,代表了对应文件句柄在文件描述符表中的索引。通常情况下,标准输入、标准输出和标准错误对应的文件描述符分别为0
、1
、2
。
文件句柄在Linux
系统中的使用非常灵活,通过文件句柄,我们可以对文件进行各种操作,如读取文件内容、写入数据到文件、关闭文件等。在编程中,开发人员可以通过系统调用来获取文件句柄,并通过文件句柄来进行文件操作。
文件句柄还可以用来进行进程间通信。比如通过管道或者套接字来传输数据。在这种情况下,文件句柄可以跨进程传递,实现进程间的数据共享。
二、阿里为什么建议修改文件句柄的值
Linux
系统默认值为1024
,也就是说,一个进程最多可以接受1024
个socket
连接。即使采用了最先进的模型,如果不进行合理的配置,也没有办法支撑百万级的网络连接并发。
在Linux
下,通过调用ulimit
命令看到单个进程能够打开的最大文件句柄数量,这个命令的具体使用方法是:
ulimit -n
用来显示和修改当前用户进程一些基础限制的命令,-n
命令选项用于引用或设置当前的文件句柄数量的限制值。对于一些用户基数很大的高并发应用,面临的并发连接数往往是十万级、百万级、千万级、甚至像腾讯QQ一样的上亿级。当单个进程打开的文件句柄数量,超过了系统配置的上限值时,就会发出Socket/File:Can't open so many files
的错误提示。对于高并发、高负载的应用,就必须要调整这个系统参数,以适应处理并发处理大量连接的应用场景。可以通过ulimit
来设置这两个参数。
ulimit -n 1000000
n
的设置值越大,可以打开的文件句柄数量就越大。建议以root
用户来执行此命令。然而,使用ulimit
命令来修改当前用户进程的一些基础限制,仅在当前用户环境有效。就是在当前的终端工具连接当前shell
期间,修改是有效的;一旦断开连接,用户退出后,它的数值就又变回系统默认的1024了
。也就是说,ulimit
只能作为临时修改,系统重启后,句柄数量又会恢复为默认值。如果想永久地把设置值保存下来,可以编辑/etc/rc.local
开机启动文件,在文件中添加如下内容:
ulimit -SHn 1000000
【1】-S
:表示软性极限值,软性极限是系统警告Warning
的极限值,超过这个极限值,内核会发出警告。普通用户可以通过ulimit
命令,将软极限更改到硬极限的最大设置值。
【2】-H
:表示硬性极限值。硬性极限是实际的限制,就是最大可以是100
万,不能再多了。root
用户权限可以更改硬极限。
终极解除Linux
系统的最大文件打开数量的限制,可以通过编辑Linux
的极限配置文件/etc/security/limits.conf
来解决,修改此文件,加入如下内容:
soft nofile 1000000
hard nofile 1000000
三、文件描述符与文件句柄的关系
在Linux
系统中,文件描述符和文件句柄是两个密切相关但概念不同的实体。文件描述符是用户空间对文件句柄的引用,它是一个非负整数,用作fdtable
(进程打开文件表)中的索引。而文件句柄则是内核空间中的实际对象,包含了文件的详细信息和状态。用户空间的操作通常通过文件描述符来间接引用和操作文件句柄。
四、文件句柄的限制层级
Linux
系统将文件句柄的限制分为三个主要层级:系统层面、用户层面和进程层面。
【1】系统级别限制: 这一限制控制整个系统可以打开的最大文件句柄数量。
▪️ 通过查看/proc/sys/fs/file-max
文件,可以获取当前的系统级别文件句柄限制。
▪️ 如果需要修改这一限制,可以使用sysctl
命令或编辑/etc/sysctl.conf
文件来实现。
【2】用户级别限制: 针对每个用户设置的最大文件句柄数量限制。
▪️ 使用ulimit -n
命令可以查看和临时修改当前shell
会话中的限制。
▪️ 为了永久修改用户级别的文件句柄限制,需要编辑/etc/security/limits.conf
文件,并添加或修改相应的nofile
限制。例如,* soft nofile 65535
和* hard nofile 65535
将分别为所有用户设置软限制和硬限制为65535
。软限制是当进程打开的文件数量达到该限制时,系统会向进程发送警告信号;而硬限制则是当进程尝试打开超过该限制的文件时,系统会拒绝该操作。
【3】进程级别限制: 每个进程都有其独立的文件句柄数量限制。
▪️ 这些限制通常与用户级别限制相关联,但也可以通过编程接口(如getrlimit
和setrlimit
)进行单独设置。
▪️ 进程的句柄数限制也可以通过/proc/[pid]/limits
目录来查看