티스토리 뷰

Serializer 하나 변경하는게 이렇게 큰 결과를 불러올 줄이야... Refactoring의 일환으로 패키지를 변경했다가 Redis 관련 에러가 났고 이를 해결한 경험을 적어놓는다.

Redis Serializer

redis 는 data를 byte array 형태로 저장한다. spring data redis에서는 user - redis 사이 데이터를 변환할 수 있도록 여러 serializer들을 제공 하고 있다.(참고 사이트)

상황

팀원 중 한 명이 기존 서비스 legacy 코드가 보기가 어려워 한번 정리 하는 셈 치고 패키지들을 변경 시켰다. 나도 리뷰 할 때 '패키지 위치만 변경 한거면 intellij에서 refactoring 잘 해주겠지' 생각에 빌드 잘 되고 테스트 통과한 것만 보고 approve를 했다. 하지만 수정 사항을 배포하니 웬걸... 에러가 빵빵 터지고 rollback을 해야 했다.

어떤 문제가?

그 때 당시 파악했던 문제는

  1. Serializer 문제
  2. 배포 시퀀스 문제

였다. 각각을 살펴 보면

1. Serializer 문제

기존엔 GenericJAckson2JsonRedisSerializer를 사용하고 있었다. 그리고 이 serializer는 redis에 저장할 때 자동으로 @class 라는 필드를 삽입해 주고 deserialize 할 때 @class 필드를 참조 하여 deserialize 해준다.

이게 문제가 된 이유는 우리가 refactoring 하며 패키지를 이동 시킨 클래스가 하필 redis에서 serialize, deserialize 할 때 사용한 클래스 였고, 변경 이전 버전에서 생성된 redis item을 deserialize 할 때 ClassNotFound exception을 빵빵 터뜨렸던 것이다.

배포 시퀀스 문제

그리고 배포 시퀀스에도 문제가 있었다. 우리는 Code Deploy에서 제공하는 half&half 배포 방식을 사용 하고 있었는데, 이렇게 되면 배포 하는 중간에도 ClassNotFound Exception이 발생할 수 있었다.

이외에도 몇 가지 이유가 더 있었지만 내부 정보여서 생략하겠다.

해결

앞서 살펴본 문제점을 바탕으로 해결방법을 도출해내었다.

  1. Serializer를 GenericJAckson2JsonRedisSerializer에서 StringRedisSerializer로 변경
    • StringRedisSerializer로 변경 하여 serialize 할 때 사용한 클래스에 대한 종속성을 없앰.
  2. 2번에 거쳐 배포
    • 첫 번째 배포에는 Refactoring 하기 이전 클래스를 그대로 놔둬서 deserialize 할 때 발생할 수 있는 ClassNotFound Exception을 방지한다.
    • 두 번째 배포때 최종 변경사항이 들어간 버전을 배포 한다.

이렇게 수정하고 배포 시나리오를 짜서 정상적으로 배포를 할 수 있게 되었다.

결론

기존 소스를 건드리는 일은 굉장히 위험한 일이라는 것을 다시 한번 느낄 수 있었고, 배포하기 전 라이브 환경과 동일한 테스트 환경에서 테스트를 해봐야 겠다는 생각이 들었다.

'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