티스토리 뷰
Serializer 하나 변경하는게 이렇게 큰 결과를 불러올 줄이야... Refactoring의 일환으로 패키지를 변경했다가 Redis 관련 에러가 났고 이를 해결한 경험을 적어놓는다.
Redis Serializer
redis 는 data를 byte array 형태로 저장한다. spring data redis에서는 user - redis 사이 데이터를 변환할 수 있도록 여러 serializer들을 제공 하고 있다.(참고 사이트)
상황
팀원 중 한 명이 기존 서비스 legacy 코드가 보기가 어려워 한번 정리 하는 셈 치고 패키지들을 변경 시켰다. 나도 리뷰 할 때 '패키지 위치만 변경 한거면 intellij에서 refactoring 잘 해주겠지' 생각에 빌드 잘 되고 테스트 통과한 것만 보고 approve를 했다. 하지만 수정 사항을 배포하니 웬걸... 에러가 빵빵 터지고 rollback을 해야 했다.
어떤 문제가?
그 때 당시 파악했던 문제는
- Serializer 문제
- 배포 시퀀스 문제
였다. 각각을 살펴 보면
1. Serializer 문제
기존엔 GenericJAckson2JsonRedisSerializer
를 사용하고 있었다. 그리고 이 serializer는 redis에 저장할 때 자동으로 @class
라는 필드를 삽입해 주고 deserialize 할 때 @class
필드를 참조 하여 deserialize 해준다.
이게 문제가 된 이유는 우리가 refactoring 하며 패키지를 이동 시킨 클래스가 하필 redis에서 serialize, deserialize 할 때 사용한 클래스 였고, 변경 이전 버전에서 생성된 redis item을 deserialize 할 때 ClassNotFound exception을 빵빵 터뜨렸던 것이다.
배포 시퀀스 문제
그리고 배포 시퀀스에도 문제가 있었다. 우리는 Code Deploy
에서 제공하는 half&half
배포 방식을 사용 하고 있었는데, 이렇게 되면 배포 하는 중간에도 ClassNotFound Exception
이 발생할 수 있었다.
이외에도 몇 가지 이유가 더 있었지만 내부 정보여서 생략하겠다.
해결
앞서 살펴본 문제점을 바탕으로 해결방법을 도출해내었다.
- Serializer를
GenericJAckson2JsonRedisSerializer
에서StringRedisSerializer
로 변경StringRedisSerializer
로 변경 하여 serialize 할 때 사용한 클래스에 대한 종속성을 없앰.
- 2번에 거쳐 배포
- 첫 번째 배포에는 Refactoring 하기 이전 클래스를 그대로 놔둬서 deserialize 할 때 발생할 수 있는
ClassNotFound Exception
을 방지한다. - 두 번째 배포때 최종 변경사항이 들어간 버전을 배포 한다.
- 첫 번째 배포에는 Refactoring 하기 이전 클래스를 그대로 놔둬서 deserialize 할 때 발생할 수 있는
이렇게 수정하고 배포 시나리오를 짜서 정상적으로 배포를 할 수 있게 되었다.
결론
기존 소스를 건드리는 일은 굉장히 위험한 일이라는 것을 다시 한번 느낄 수 있었고, 배포하기 전 라이브 환경과 동일한 테스트 환경에서 테스트를 해봐야 겠다는 생각이 들었다.
'experiences' 카테고리의 다른 글
도메인 사이 의존성 줄이기 (0) | 2021.12.21 |
---|---|
ObjectMapper에 관하여 (0) | 2021.12.21 |
Kill과 trap (0) | 2021.12.21 |
Autowired와 AOP를 함께 사용할 때 주의 해야 할 점 (0) | 2021.12.21 |
Deadlock 현상 해결 (0) | 2021.12.21 |
- Total
- Today
- Yesterday