FullStack/40. Linux

Too many open files 오류

nakanara 2023. 5. 4. 09:00
반응형

 

 

Too many open files 오류

다른 Linux 서버에서 발생하지 않았던 Too many open files 문제가 발생했다. 특정 실행 파일에서 발생하였으면 분석하기가 좋을 텐데, 결과는 동일한데 발생했던 발생 포인트가 달랐다.

  • 발생 1) Tomcat 2대를 TCP 클러스터링 관련한 곳에서 발생
13-Mar-2023 08:13:10.721 SEVERE [GroupChannel-Heartbeat[Catalina-Channel]-1] org.apache.catalina.tribes.group.interceptors.TcpFailureDetector.memberAlive Unable to perform failure detection check, assuming member down.[org.apache.catalina.tribes.membership.StaticMember[tcp://10.10.10.1:4055,10.10.10.1,4055, alive=0, securePort=-1, UDP Port=-1, id={0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 }, payload={}, command={}, domain={}]]
    java.net.SocketException: Too many open files
        at java.net.Socket.createImpl(Socket.java:478)
  • 발생 2) Jar 파일 읽지 못하는 오류
24-Apr-2023 09:11:52.060 SEVERE [ajp-nio-0.0.0.0-8009-exec-9] org.apache.catalina.core.StandardWrapperValve.invoke Servlet.service() for servlet [jsp] in context with path [] threw exception [org.apache.jasper.JasperException: Unable to compile class for JSP] with root cause
    java.io.FileNotFoundException: /app/webapp/app/WEB-INF/lib/jaxb-runtime-2.3.4.jar (Too many open files)
        at java.util.zip.ZipFile.open(Native Method)
        at java.util.zip.ZipFile.<init>(ZipFile.java:225)
        at java.util.zip.ZipFile.<init>(ZipFile.java:155)

"Too many open files"는 프로세스가 OS에 요청할 수 있는 리소스의 수가 설정되어 있고, 오류는 그 제한을 넘었기 때문에 발생한다.

문제는 왜 발생했냐는 것이 문제이다.
접속 수가 많아서는 아닐 것 같은데 프로그램상 누수가 생기는 것 같은데 확인이 필요할 것 같다.

우선 리소스 요청 수를 늘리는 작업을 진행했다.

리소스는 기본적으로 Hard: 1024, Soft: 4096으로 설정되어 있다.

  • Soft Limit: non-root에서 계정에서 설정가능하며, 일시적으로 넘어도 경고 알림이 있을 뿐 문제없음
  • Hard Limit: root계정에서 설정가능하며 실제 제한 값
$ ulimit -Hn
4096
$ ulimit -Sn
1024

"Too many open files"가 발생한 것은 결국 Hard Limit를 초과했다고 볼 수 있다.
관련 설정은 root 계정으로 /etc/security/limits.conf 파일에서 확인이 가능하다.

기본적으로는 별 설정값은 없다.

$ cat /etc/security/limits.conf

#*               soft    core            0
#*               hard    rss             10000
#@student        hard    nproc           20
#@faculty        soft    nproc           20
#@faculty        hard    nproc           50
#ftp             hard    nproc           0
#@student        -       maxlogins       4
root hard nofile 500000 # 추가
root soft nofile 500000 # 추가
  • 설정 시 주의

Soft, Hard limit 값은 System 전체의 Limit보다 작아야 한다.

  • System Limit 확인 방법
$ cat /proc/sys/fs/file-max
790392

설정 후 재 로그인을 하면 설정된 값을 확인할 수 있으며, 이미 시작된 프로세스는 다시 시작을 해야지 적용이 된다.
만약 재실행이 어려운 환경이라면 다음의 방법으로 설정이 가능하다.

# 프로세스 PID 확인
$ ps -ef | grep tomcat 
user     1000  2805  0 Apr25 pts/0    00:18:37 /usr/local/openjdk-8/bin/java -Dignore.endorsed.dirs= -classpath /usr/local/tomcat/bin/bootstrap.jar:/usr/local/tomcat/bin/tomcat-juli.jar -Dcatalina.base=/usr/local/tomcat -Dcatalina.home=/usr/local/tomcat -Djava.io.tmpdir=/usr/local/tomcat/temp org.apache.catalina.startup.Bootstrap start

# LIMIT 확인
$ prlimit --nofile --output RESOURCE,SOFT,HARD -- pid 1000
RESOURCE SOFT HARD
NOFILE   1024 4096
  • 과거 값으로 설정된 경우 설정 값을 수동으로 변경한다.
$ prlimit --nofile=500000 --pid=1000

필요한 경우 값에 대한 설정이 맞지만 다른 서비스에서 발생하지 않는 것으로 판단했을 때는 관련 소스에 문제가 있는 것 같다.

  • 프로세스의 관련 리소스 확인 방법
# PID를 이용한 확인 방법
$ lsof -p 1000
COMMAND  PID  USER   FD      TYPE             DEVICE SIZE/OFF      NODE NAME
java    1000 user  cwd       DIR               0,49       64  17934682 /usr/local/tomcat
java    1000 user  rtd       DIR               0,49      103  50950420 /
java    1000 user  txt       REG               0,49     8822   2424981 /usr/local/openjdk-8/bin/java

# UID를 이용한 확인 방법
$ lsof -u user
COMMAND     PID  USER   FD      TYPE             DEVICE   SIZE/OFF      NODE NAME
mysqld     2462 user  cwd       DIR             202,16       4096    529799 /var/lib/mysql
mysqld     2462 user  rtd       DIR               0,39         52  19263216 /

 

반응형