客户那边在“新建调查”查询时,经常报错:
后台日志捞取如下:
初看,认为是文件句柄数不够,那就增大句柄数呗。
[root@zq] vi /etc/security/limits.conf #文件最后添加
## 系统全局性限制,*代表通配符 所有的用户
* soft nofile 65535 # 最大文件数
* hard nofile 65535
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”错误。
经过在网上多次查询,了解了关于linux系统的lsof方面的知识。
在 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的值。
在查找内容的过程中,偶然间看到可以动态修改运行中程序的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.
然后,赶紧的在“新建调查”页面发起查询,没错,大概率就是这里导致的了。
经过网上百度与向同事请教,得到一条重要的信息:项目是由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。可使用下面的方法修改:
[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使其生效。
MySQL打开的文件描述符限制,默认最小1024;当open_files_limit没有被配置的时候,比较max_connections*5和ulimit -n的值,哪个大用哪个,当open_file_limit被配置的时候,比较open_files_limit和max_connections*5的值,哪个大用哪个
因为项目代码里配置了max_connection=16384,这里就不用管了。
查询到的两个redis实例里open files的值分别是10240与4096,看了项目里的代码,没分析出这俩值是怎么配置的????
在“新建调查”页面,按照之前查询失败的条件进行多次查询,ok,没有报错。
当选择所有探针进行查询时,等了许久页面报错,logquery.log中无错误,查看nginx的日志得到:
upstream prematurely closed connection while reading response header from upstream。
这种错误意思很明显,就是上游服务过早的关闭了连接。
代码中nginx配置的keepalive_timeout的值为65秒。keepalive_timeout这个配置的意思是说长连接保持的时间,如果没有任何数据传输的话,超过这个时间,服务端会关闭这个连接。
所以呢,有两种方法可提供:
针对客户,暂使用增大keepalive_timeout的值。
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"问题排查