排查Too many open files问题

 

客户那边在“新建调查”查询时,经常报错:

排查Too many open files问题_第1张图片

后台日志捞取如下:

初看,认为是文件句柄数不够,那就增大句柄数呗。

1、修改系统中的 /etc/security/limits.conf文件中

[root@zq]  vi /etc/security/limits.conf  #文件最后添加

## 系统全局性限制,*代表通配符 所有的用户
*    soft nofile 65535     # 最大文件数
*    hard nofile 65535

2、查看是否设置成功

ulimit -a                       # 用来显示当前的各种用户进程限制
# 默认值1024 

[root@zq]# ulimit -a
core file size          (blocks, -c) 0
data seg size           (kbytes, -d) unlimited
scheduling priority             (-e) 0
file size               (blocks, -f) unlimited
pending signals                 (-i) 63450
max locked memory       (kbytes, -l) 64
max memory size         (kbytes, -m) unlimited
open files                      (-n) 65535            # 文件句柄 66535
pipe size            (512 bytes, -p) 8
POSIX message queues     (bytes, -q) 819200
real-time priority              (-r) 0
stack size              (kbytes, -s) 8192
cpu time               (seconds, -t) unlimited
max user processes              (-u) 63450
virtual memory          (kbytes, -v) unlimited
file locks                      (-x) unlimited
 

open files的值是65535,说明我们设置成功了

然而,再次进行“新建调查”,还是报“too many open files”错误。

 

3、进一步分析

经过在网上多次查询,了解了关于linux系统的lsof方面的知识。

3.1、文件描述符总数file-max介绍

在 Linux 中,文件描述符是一种资源,为了控制对资源的合理使用,Linux 会限制所有进程所能打开的文件描述符总数

file-max是设置系统所有进程一共可以打开的文件数量。同时一些程序可以通过setrlimit调用,设置每个进程的限制。如果得到大量使用完文件句柄的错误信息,是应该增加这个值。

可以通过下面的命令查看:

[root@zq ~]# cat /proc/sys/fs/file-max

791542

通常来说,如果机器的内存越大,那么file-max的默认值也会越大。当然,也可以手动调大它:

[root@zq ~]# sudo vi /etc/sysctl.conf

fs.file-max = 791543

[root@zq ~]# sysctl -p          # 使修改生效                 

 [root@zq ~]# cat /proc/sys/fs/file-max

791543

那么要怎样才能知道系统当前打开了多少文件描述符呢?可以用下面的命令:

[root@zq ~]# cat /proc/sys/fs/file-nr

10720   0       791543

# 输出结果的第一个值表示系统当前打开了 704 个文件描述符,在 Linux 2.6 之后,第二个值总是 0,第三个值等于/proc/sys/fs/file-max的值

3.2、偶然间的发现

在查找内容的过程中,偶然间看到可以动态修改运行中程序的max open files值。

这时,想到是不是修改了ulimit的值,但每个进程的文件句柄数还受各自进程的控制,然后直接查询进程的句柄数open files值,发现是1024,并不是65535.

(poc)[root@zq di]# cat /proc/11282/limits
Limit                     Soft Limit           Hard Limit           Units
Max cpu time              unlimited            unlimited            seconds
Max file size             unlimited            unlimited            bytes
Max data size             unlimited            unlimited            bytes
Max stack size            8388608              unlimited            bytes
Max core file size        0                    unlimited            bytes
Max resident set          unlimited            unlimited            bytes
Max processes             771849               771849               processes
Max open files            1024                 1024                 files
Max locked memory         65536                65536                bytes
Max address space         unlimited            unlimited            bytes
Max file locks            unlimited            unlimited            locks
Max pending signals       771849               771849               signals
Max msgqueue size         819200               819200               bytes
Max nice priority         0                    0
Max realtime priority     0                    0
Max realtime timeout      unlimited            unlimited            us

使用prlimit命令手工修改了logquery进程的open file值:

(poc)[root@zq di]# prlimit --pid 11282 --nofile=65535:65535

