본문 바로가기
FullStack/40. Linux

Too many open files 오류

by nakanara 2023. 5. 4.
반응형

 

 

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 /

 

반응형