linux文件句柄详解

附上两篇值得参考的博客:

https://blog.csdn.net/zhengzhaoyang122/article/details/140242801

https://developer.aliyun.com/article/617809

在linux系统中,文件句柄(File Handle) 是 Linux 系统中用于标识和管理打开文件的整数索引。每个打开的文件、socket、管道等都占用一个文件句柄。

linux中一切皆文件,所以了解文件句柄是相当重要的。

一、文件句柄与文件描述符

文件句柄数,定义为单个进程能够同时打开和管理的文件句柄的最大数量。这一限制对于系统资源的合理分配与防止滥用至关重要。

在Linux系统中,每个进程都有一个文件描述符表,它是一个数组,用来保存该进程打开的文件句柄。每个文件描述符都是一个非负整数,代表了对应文件句柄在文件描述符表中的索引。通常情况下,标准输入、标准输出和标准错误对应的文件描述符分别为0、1、2。

文件句柄在Linux系统中的使用非常灵活,通过文件句柄,我们可以对文件进行各种操作,如读取文件内容、写入数据到文件、关闭文件等。在编程中,开发人员可以通过系统调用来获取文件句柄,并通过文件句柄来进行文件操作。

文件句柄还可以用来进行进程间通信。比如通过管道或者socket来传输数据。在这种情况下,文件句柄可以跨进程传递,实现进程间的数据共享。

二、文件句柄与文件描述符的关系

在Linux系统中,文件描述符和文件句柄是两个密切相关但概念不同的实体。文件描述符是用户空间对文件句柄的引用,它是一个非负整数,用作fdtable(进程打开文件表)中的索引。而文件句柄则是内核空间中的实际对象,包含了文件的详细信息和状态。用户空间的操作通常通过文件描述符来间接引用和操作文件句柄。

三、文件句柄限制层级

1.进程级限制

ulimit -n,单个进程可打开的最大句柄上限

bash 复制代码
[root@test ~]# ulimit -n
65535

2.用户级限制

/etc/security/limits.conf,单个用户可打开句柄上限

bash 复制代码
[root@test ~]# cat /etc/security/limits.conf
#对root用户生效
root soft nofile 655350
root hard nofile 655350

#对所有用户生效
* soft nofile 655350    #软限制,触发会告警
* hard nofile 655350    #硬限制,触发会禁止再生成fd

3.系统级限制

/proc/sys/fs/file-max,所有进程句柄总和上限

bash 复制代码
[root@test ~]# cat /proc/sys/fs/file-max
1755090
[root@test ~]# cat /proc/sys/fs/file-nr
1728    0       1755090    
#含义:
已分配    未释放    最大值

举个栗子

nginx的配置文件如下:

bash 复制代码
[root@test ~]# !vim
vim /opt/web_app/nginx-1.16.1/conf/nginx.conf

user  nginx;
worker_processes  2;

#error_log  logs/error.log;
#error_log  logs/error.log  notice;
#error_log  logs/error.log  info;

#pid        logs/nginx.pid;


events {
    use epoll;
    worker_connections  60000;
}

#nginx进程信息
[root@test ~]# ps -ef | grep 32202
nginx     3933 32202  0 18:01 ?        00:00:00 nginx: worker process
nginx     3934 32202  0 18:01 ?        00:00:00 nginx: worker process
root      9813 24528  0 18:10 pts/3    00:00:00 grep --color=auto 32202
root     32202     1  0 Feb28 ?        00:00:00 nginx: master process /opt/web_app/nginx-1.16.1/sbin/nginx

nginx用户有三个进程,其中master进程1个,worker进程有两个。按照进程级别的限制,那么每个进程能处理的最多的socket就是65535个,但nginx的event里面限制了60000,那就是选择最小值,这里理论上1个worker能处理60000个链接。有2个worker,所以理论上nginx用户最多能处理12万个链接。同时12万并没有超过用户级限制的655350,所以理论成立。

四、各功能消耗量

场景 文件句柄消耗
打开文件 1 个文件 = 1 个句柄
TCP 连接 1 个连接 = 2 个句柄 (收发)
数据库连接 每个连接消耗多个句柄
高并发服务 成千上万个并发连接

句柄耗尽后果

  • Too many open files 错误
  • 服务无法接受新连接
  • 数据库连接失败
  • 日志无法写入

五、实际限制因素

在配置文件句柄理论限制参数后,系统最大文件句柄数实际上是受到硬件和内存的限制的。

内存与句柄关系:每个文件句柄消耗约 1KB 内核内存

建议:句柄数 ≤ 可用内存 (GB) × 100 万

系统级限制可参考一下计算公式进行配置:

复制代码
最大句柄数 ≈ 可用内存 (GB) × 100 万 × 安全系数 (0.5-0.8)
相关推荐
IT邦德12 小时前
Dify1.6基于ubuntu系统的部署实战
linux·运维·ubuntu
非凡ghost12 小时前
分区助手:Windows 磁盘管理的“瑞士军刀“,分区调整不再怕丢数据
服务器·windows·电脑·软件需求
蓝速科技12 小时前
蓝速科技会议电子门牌规模化部署与运维成本实测
运维·科技
许彰午12 小时前
# allbytaskid——一个接口扛六个DataStore
运维·服务器·php
吠品12 小时前
Java byte数组与String互转:编码细节与踩坑记录
java·linux·服务器
牛奶咖啡1312 小时前
AI助力运维——AIGC运维应用实践—Deepseek的介绍与本地部署选型
运维·人工智能·deepseek·deepseek能做什么·deepseek本地部署配置·本地部署选型避坑原则·本地部署的典型方案
木白CPP13 小时前
Linux 驱动UART子系统源码分析
linux·运维·服务器·驱动开发·嵌入式硬件·开源软件
-今昭-13 小时前
HAProxy 负载均衡部署
运维·负载均衡
RisunJan13 小时前
Linux命令-times(进程累计时间显示)
linux·运维·chrome
xiaoxiangsiyan14 小时前
RHCE2026完整版全知识点清单
运维·网络·学习·自动化·rhce