tomcat 구동 시 /dev/random 블로킹 이슈

서버|2016. 8. 25. 16:30

[현상]

새로 지급 받은 리눅스 신규 장비에 java, tomcat 환경 구성을 하고 tomcat 구동 시 대기 상태로 빠지는 현상이 있었다. 특이한 점은 몇 분 지나면 tomcat 구동이 완료되는 경우와 몇 십 분이 지나도 서버 구동이 완료되지 않는 경우가 있다라는 것이다.


지연 현상이 발생되면서 다음과 같은 로그가 남았고, 해당 로그를 통해서 그 원인 및 해결 방법을 찾아보왔다.

[2016-08-23 18:10:36 INFO  o.s.w.c.ContextLoader][313] - Root WebApplicationContext: initialization completed in 2785 ms

8월 23, 2016 6:11:14 오후 org.apache.catalina.util.SessionIdGenerator createSecureRandom

INFO: Creation of SecureRandom instance for session ID generation using [SHA1PRNG] took [38,251] milliseconds.



[해결방법]

해결 방법은 생각보다 쉽게 찾을 수 있었다. 다음의 java 옵션을 추가해 주면 tomcat 구동 시 더이상의 대기 상태는 발생하지 않았다.

JAVA_OPTS="$JAVA_OPTS -Djava.security.egd=file:/dev/./urandom"



[원인]

해결 방법을 찾긴 했는데 왜 위의 옵션을 추가하면 지연 없이 톰켓이 구동되는지 찾아보았다.


리눅스 서버는 난수를 생성하기 위해서 기본적으로 /dev/random 디바이스를 사용한다.

 - 리눅스의 /dev 디렉토리는 시스템 디바이스 파일을 저장하고 있는 디렉토리이다.

   > 하드디스크는 /dev/sda

   > 씨디롬은 /dev/cdrom


/dev/random은 랜덤 비트의 풀이며 Entropy pool 이라고 부른다.

사용자 입력 신호(키보드, disk I/O, 마우스 click등)가 Entropy pool에 비트의 형태로 저장이 되고  난수를 생성할 때 Entropy pool에 default size만큼의 bit가 충분하지 않다면 /dev/random은 블로킹 된다.


여기서 /dev/random 이야기를 하는 이유는 자바에서 SecureRandom 클래스가 session ID를 생성할 때 /dev/random을 사용하기 때문이다. (위의 로그에 기록되어 있는 것 처럼 Creation of SecureRandom instance for session ID generation using [SHA1PRNG] 을 보면 알 수 있다.)


문제의 원인이 /dev/random 블로킹 상태로 빠지는 경우이기에 대체적으로 블로킹 되지 않는 /dev/urandom을 사용하도록 솔루션을 제공하고 있다.


여기서 한번 짚고 넘어가야 할 것은 왜 우리가 추가한 설정이 /dev/urandom이 아닌 /dev/./urandom 일까? 이것은 Java Bug 6202721 로 인한 영향도로 확인했다.

Java 5 또는 그 이후 버전에서는 /dev/./urandom 설정으로 추가해야 한다. 만약 /dev/urandom을 추가하게 되면 /dev/random으로 인식하게 되어 또 다시 블로킹 이슈가 발생할 수 있다.

Footnote: In the above examples, you need the crazy-looking filename, e.g., the extra /./, to trick Java into accepting your filename. If you just use /dev/urandom, Java decides you didn't really mean it and replaces what you wrote with /dev/random. Craziness!



[결론]

현재 /dev/random을 사용하고 있는 테스트, 라이브 장비에서는 블로킹 문제가 발생되고 있지 않은 상황이다.

이는 빈번한 I/O가 발생됨으로써 Entropy pool에 비트가 충분히 채워지고 있기 때문인 것으로 확인된다.

정상적으로 잘 동작하고 있는 환경의 톰켓에 굳이 urandom으로 설정을 바꿀 필요는 없을 것으로 보이며 위와 같은 블로킹 이슈가 발생되는 환경(개발망)에 대해서만 옵션을 추가하여 문제를 해결하는 것이 좋을 것 같다.


추가적으로 글을 쓰기 위해 이것 저것 조사하다 보니 rngd 데몬 프로그램을 이용해서 /dev/random의 블로킹 이슈를 해결하는 방법도 알게 되었다.

 - rngd 데몬 프로그램은 /dev/random 디바이스에 신호를 지속적으로 전송해서 블로킹 문제를 해소한다.

'서버' 카테고리의 다른 글

Kubernetes 설치  (6) 2017.01.12
Docker 정리  (2) 2017.01.04
리눅스 컨테이너 (LXC)  (0) 2017.01.04
MQTT (mosquitto broker 오픈소스)  (0) 2016.11.02
Nginx  (0) 2016.07.15
Apache worker 파일에 template 적용하기  (0) 2016.01.22
tomcat7 소스 빌드  (0) 2015.09.07
Tomcat Parallel deployment  (0) 2015.09.02

댓글()