记一次 解决PHP Linux服务器报 打开文件数过多的异常

2021-07-27更新:

-----------------------------------------------------------

今天又遇到这个异常了,前端站点打不开,抛出同样的异常错误。查看连接数,只有8465个(最大连接数设置的是40960)。为了恢复网站,暂时先重启httpd服务。

service httpd start 启动
service httpd restart 重新启动
service httpd stop 停止服务

重启后,连接数降到5001个。网上找到个统计某个进程的所有打开的文件数和明细,下次出问题时,执行这个命令查看下。

#!/bin/bash
if [ $# -eq 0 ]
  then
    echo "No PID specified"
    echo "Run command with PID, for example:"
    echo "lsof-script.sh 12345"
    exit 2
fi

JAVA_PROCESS_PID=$1

lsof -p $JAVA_PROCESS_PID > lsof-output-$JAVA_PROCESS_PID.txt

echo "Files open by the process:"
cat lsof-output-$JAVA_PROCESS_PID.txt |  wc -l

echo "Generated output file with counts of grouped open files lsof-sorted-counts-$JAVA_PROCESS_PID.txt"
cat lsof-output-$JAVA_PROCESS_PID.txt | awk '{print $9}' | sed -e "s/\(^.*\)\(segmentstore\).*$/\1\2/" |  sed -e "s/\(^.*\)\(repository[/]index\).*$/\1\2/" | sed -e "s/\(^.*\)\(felix[/]bundle\).*$/\1\2/" |  sed -e "s/\(^.*\)\([/]lib\).*$/\1\2/" |  sed -e "s/\(^.*\)\([/]logs\).*$/\1\2/" |  sed -e "s/\(^.*\)\([/]ext\).*$/\1\2/" | sort | uniq -c | sort -rn -k1 > lsof-sorted-counts-$JAVA_PROCESS_PID.txt

echo "Total open files in OS:"
lsof | wc -l
View Code

 

 

-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*

 

PHP网站突然不能访问,报错信息:

Warning: require(/var/www/html/web/common/bootstrap sys. inc. php): failed to open stream: Too many open files in /var/www/html/web/index. php on line 5

Fatal error: requireo: Failed opening required/var/www/html/web/common/bootstrap sys. inc. php (include path= /usr/share/pear: /usr/share/php )in /var/www/html/web/index php on line 5

其实这个错误和PHP本身没有关系,因为linux同时打开的文件数是有限制的。只要达到这个限制,就会导致PHP报错。因此不要盲目的去分析PHP有没有问题。

解决方法,是先去定位是哪些进程占用了文件句柄。可供使用的命令(用这些命令基本就可以定位了,定位到问题就已经解决了90%):

# 统计服务器总的文件打开数

lsof |wc -l 

# 查看打开句柄数的所有进程,排序(从多到少)
lsof -n|awk '{print $2}'|sort|uniq -c|sort -nr|more(其中第一列是打开的句柄数,第二列是进程ID)

# 根据ID号来查看进程名

ps aux|grep [pid]  或 ps aef|grep [pid]

# 查看某个进程打开的文件数

lsof |grep [pid]|wc -l

还有这种方式:lsof -p [pid]|wc -l(但这种方式统计出来的不太准确,偏少很多,原因暂不清楚)

 

我这边查出来是有个并不需要的服务,占用了1万多个句柄
强行kill掉后,降低到7800左右(之前为24000多)

 

附加:

# 查看连接外部的tcp和端口

netstat -an|grep tcp|grep 121 

 

posted @ 2021-06-21 11:41  流失的痕迹  阅读(494)  评论(0编辑  收藏  举报