회고록

2024 8월 5째 주

develua 2024. 9. 1. 14:15

결제 키가 중복해서 저장되는 원인 분석하면서 느낀점

  1. 분석과정에서 여러 방법들을 활용합니다.
    1. Loki(로그), 묶혀있던 로그 테이블, ...
  2. 요청 별 로깅의 중요성
    1. 실제로 그런 값을 받았는지, 내부적으로 그렇게 처리한 것인지 확인에 용이했음
    2. 요청 데이터와 적재된 데이터들 간의 관계를 따져보면서 이상 현상들을 확인함
      1. 결제 실패 시, 결제 재시도
      2. 마지막으로 재시도된 데이터만 관리됨.
      3. 동일 pgRequestId 로 재요청
    3. 결론: 실제로 서버로의 요청/응답 이력들이 원인을 분석하는데 도움이 많이 됐다.
  1. 그간 불필요하다고 생각했던 로그 테이블의 뜻밖의 활용
    1. socar-payment <-> socar-pg 간 연결고리가 pg_request_id 이다.
    2. socar-pg 에서 중복해서 결제 요청된 사실 발견 (다행히 중복 결제 요청해도 결제 실패할 수 밖에 없는 결제 요청들이었음 )
    3. 드러나지 않은(socar-payment.payment_transaction 에는 없는) pg_request_id 로의 시도를 socar-payment 의 로그 테이블에서 발견
    4. 새로운 연결고리의 키를 발견
  2. 결론: 모든 요청들을 관리하는 정보들은 중요하다.

 

롤링 업데이트로 배포 시, 발생한 호환성 이슈

 

그간 팀 내에선 코드 수준에서만 호환성 문제를 고민했다.

(방어 로직을 추가해서 배포 하고, 이후 방어로직 삭제한 코드 재배포하는 것으로 대응)

 

이번에 방어 로직으로도 해결할 수 없는 호환성 이슈 직면했고, 우선 에러 로그 찍히는 것 확인하고, 바로 롤백 진행됐다.
이상하게 롤백 과정에서 이전 버전의 새로 뜨는 파드도 하위 호환이 되지 않고, 롤백 시점에도 일식적으로 예외 발생하다가 정상 동작했다.

 

처음엔 팀원 모두가 방어로직 반영이 안된 부분이 있을 것으로 예상하고, 신규 인터페이스와 호환이 안되는 부분을 중점적으로 탐색했다.
이것저것 과거 데이터로 신규 로직에 테스트 코드도 돌려보고, 앱 테스트도 진행해 봤으나, 전체 결제 플로우 정상 동작했다.

 

다시, 원점으로 돌아가 Datadog 에 찍힌 에러 로그를 천천히 살펴보고 있는데, 과거 데이터가 아닌 신규 데이터를 읽는데 문제가 발생했다는 사실을 발견했다.

 

롤링 업데이트 과정에서 신규 버전 파드가 Redis 에 저장한 데이터를 구버전 파드가 읽는게 문제였다고 추측했고(구버전엔 방어 로직이 반영돼있지 않음), 실제로 2개의 파드만이 예외 발생한 것을 확인했다. 

- 배포 시, 아직 terminated 되지 않은 구버전 파드

- 롤백 시, 막 running 으로 바뀐 첫번째 구버전 파드

 

spec.minReplicas: 2

 

 

1. 어떻게 해결할 수 있을까?

  1. 배포 전략을 변경합니다. (rolling -> blue/green)
    1. 신규 버전과 구버전이 동시에 트래픽을 받지 않도록 합니다.
  2. 호환성 문제가 되는 코드 배포 이전에 방어로직을 선배포 진행합니다.

 

2. 결론: 호환성은 꼼꼼한 방어로직만으로 대응이 가능할 거라 생각했던게 오산. 방어로직이 반영되지 않은 구버전 파드와 신규 버전 파드가 동시에 요청을 처리할 때, 문제될 부분이 없는지도 고민이 필요하다

 

 

일단 머지하기 전에 리뷰 받을 때 문제없을지 고민해보자

 

정책적으로 다른 도메인과의 인터페이스 등이 확정되지 않았을 때, 큰 틀만 개발해두는 경향이 있다. 
이번에도 그렇게 개발된 뼈대를 프로젝트 릴리즈 브랜치(= 이하 베이스 브랜치)에 머지한 것이고, 개발이 완성된 상태가 아니라(= 내용이 확정된 상태가 아님) 리뷰 받기도 애매했으며, 다른 뼈대들 개발에 의존성이 있는 내용이라 머지가 되었다. 


다만, 이렇게 했을 때, 이후 살을 붙인 PR 에 나타난 변경점들은 뼈대에 대한 변경점을 모르기 때문에 팀원들에겐 낯선 내용이 된다. 
그래서 이번에도 미리 머지한 내용이 그렇게 많지는 않아 프로젝트를 같이 진행하는 팀원과 이야기 해 프로젝트 신규 베이스 브랜치를 다시 생성하기로 했다. 

 

이럴 때, 미리 머지해 두는 것보다 의존성 있는 다른 작업들을 해당 작업 브랜치에서 분기해서 작업하는 걸 먼저 고려한다.

다만, 이후 뼈대가 수정되거나 살을 붙이는 작업 시, 충돌이 날 수 있으나 참조한 내용이 수정됐다면, 수정된 내용을 기반으로 하기 내용도 수정되는게 맞지 않을까란 생각이 든다. 

 

1. 결론 

프로젝트 관련해서 일부 미확정된 부분이 머지된 상태였고, 이는 이후 팀원들에게 낯선 변경점들을 제공한다.

팀원들이 알고 있는 내용과 어떤 것들이 달라졌는지가 모두 변경점에 녹아져 있어야 팀원들도 질 좋은 리뷰도 가능하다고 생각한다. 

  1. 큰 틀에 대해선 모든 작업 이전에 먼저 합의하고, 진행하는게 이후 수정 사항을 최소화할 수 있다.
  2. 정책적으로 확정되지 않았거나 팀원들간 합의되지 않은 구조는 머지하지 않는다.