1. 개요
프로젝트에서 급하게 오픈한 시스템에서 오랜만에 다음의 에러를 발견했다. 보통 이 에러는 해당 시스템에서 필요한 FD(File Descriptor/openfiles) 수보다
계정의 User Limit이 작게 설정되어있을 경우에 발생하게 된다. 예상컨대, 분명 openfiles 값이 디폴트인 1024로 되어 있을거라..일단 상황부터 확인해보기로!
java.io.IOException: Too many open files
at sun.nio.ch.ServerSocketChannelImpl.accept0(Native Method)
at sun.nio.ch.ServerSocketChannelImpl.accept(ServerSocketChannelImpl.java:422)
at sun.nio.ch.ServerSocketChannelImpl.accept(ServerSocketChannelImpl.java:250)
at org.apache.tomcat.util.net.NioEndpoint$Acceptor.run(NioEndpoint.java:482)
at java.lang.Thread.run(Thread.java:748)
2. 상황 확인
lsof 명령어를 이용하여 확인 FD 사용 개수 확인했다. (프로세스 ID : 3196 / 계정 User ID : 703)
$ lsof -p 3196 | wc -l (-p : pid)
$ lsof -u 703 | wc -l (-u : uid)
ps 명령어로 WAS의 스레드 생성 개수를 확인하고, netstat 명령어로 네트웍 커넥션 개수를 확인했다.
$ ps -efL | grep java | grep -v grep | wc -l
$ netstat -an | wc -l (각 상태별 커넥션 개수 확인)
위의 몇가지 명령어들로 사용중인 커넥션을 포함하여 WAS가 구동되는 계정에 총 1500개 정도의 파일이 열려 있는 것으로 확인되었다.
의심했던 것처럼 계정의 Limit이 초과된 것이 틀림 없다.
해당 계정의 User Limit 을 확인해본다. 아니나다를까 역시나 default 값을 사용중이었다. (ulimit -aH 로 Hard Limit 도 확인)
$ ulimit -aS
...
open files (-n) 1024
...
3. 조치
2에서 확인한 내용을 토대로 openfiles를 늘려주기로 했다. 보통, 계정의 user profile에 설정하기도 하고 limit.conf에 설정하기도 한다.
1) 명령어로 설정하기 (ulimit 명령어의 -n 옵션 사용)
$ ulimit -n 40960
2) 파일에 설정하기 (/etc/security/limits.conf 파일에 추가/수정)
계정명 soft nofile 40960
계정명 hard nofile 40960
늘려주고 나니 계정 재접속 후 WAS 재기동 하고 나니 Too many open files 는 안녕~~!