실시간으로 서버시간을 가져와 DB에 있는 데이터와 비교하여 특정 동작을 하는 Java로 만든 module 에 대해서 문제가 생겼다.
두 서버 한국표준시(KST)로 자동 timezone을 잡지만 DB에 있는 데이터와 시간비교를 할 때 조금 더 늦게 Java module이 처리되는 상황이 발생했다.
Java에서 시간 얻어오는 부분.. DB 시간 처리관련해서 오랜만에 매우 삽질을 하다가 아래와 같은 사실을 발견했다.
일단 서버 환경은 이렇다
OS: HP-UX 32bit
JAVA: JRE8
DBMS: Oracle 11g
원인파악과정:
- Java Module을 기동시에는 문제가 없으나 시간이 지난 후 점점 OS시간과 Module의 print 한 log 시간과 맞지 않는 상황이 발생
- Linux server date 확인
- DB server date 확인
- Module 시간처리 함수 (System.currentTimeMilli()) document 및 오류 이슈사항 확인
- 다시 1로 돌아서 기동시에는 동기화가 되지만 시간이 지날수록 차이가 나는 것에 대해 고민.
기동할때 처음 value initialization되는게 뭐가 있지?..
확인결과(원인):
HP-UX 장비만 해당 되는 내용이며, 서버의 System에서 System time을 가져와서 처리하지 않고, JDK 1.3 상위버전부터 JVM Hotspot에서 관리하도록 변경되었다.
gettimeofday(system call) 오버헤드를 최소화하거나 회피하기위해서 한번만 호출 후 cpu tick을 계산해서 더하는 방식으로 현재 시간을 계산하는 것이다.
그 때문에 주기적으로 OS와 동기화가 되지 않으므로 실제 OS시간과의 오차가 발생하게 된다.
The HotSpot JVM uses the gettimeofday() system call to obtain date and time information.
For performance reasons a new mechanism is used that uses the number of CPU ticks since the application started, to calculate the current time. As a result, changes to the system date or time using date(1), adjtime(2) or time synchronization utilities such as ntp will not be reflected in the date and time that the Java program returns, until the process is restarted.
If your application requires that system time changes are immediately reflected, you can use the
-XX:+UseGetTimeOfDay option to tell the JVM to use the gettimeofday call instead of the new, lightweight mechanism. However you may notice a drop in performance
해결
JVM 기동시에
-XX:+UseGetTimeOfDay
-XX:+UseHighResolutionTimer
옵션을 주어 매번 시스템 시간을 읽어오도록 변경할 수 있다.
'Linux' 카테고리의 다른 글
WSL(Windows Subsystem for Linux) Ubuntu 설정 (0) | 2020.01.29 |
---|