이번에 총 4건의 에러가 발생해서 급하게 롤백을 진행했던 사례(정말 다행히 대고객 영향은 없었습니다)에 대해서 말씀드리도록 하겠습니다
정말 간단하게 요약을 하면 과정은 다음과 같습니다
1. 제 서버의 Java의 Dto 클래스를 Kotlin의 data class로 변경했습니다
2. 이를 사내 nexus에 배포하였습니다
3. 이를 sdk 형태로 의존하고 있는 다른 서버를 배포했습니다
4. Jackson Deserialize Exception 이 발생해서 바로 롤백을 했습니다
제 기존 JavaClass 에는 NoArgumentConstructor 가 달려있었지만, data class로 변경한 클래스에는 noArgumentConstructor 가 없습니다
이런 상황을 해결하기 위해서 KotlinModule을 등록하면 되는데요
이 부분은 제 서버에서는 이미 등록이 되어있기에 당연히 잘 Deserialize 될 것이라고 생각하지 못했던 것이 이 문제의 원인이었습니다
해결했던 방식으로 제 서버에 요청을 보낼 때, 제 서버에 sdk에 있는 ApiCallerManager 클래스에
new ApiCallerManager("path").registerModule(new KotlinModule())
위와 같은 코드를 추가했습니다
sdk를 사용하는 다른 서버에서 위의 ApiCallerManager를 import 해서 사용하게 되면, 자동으로 KotlinModule 도 함께 추가되기에 문제없이 Deserialize가 되면서 문제가 해결되었는데요
이 과정을 겪고 나니 고민이 되는 부분이 생겼습니다.
만약 java 에서 kotlin 마이그레이션을 진행한 이후에, 패키지나 네이밍을 바꾸지 않는다면 다른 서버의 코드도 그대로 컴파일이 되지만, 실제 런타임이 되기 전까지는 절대로 찾을 수 없는 버그가 됩니다.
만약 정말 중요한 API였고 그 API 호출이 실제로는 진행되었지만 고객에게는 실패처리가 나가게 된다면, 같은 요청이 2번 수행되고, 이에 따라 보상을 해줘야 할 수도 있습니다
만약 이 부분을 무조건 테스트를 통해서 잡게 된다면 ApiCallerManager에서 요청을 하는 모든 path를 serialize 하고, 그 결과물을 다시 DeSerialize 하도록 하면 이 문제를 해결할 수 있을 것 같기는 합니다
만약 이 부분이 없다고 하면? 지금같은 문제를 결코 피할 수 없기에 테스트를 작성할 필요성이 있다는 생각이 확실히 드는 시간이었습니다
'Spring' 카테고리의 다른 글
여러분들은 동적 쿼리 어떻게 쓰시나요? (우리 팀에서Jpa Criteria 를 선택한 이유) (2) | 2023.12.24 |
---|---|
MDC 를 활용해 부가적인 정보를 남겨보자 (6) | 2023.12.03 |
테이블을 병합할 때, Auto Increment를 주의하자 (4) | 2023.10.08 |
공유 자원을 관리하는 bulk head에 대해서 알아보자 (8) | 2023.10.02 |
스프링에서 발생한 에러 로그를 슬랙으로 모니터링하는 방법 (1) | 2023.07.08 |