java.net.SocketException: Too many open files 에 대한 대처

2008. 4. 2. 14:31리눅스



이전 보안회사에 재직할 때, 개발한 솔루션-서버-을 행정기관에 납품한 경우가 있었다.
이 행정기관은 내부 관리 서비스와 함께 대민 서비스가 주요한 서비스이기도 했다.
서비스를 오픈하고 시간이 흐르자 장애가 발생했었다.
세션을 유지하고 클릭하는, 서비스 요청하는 동시 접속자가 일시적을 증가하는 경우에 다음과 같은 에러가 발생하곤 했었다.

java.net.SocketException: Too many open files
         at java.net.PlainSocketImpl.socketAccept(Native Method)
         at java.net.PlainSocketImpl.socketAccept(Compiled Code)
         at java.net.PlainSocketImpl.accept(Compiled Code)
         at java.net.ServerSocket.implAccept(Compiled Code)
         at java.net.ServerSocket.accept(Compiled Code)
         at org.apache.tomcat.service.PoolTcpEndpoint.acceptSocket(Compiled Code)
         at org.apache.tomcat.service.TcpWorkerThread.run(Compiled Code)
         at org.apache.tomcat.util.ThreadPool$ControlRunnable.run(Compiled Code)
         at java.lang.Thread.run(Compiled Code)

솔 루션 자체의 내부 기능을 보아 파일 I/O 쪽 액세스에 무리가 없다고 판단하고 있어서인지 이래저래 고심을 했었는데, 이 액세스 가능여부에 socket 부분까지 포함된다는-로그에도 이미 있지만- 사실에 그 순간은 "이런! 경우가 다 있나~" 하고 무릎을 치면서, 보는 그대로를 믿지 않는 자신을 탓하기도 했었다.

솔루션이 생성된 특정 계정으로 프로세스가 구동될 경우, O/S 설정값에 영향을 받는다는 것도 그때 처음 접했던 것 같다.

당시, 솔루션이 설치된 O/S는, HP-UX 11.xxi 64bit itanium 시리즈였던 것으로 기억된다.(itanuim 64bit 프로세스에 기반한 시스템에서 장애를 지금도 많이 겪는다. ㅡ,.ㅡa)

[grim@www /]$ ulimit -a
core file size (blocks)  0
data seg size (kbytes)   unlimited
file size (blocks)       unlimited
max memory size (kbytes) unlimited
stack size (kbytes)      8192
cpu time (seconds)       unlimited
max user processes       2048
pipe size (512 bytes)    8
open files               1024
virtual memory (kbytes)  2105343

로그인 쉘에서 위와 같이 입력할 경우, 해당 결과를 보면 open files 항목이 보일텐데, 다중 접속자를 감안 시스템 솔루션을 개발하는데에는 이 부분의 기본값이 솔루션 기능의 lock 역할을 할 수도 있다.

이때는, 권한이 있는 사용자 쉘에서

[grim@www /]$ ulimit -n 2048

처럼 입력하여 여유를 주면 되겠다.

========================================================================================

제  목 : Too many open files 에러발생시
작성자 : 좋은진호(truefeel, http://coffeenix.net/ )
작성일 : 2006.7.10(월)

자바에서 다음과 같은 에러가 발생했다면 FD(File Descriptor)를 늘려줘야 한다.

 
java.net.SocketException: Too many open files
        at java.net.PlainSocketImpl.socketAccept(Native Method)
        at java.net.PlainSocketImpl.accept(PlainSocketImpl.java:353)
        at java.net.ServerSocket.implAccept(ServerSocket.java:448)
        at java.net.ServerSocket.accept(ServerSocket.java:419)
... 생략 ...
 


1. open files 최대 개수 확인

먼저 ulimit -a 으로 open files 개수를 확인한다. ulimit -aH는 hard limit, -aS는 sort limit를 확인.
csh 쉘을 사용하면 limit 명령으로 살펴볼 수 있다.

 
$ ulimit -a
core file size          (blocks, -c) 0
data seg size           (kbytes, -d) unlimited
file size               (blocks, -f) unlimited
pending signals                 (-i) 1024
max locked memory       (kbytes, -l) 32
max memory size         (kbytes, -m) unlimited
open files                      (-n) 1024
pipe size            (512 bytes, -p) 8
POSIX message queues     (bytes, -q) 819200
stack size              (kbytes, -s) 10240
cpu time               (seconds, -t) unlimited
max user processes              (-u) 69632
virtual memory          (kbytes, -v) unlimited
file locks                      (-x) unlimited
 


2. 프로세스별로 오픈된 파일 개수 확인

열린 파일

lsof 명령으로 확인할 수 있다. 지정한 프로세스가 몇개의 파일을 사용중인지를 확인할 때는 다음처럼 실행
하면 알 수 있다.

lsof -p PID | wc -l

1234, 1236 PID 2개에 대해 살펴본다면 콤마(,)로 PID를 구분해서 적어주면 된다.

 
$ lsof -p 1234,1236 |wc -l
 


3. 파일개수 늘리기

리눅스환경을 기준으로 설명한다. truefeel 사용자의 open files개수를 4096(sort limit),
6144(hard limit) 로 제한한다면 /etc/security/limits.conf에 다음 줄을 추가해주면 로긴시 적용된다.

 
truefeel         soft    nofile          4096
truefeel         hard    nofile          6144
 


4. 참고 자료

* Too Many Open Files Exception
  http://kr.bea.com/files/services/customer_support/best_tip/06_200406/06_2_14.pdf

* Too many open files
  http://kr.bea.com/services/customer_support/SupportPattern/08_15_Too_Many_Open_Files_Pattern.html
# by 변익수 | 2006-08-29 13:38 | Error Message | 트랙백 | 덧글(0)