||
글. 심수현(Dante) / 전시개발팀
안녕하세요.
전시개발팀에서 여기어때 서비스를 개발하고 있는 단테입니다.
저희 팀은 레거시 API와 신규 API의 응답이 같은지 비교하기 위해 쉐도잉이라는 방법을 사용합니다.
쉐도잉(Shadowing)이란?
실제 요청을 신규 로직에도 보내 기존 로직과 결과를 비교하는 방식입니다. 사용자에게는 기존 로직의 결과를 전달하고 신규 로직의 결과는 검증에 사용합니다. 두 응답이 일치하지 않는다면 신규 로직에 잘못된 비즈니스 로직이 적용되었다고 판단할 수 있습니다.
쉐도잉을 처음 도입한 이야기는 이전에 주드가 작성한 전시 API 서비스 전환기 Part 2에 있으니 이 글을 읽기 전에 먼저 보셔도 좋을 것 같습니다.
저희는 클라이언트가 쓰는 API를 주로 만들지만 사용자 눈에는 보이지 않는 내부 개선 작업도 꽤 자주 합니다.
내부 구조 개선, 성능 개선, 리팩토링, 그리고 우리가 호출하는 외부 API의 동작이 바뀌어서 맞춰야 하는 작업까지요.
이런 작업은 겉으로 보면 달라진 게 없어야 정상입니다. 그래서 오히려 검증이 어렵습니다.
기능이 새로 생긴 게 아니니 QA를 요청하기도 애매하고 그렇다고 이런 작업이 있을 때마다 QA 일정을 잡을 수도 없었습니다.
결국 개발자가 직접 검증하고 배포하는 일이 반복됐습니다.
오늘은 그 검증을 어떻게 해왔고 무엇이 불편했고 지금은 어떻게 바꿨는지 이야기해 보겠습니다.
이번에 검증해야 했던 변경
최근에 가장 크게 검증이 필요했던 작업부터 소개하겠습니다.
전시 영역의 제휴점 상품 정보는 원래 원천 데이터에서 Kafka로 변경분을 받아 전시 쪽 MongoDB에 저장해 두고 읽는 구조였습니다.
오랫동안 잘 돌아간 구조였지만 다루는 상품이 늘어나면서 확장성에 대한 고민이 생겼고 증분이 전시 저장소까지 반영되는 사이의 지연 때문에 실시간성 이슈도 생겼습니다.
그래서 MongoDB를 거치지 않고 원천 데이터에서 제공하는 API를 직접 호출하도록 바꾸기로 했습니다.
말은 간단하지만 제휴점 리스트(PLP), 숙소 상세(PDP), 객실 리스트(ILP), 객실 상세(RDP), 달력 요금 처럼 가격과 재고를 보여주는 화면의 데이터 출처가 통째로 바뀌는 작업입니다.
사용자나 제휴점 고객 입장에서는 가격 변동이 없다면 어제 보던 가격과 오늘 보는 가격이 같아야 하는데 이걸 무엇으로 확인할지가 문제였습니다.
내부 테스트만으로는 부족했습니다
저희가 다루는 응답은 숙소, 객실, 날짜, 인원, 회원 등급, 할인이 얽혀 있어서 테스트 케이스로 만들 수 있는 조합이 실제 요청의 극히 일부에 불과했습니다.
테스트는 통과하는데 운영에서 어떤 숙소의 어떤 날짜에서만 가격이 다르게 나오는 식의 문제는 테스트로 잡히지 않았습니다.
그래서 이런 작업에도 쉐도잉을 씁니다.
방법은 단순합니다.
실제 요청이 들어오면 사용자에게는 기존 로직의 결과를 그대로 내려주고 내부의 별도 스레드에서 개선한 로직을 한 번 더 호출한 뒤 두 결과를 비교하는 방식입니다.
비교 대상은 경우에 따라 달랐습니다.
API 응답 전체를 비교할 때도 있었고 응답을 만들기 전 단계의 중간 객체를 비교할 때도 있었습니다.
어느 쪽이든 운영 트래픽을 그대로 테스트 데이터로 쓸 수 있다는 점이 가장 큰 장점이었습니다.
그런데 비교 결과를 읽는 건 사람이었습니다
비교 자체는 코드가 했습니다. 문제는 그다음입니다.
비교 결과는 로그로 남겼는데 예를 들어 PDP API를 V2에서 V3로(성능개선) 새로 만들 때 쓰던 쉐도잉 로그는 이런 모양이었습니다.
SHADOW_DIFF request placeId=100001, checkInOut=(2026-09-10, 2026-09-11), person=2, userId=null, membership=ELITE, hardBlock=null, platform=APP, channel=yeogi, display=10, channeling=false, channelCode=null
field=pdp.roomInfoList[roomId=20011] v2Value=pre


