句柄过多导致SSH失败
现象描述
scp文件的时候,突然有一个节点拷贝失败了。以为免密被修改了,结果一问说原因是:句柄过多。
以前这种情况接触较少,就顺带查了一下资料。
句柄的定义
这个标题隐含的一个前提就是:句柄数是有一个上限的。
那什么是句柄,看看维基百科的定义:
In computer programming, a handle is an abstract reference to a resource that is used when application software references blocks of memory or objects that are managed by another system like a database or an operating system.
A resource handle can be an opaque identifier, in which case it is often an integer number (often an array index in an array or "table" that is used to manage that type of resource), or it can be a pointer that allows access to further information. Common resource handles include file descriptors, network sockets, database connections, process identifiers
(PIDs), and job IDs. PIDs and job IDs are explicitly visible integers; while file descriptors and sockets (which are often implemented as a form of file descriptor) are represented as integers, they are typically considered opaque. In traditional implementations, file descriptors are indices into a (per-process) file descriptor table, thence a (system-wide) file table.
简单说,就是 对软件使用的资源一种抽象的引用。这里的资源可以是数据库链接、进程标识、文件描述符等等。
说实话,还是有一点晦涩。
再看看通俗点的解释:
句柄其实就是和你的身份证号码。
句柄的英文是"Handle",本义就是"柄",只是在计算机科学中,被特别地翻译成"句柄",其实还是个"柄"。从一个小东西拎起一大堆东西,这难道不像是个"柄"吗?
对象就比如你对象,句柄就好比你对象的手机号码,你不必时时刻刻关心你对象在哪里干嘛,你只要有需要的时候打ta电话就能找到,连释放的时候都可以一个电话说:我们分手了。
句柄就是个数字,一般和当前系统下的整数的位数一样,比如32bit系统下就是4个字节。
这个数字是一个对象的唯一标示,和对象一一对应。
这个对象可以是一个块内存,一个资源,或者一个服务的context(如 socket,thread)等等。
阿里的同学可以理解为抓手(笑)
最早的windows开发书籍,handle是被翻译成“把手”的。虽然不好听,但是个人认为相当传神。
1.虽然你握住的只是把手,却能拉动整扇门,而且你根本不用在意那门长什么样子
2.一扇门如果有多个把手,被不同的人(进程)握住,门往哪儿走就不好说了
也就是说,这玩意本身就是抽象出来的概念,简单的理解成 把手 就好了,不同平台用的东西也不太一样。
句柄不够引起的常见错误
不够用的时候一般报错:Can’t open so many files 或者 Two many open files。会导致一些功能无法使用,比方说SSH失败、无法创建链接。
因为本质上Linux里一切皆文件,想建链接就要再开一个文件,如果句柄不够用了,那就GG了。
查看句柄数的命令
那么,句柄数是多少呢?可以通过ulimit -n来查看单个进程能打开的最大文件句柄数量
wswang@DESKTOP-HITRQF5:~$ ulimit -n
1024
系统设置的最大文件句柄数可以通过配置来看
wswang@DESKTOP-HITRQF5:~$ more /proc/sys/fs/file-max
1048576
查看当前打开的句柄数
wswang@DESKTOP-HITRQF5:~$ lsof|awk '{print $2}'|wc -l
127
找到占用句柄最多的进程
wswang@DESKTOP-HITRQF5:~$ lsof|awk '{print $2}'|sort|uniq -c|sort -nr|more
30 8
24 82
23 78
20 77
17 80
15 83
13 81
11 79
10 1
5 7
1 PID
查看占用句柄最多的进程
wswang@DESKTOP-HITRQF5:~$ ps -ef | grep 8
wswang 8 7 0 09:56 tty1 00:00:00 -bash
wswang 84 8 0 16:22 tty1 00:00:00 ps -ef
wswang 85 8 0 16:22 tty1 00:00:00 grep --color=auto 8
修改句柄相关设置
修改之前,有几个参数的含义需要注意:
1. hard nofile(/etc/security/limits.conf) 可打开的文件描述符的最大数(超过会报错)
2. soft nofile(/etc/security/limits.conf) 可打开的文件描述符的最大数(超过会警告)
3. /proc/sys/fs/file-max 系统最多可以分配的文件句柄。
4. /proc/sys/fs/nr_open 单进程的最大句柄数限制。
这就意味着有大小关系: 3>4>1>2,修改设置的时候不能破坏这个关系
修改用户相关的配置,直接在配置文件里修改即可,一般修改 /etc/security/limits.conf 就好
* soft nofile 65536
* hard nofile 65536
随后注销后重新登录,执行 ulimit -a 使参数生效就好了。
修改系统的句柄限制,通过执行”echo 100000000 > /proc/sys/fs/file-max”命令来动态修改该值;也可以通过修改”/etc/sysctl.conf”文件来永久修改该值。
参考
https://www.infoq.cn/article/pqu7imf8chpz-rnloslj
https://blog.csdn.net/fygkchina/article/details/106537736
https://segmentfault.com/q/1010000005944829
https://www.cnblogs.com/wkun/p/4254347.html
https://www.zhihu.com/question/27656256
https://stackoverflow.com/questions/1303123/what-is-a-handle-in-c
https://matianxin.github.io/2020/06/01/Linux/TooManyOpenFiles/