(poc)[root@zq di]# cat /proc/11282/limits
Limit                     Soft Limit           Hard Limit           Units
Max cpu time              unlimited            unlimited            seconds
Max file size             unlimited            unlimited            bytes
Max data size             unlimited            unlimited            bytes
Max stack size            8388608              unlimited            bytes
Max core file size        0                    unlimited            bytes
Max resident set          unlimited            unlimited            bytes
Max processes             771849               771849               processes
Max open files            65535                65535                files
Max locked memory         65536                65536                bytes
Max address space         unlimited            unlimited            bytes
Max file locks            unlimited            unlimited            locks
Max pending signals       771849               771849               signals
Max msgqueue size         819200               819200               bytes
Max nice priority         0                    0
Max realtime priority     0                    0
Max realtime timeout      unlimited            unlimited            us

这种方法只是临时修改,一旦进程挂掉再被拉起,设置的值又会恢复成默认值1024.

然后,赶紧的在“新建调查”页面发起查询,没错,大概率就是这里导致的了。

 

4、修改所有进程的句柄数(open files

经过网上百度与向同事请教,得到一条重要的信息:项目是由pserver.server控制的,直接在启动服务文件里添加“LimitNOFILE=65535”即可修改所有进程的open files值。

(poc)[root@zq di]# vi /lib/systemd/system/pserver.service

[Service]
.....
#KillSignal=SIGQUIT
Restart=on-abnormal
RestartSec=30
#KillMode=control-group
TimeoutSec=0
#StandardOutput=syslog
#StandardError=inherit
PrivateTmp=yes
LimitNOFILE=65535  # 加上这行

[Install]
WantedBy=multi-user.target

运行systemctl daemon-reload让配置文件激活,再重启服务service pserver restart,即可让配置生效

然,这种方法并没有修改mysql、redis、nginx等中间件的进程的句柄数open files。可使用下面的方法修改:

 

4.1、修改nginxopen files

 [root@zq]# vi /etc/nginx/nginx.conf

user nginx;
worker_processes  4;
error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;

worker_rlimit_nofile 65535;  # nginx进程文件句柄限制,增加这行

events {
    worker_connections  1024;
}

执行nginx –s reload使其生效。

4.2mysqlopen files

MySQL打开的文件描述符限制,默认最小1024;open_files_limit没有被配置的时候,比较max_connections*5ulimit -n的值,哪个大用哪个,当open_file_limit被配置的时候,比较open_files_limitmax_connections*5的值,哪个大用哪个排查Too many open files问题_第2张图片

排查Too many open files问题_第3张图片

因为项目代码里配置了max_connection=16384,这里就不用管了。

4.3  redisopen files

查询到的两个redis实例里open files的值分别是102404096,看了项目里的代码,没分析出这俩值是怎么配置的????

排查Too many open files问题_第4张图片

 

5、测试查询

在“新建调查”页面,按照之前查询失败的条件进行多次查询,ok,没有报错。

当选择所有探针进行查询时,等了许久页面报错,logquery.log中无错误,查看nginx的日志得到:

upstream prematurely closed connection while reading response header from upstream

这种错误意思很明显,就是上游服务过早的关闭了连接。

代码中nginx配置的keepalive_timeout的值为65秒。keepalive_timeout这个配置的意思是说长连接保持的时间,如果没有任何数据传输的话,超过这个时间,服务端会关闭这个连接

所以呢,有两种方法可提供:

  1. 增大keepalive_timeout的值
  2. 优化logquery查询代码,这个工作量大

针对客户,暂使用增大keepalive_timeout的值。

 

6、附录

https://www.cnblogs.com/kcxg/p/11471320.html#_label4   Linux(CentOS 7)修改max open files的值

https://blog.csdn.net/yetugeng/article/details/88054583 Linux 系统参数调优 之 文件描述符总数file-max

https://www.cnblogs.com/hark0623/p/6094076.html       file-max与ulimit的关系与差别

https://www.cnblogs.com/coder-yoyo/p/9157148.html   Nginx" upstream prematurely closed connection while reading response header from upstream"问题排查

 

你可能感兴趣的:(linux,句柄)