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)
相关推荐
Tokai_Teio_119 小时前
XYCTF 2024 web(1)
java·服务器·开发语言
樱桃花下的小猫19 小时前
僵尸毁灭工程-服务器B42测试版教程
服务器·僵尸毁灭工程·新手友好·云鸢互联·零门槛一键开服·僵尸毁灭工程b42测试
wljy119 小时前
八、Linux系统下的文件IO (二)
linux·运维·服务器
爱和冰阔落19 小时前
Linux 性能优化基石:全景拆解 PRI/NI 优先级算力争夺与 O(1) 调度算法精髓
linux·算法·性能优化
代码AC不AC19 小时前
【Linux】线程封装
linux·线程封装
艾莉丝努力练剑19 小时前
【QT】常用控件(三)Qt布局管理器(网格/表单/间隔器)
java·linux·运维·服务器·开发语言·网络·qt
小猫咪0119 小时前
Linux 日志系统入门:/var/log 和 journalctl 怎么排查问题?
linux
LT101579744419 小时前
2026年自动化性能测试平台选型:持续集成与常态化测试落地指南
运维·ci/cd·自动化
樱桃花下的小猫19 小时前
幻兽帕鲁 - 服务器管理员权限与 GM 命令完全指南
服务器·幻兽帕鲁·新手友好·云鸢互联·零门槛一键开服·幻兽帕鲁服务器·幻兽帕鲁游戏服务器管理员教程