저장을 습관화
에러 기록 - DB에 createdAt이 9시간 전으로 저장되는 현상 본문
- 증상
NestJS + TypeORM + Socket.io로 사용자 간의 채팅 기능 작성 중
서로의 채팅 입력 시간이 9시간 전으로 표시되는 문제 발생
/src/channel.service.ts (입력 내용을 DB에 먼저 저장하고, socket.io를 이용하여 같은 채널 사람들에게 전송함)
// ...
// 채팅 작성
async postChat({ url, name, content, myId }) {
// 채널 조회
const channel = await this.channelsRepository
.createQueryBuilder('channel') // 'alias'
.innerJoin('channel.Workspace', 'workspace', 'workspace.url = :url', {
url: url,
}) // 'property', 'alias', 'condition', 'parameters'
.where('channel.name = :name', { name: name }) // 'where', 'parameters
.getOne();
if (!channel) {
throw new NotFoundException('채널이 존재하지 않습니다.');
}
const chats = new ChannelChats();
chats.content = content;
chats.UserId = myId;
chats.ChannelId = channel.id;
const savedChat = await this.channelChatsRepository.save(chats);
const chatWithUser = await this.channelChatsRepository.findOne({
where: { id: savedChat.id },
relations: ['User', 'Channel'],
});
// socket.io로 워크스페이스/채널 사용자에게 전송
this.eventsGateway.server
.to(`/ws-${url}-${channel.id}`)
// `워크스페이스-워크스페이스 이름-채널ID`
.emit('message', chatWithUser);
}
// ...
/src/entities/ChannelChats.ts
@CreateDataColumn() 데코레이터와 기본 옵션 Date 사용 중
// ...
// ...
export class ChannelChats {
// ...
@CreateDateColumn()
createdAt: Date;
@UpdateDateColumn()
updatedAt: Date;
// ...
}
이러한 환경에서
DB에 createdAt이 9시간 전으로 저장되고 있는 중
DB는 AWS RDS를 이용 MySQL를 사용중임
지역은 ap-northeast-2a(아시아 태평양, 서울)
- 원인
백엔드(NestJS) 서버와 DB 서버 각각의 타임존이 잘못되어있는 것이라고 생각됨..
- 해결을 위한 시도
NestJS 실행 중인 서버의 시간과 타임존
// 2023년 11월 18일 오후 4시 34분 기준
console.log(new Date());
// 2023-11-18T07:34:51.817Z
console.log(Date());
// Sat Nov 18 2023 16:34:51 GMT+0900 (대한민국 표준시)
console.log(Intl.DateTimeFormat().resolvedOptions().timeZone);
// Asia/Seoul
DB의 타임존
'DB는 NestJS가 TypeORM 이용해서 전송하는 데이터를 저장만 할테니,
DB의 타임존이나 시간 설정은 불필요하지 않을까?'라고 생각함
검색해보니 옵션을 넣어주는 것으로 NestJS의 타임존을 설정할 수 있다는 내용을 발견
app.module.ts에 아래와 같이 timzone 옵션을 넣어줌
TypeOrmModule.forRoot({
timezone: 'Asia/Seoul',
}),
이후 브라우저에서는 서로의 채팅 입력 시간이 정상적으로 확인되나
DB에서는 여전히 9시간 전으로 저장되는것을 확인
AWS RDS의 타임존을 Asia/Seoul로 변경함
그에 대한 기록
AWS RDS MySQL DB Timezone 변경
AWS RDS를 이용하여 생성한 MySQL DB의 기본 타임존은 UTC로, `select now()`를 입력해서 시간을 확인하였을때 실제 현지 시간보다 9시간 느림 이것을 수정하기 위하여 타임존을 변경하는 방법에 대한 메
ctrs.tistory.com
DB 타임존 변경 이후 다시 채팅 테스트를 진행하였고
DB에는 제대로 된 시간이 저장되었으나
브라우저에서는 서로 상대방의 채팅 내역이 9시간 빠르게 표시되는 것을 확인함..
다시 app.module.ts의 TypeOrmModule의 timezone 옵션을 제거하고 NestJS를 재실행
TypeOrmModule.forRoot({
// timezone: 'Asia/Seoul',
}),
브라우저와 DB 모두 정상적으로 시간이 나오는 것을 확인함