Replies: 4 comments
-
|
저는 멱등성을 '같은 작업이 여러 번 실행되더라도 시스템 상태를 한 번 실행한 것과 동일하게 유지하는 설계 원칙'이라고 생각합니다. 같은 작업이 중복 실행되는 상황은 생각보다 많습니다. 이런 상황에서 중요한 것은 단순히 같은 응답을 반환하는 것이 아니라, 멱등성을 보장하는 방법은 상황에 따라 다릅니다. 이 방식은 외부 API에만 적용되는 것은 아닙니다. 그 외에도 주문 번호 같은 비즈니스 키를 기준으로 중복을 검사하거나, 재시도는 이런 멱등성이 보장된 이후에 적용해야 안전합니다. 결국 책임을 나눠보면, "요청을 받는 쪽은 멱등성을 통해 중복 실행을 흡수하고, 정리하면 멱등성은 외부 API 호출에만 필요한 기술이 아니라, 사용자 요청, 메시지 처리, 이벤트 발행, 배치와 트랜잭션 재시도까지 분산 시스템 전반에서 '한 번 더 실행돼도 안전한 시스템을 만드는 원칙'입니다. |
Beta Was this translation helpful? Give feedback.
-
멱등성같은 요청을 몇 번 반복하더라도 결과가 항상 동일하다는 성질이다.
네트워크는 언제든 끊길수가 있고, 클라이언트가 요청을 보냈는데 응답을 못 받으면 두 가지 상황의 가능성이 동시에 존재한다.
그래서 멱등성이 있다면, 1,2이든 신경 쓸 필요 없이 그냥 같은 멱등키로 재시도를 하고, 즉, 멱등성은 안심하고 재시도할 수 있는 권리를 제공해준다고 생각한다. 멱등키로 중복 식별토스의 서버 기준, 멱등 요청의 식별은 다음 조합으로 한다.
토스 블로그 기준 서버의 내부 의사 흐름
저장소가 단순 K-V이라면 Redis로, 복잡하다면 별도 DB/테이블을 권장한다고 한다. 재시도 정책과 예외 처리 구현재시도 정책
예외처리재시도를 해야하는것: 일시적이고 결과가 불확실한 상황
재시도 안해도 되는것: 영구적으로 결과가 정해진 상황
Spring에서 재시도 구현
|
Beta Was this translation helpful? Give feedback.
-
|
멱등성을 전제로 하는 재시도는 “같은 요청을 여러 번 보내도 결과가 한 번 처리된 것과 같을 때”만 적용해야 한다고 생각합니다. 특히 외부 API 호출에서는 네트워크 타임아웃, 일시적인 5xx 서버 오류, 연결 실패처럼 실제 처리 결과를 우리 서버가 확신할 수 없는 경우에 재시도가 필요하기에 멱등성을 보장해야합니다. 재시도 횟수재시도 정책은 무한 재시도가 아니라 제한적으로 가져가야 한다고 생각합니다. 예를 들어 최대 3회 정도만 재시도하고, 간격은 1초에서 2초, 2초에서 4초처럼 점진적으로 늘리는 방식이 적절할것 같습니다. 이렇게 해야 일시적인 장애는 복구할 수 있으면서도, 외부 API나 우리 서버에 과도한 부하를 주지 않을 수 있다고 생각합니다. 언제 사용할지멱등성 적용 기준은 “중복 처리되면 치명적인 작업인가?”라고 생각합니다. 결제 승인, 결제 취소, 주문 생성, 포인트 충전처럼 한 번만 실행되어야 하는 작업에는 반드시 멱등성을 고려할 필요가 있습니다. 멱등성 예외처리400, 401, 403처럼 요청 값이나 인증이 잘못된 경우는 재시도해도 성공 가능성이 낮으므로 즉시 실패 처리하는 것이 적절하고, 500번대 오류, 타임아웃, 네트워크 연결 실패는 일시적인 문제일 수 있으므로 멱등성 키가 있다는 전제하에 제한적으로 재시도할 필요가 있다고 생각합니다. 결국 멱등성은 “무조건 재시도해도 된다”는 의미가 아니라, “재시도해도 중복 부작용이 생기지 않도록 설계한다”는 의미에 더 부합한다 생각합니다. 결제 같은 도메인에서는 외부 API 호출 성공 여부와 우리 서버의 후속 처리 성패 여부가 어긋날 수 있기 때문에, 결제 승인 자체뿐 아니라 DB 저장, 주문 상태 변경, 포인트 지급 같은 내부 처리도 함께 멱등하게 설계해야 무결성이 보장됩니다. 예를 들어 orderId나 paymentKey에 unique 제약을 걸고, 이미 처리된 결제라면 에러로만 보지 않고 이미 성공한 요청으로 해석해야합니다. |
Beta Was this translation helpful? Give feedback.
-
|
멱등성을 전제로 한 재시도는 같은 요청을 다시 보내도 결과가 중복으로 발생하지 않을 때 적용해야 합니다. 주로 재시도할 수 있는 경우는 네트워크 timeout, 연결 실패, 일시적인 5xx 오류, 429, 처리 중 상태 같은 일시적 실패입니다. 찾아보니 재시도 정책은 보통 무한히 하지 않고, 최대 3회 정도로 제한하며 1초, 2초, 4초처럼 간격을 점점 늘리는 방식이 좋다고 합니다! Toss 결제 승인 API처럼 중복 처리가 위험한 경우에는 같은 결제 승인 시도에 대해 같은 |
Beta Was this translation helpful? Give feedback.

Uh oh!
There was an error while loading. Please reload this page.
-
멱등성을 전제로 하는 재시도는 언제, 어떤 기준으로 적용해야 할까요?
이번 외부 API 미션에서 Toss 결제 승인 API를 사용할 때, 멱등성 키(Idempotency-Key)로 안전하게 재시도를 보장하라는 문구가 있습니다.
위 내용 말고도 해당 내용에 대해서 자유롭게 이야기 해주셔도 됩니다.
(멱등성에 관하여 하고싶은말)
Beta Was this translation helpful? Give feedback.
All reactions