附上两篇值得参考的博客:
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)