프로그래밍/devops

DB,서버 타임존 일괄 UTC 세팅 후 client에서 KST 출력

브래드 킴 2022. 12. 9. 15:40
728x90

하나의 웹서비스를 특정 지역에서 제공하기 위해서는 필수적으로 고민하게 되는 개발이슈는 local 시간에 대한 문제이다. 글로벌한 회사들은 고민의 여지 없이 DB,linux,서버프로그램의 모든 서버의 시간대를 UTC로 설정한 뒤에, 클라이언트 화면단에서 각각의 국가에 맞게 시간을 세팅하여 화면을 제공할 것이다.

 

그러나, 한국에서만 서비스를 제공하는 은행, 공공기관 같은 경우에는 경험상 서버, DB세팅을 한국시간대인 KST로 하는 경우도 적지 않았다. 사실, KST로 세팅하게 되면 DB에 저장되는 생성일, 수정일 등의 날짜와 서버로그 또한 한국시간대로 설정이 되어 보고를 위한 데이터추출 또는 로그트래킹 등 개발자들입장에서 편리한 부분이 많은것도 사실이다. 다만, UTC든 KST든 통일된 시간대로 운영체제, DB, 서버프로그램이 세팅이 되어 있어야 하는데, 어느것 하나로 통일되어 있지 않으면 시간이 뒤죽박죽 섞이는 일들이 벌어진다.

 

개인적으로 UTC로 모든 서버와 프로그램을 맞추는 설계가 좋아보인다고 생각하는 이유중 하나는, linux, mysql, docker, spring(또는 express와 같은 F/W) 등 대부분 global 서비스들의 default 세팅이 utc이므로 디폴트 세팅을 그대로 두는 편이 앞서 말한 뒤죽박죽 시간대의 발생 가능성을 원천 차단하는 것이라 생각한다. kst로 바꾸려하면, linux시간대는 kst일지라도 docker가 utc일 경우 별도로 docker파일에 kst설정을 넣어줘야 하고, 프레임워크 세팅 또한 추가적으로 해줘야 하는 번거로운 상황이 연쇄적으로 발생한다.

 

그래서 이글에서는 기존에 KST로 설정돼 있는 서버,DB 시간대를 모두 UTC로 변경하는 상황을 가정하고 그 절차에 대해서 설명해보고자 한다. 인프라 아키텍처는 aws ec2의 linux인스턴스에 docker컨테이너로 서비스를 배포하고, rds에 mysql로 db를 세팅한 가장 일반적인 springboot서버프로그램을 가정해보자. 프론트엔드는 react를 사용하여 만든 소스코드가 s3에 배포된 상황이라고 가정하자.

 

  • 리눅스

기존의 리눅스에는 아래와 같은 명령어를 통해 심볼릭이 kst로 잡혀 있었다고 가정하자.

sudo ln -sf /usr/share/zoneinfo/Asia/Seoul /etc/localtime  

기존의 심볼릭은 제거가 되지 않으므로, 아래와 같이 변경해준다.

sudo ln -sf /usr/share/zoneinfo/UTC /etc/localtime

만약 최초로 ec2로 인스턴스를 만드는 상황이라면, 그대로 두면된다. default는 utc이다.

 

  • mysql

RDS -> 데이터베이스 -> test-db에 구성탭에 가보면 파라미터 그룹란이 있다. 아마 기존에 kst로 설정이 돼 있었다면 파라미터 그룹란에 만들어진 파라미터그룹이 존재할 것이고, 아래와 같이 설정이 되어 있을것이다.

해당 설정을 UTC로 변경하자. 만약 변경이 아니라, 신규 RDS를 구축하는 상황이라고 한다면 기본값을 그대로 두자. default는 utc이다. 변경됐다면 DB에 접속하여 아래 명령쿼리를 날려보자. utc시간대로 찍힌다면 정상.

select now();

 

  • Dockerfile
#도커컨테이너 시간설정
RUN ln -sf /usr/share/zoneinfo/Asia/Seoul /etc/localtime
ENV TZ=Asia/Seoul

도커파일내에 위의 둘중에 한가지 설정이 돼 있다면, 모두 제거하도록 하자. 서버 운영체제와 별개로 docker내 alpine 리눅스내에서 서버시간대를 kst를 맞추고자 하는 부분이므로, utc로 통일하고자 한다면 제거하면된다.

 

  • springboot의 타임존 설정

1)애플리케이션 코드 내부에 @PostConstruct를 이용하는 방법

2)jar파일 실행시 Duser.timezone=Asia/Seoul  옵션을 주고 실행

 

스프링부트에서는 일반적으로 위 두가지 방법중 한가지를 통해 서버프로그램의 시간대를 설정한다. 위 코드를 모두 제거한다면 프레임워크의 타임존의 기본값이 kst가 아닌 디폴트인 utc로 설정되게 될 것이다.

 

  • 프론트엔드

UTC로의 서버설정이 모두 끝났다면, 화면단에서는 KST로의 변환이 필요하다.  먼저, javascript는 기본적으로 서버api부터 db 데이터의 날짜를 받게 되는데, return받은 날짜 데이터를 일반적으로 Date 라이브러리 함수를 사용하여 변환하여 사용한다. 해당 Date 함수내에는 utc날짜에서 local날짜로 변환하는 기능이 포함되어 있다. 그렇다면, 해당 데이터가 utc, kst, 또는 cst(중국)인지 어떻게 알수 있을까?

 

사실 mysql db안에는 데이터가 utc이든 kst이든 2022-12-09 01:59:39.192679  이런식으로 별도의 지역 구분자 없이 저장이 되어있다. 그러나, 서버에서 api요청을 처리할때 UTC의 경우에는 "2022-12-09T01:59:39.192Z" 이런식으로 +Z를 붙여 utc데이터임을 명시해서 client에 return 해주게 된다. 만약 데이터의 날짜가 KST라면 "날짜 +0900" 이런식으로 utc기준 지역별 시간대를 명시해서 return 해준다.

 

그러므로 클라이언트의 javascript 에서는 DB에 저장된 날짜가 어떤시간대로 저장되어 있는지 알수가 있게 되고, Date 라이브러리를 통해서 주어진 날짜를 사용자의 피씨환경상에서 주어지는 local타임존으로 변환하여 화면에 출력함으로서, 편리하게 utc -> kst로의 변환이 가능하게 되는 것이다.

728x90