김코딩

비동기식 결제 승인 API의 응답속도 테스트 및 분석 본문

TIL

비동기식 결제 승인 API의 응답속도 테스트 및 분석

김코딩딩 2025. 8. 6. 23:40

테스트 대상 API

@PostMapping("/payments/confirm")
public ResponseEntity<ApiResponse<PaymentConfirmResponse>> confirmAndChargePoint(
    @RequestBody PaymentConfirmRequest request,
    @AuthenticationPrincipal Auth auth) {

    long startTime = System.currentTimeMillis();
    PaymentConfirmResult paymentConfirmResult = paymentFacade.confirmAndChargePoint(
        auth.getId(),
        PaymentPresentationMapper.toPaymentConfirmCommand(request)
    );
    long duration = System.currentTimeMillis() - startTime;
    log.info("CONFIRM API 비동기 응답 시간: {}ms", duration);

    return ApiResponse.success(
        HttpStatus.OK,
        "포인트 충전이 완료되었습니다.",
        PaymentPresentationMapper.toPaymentConfirmResponse(paymentConfirmResult));
}

 

  • 비고: 기존의 동기 방식에서 비동기 방식으로 전환하였지만, 테스트 대상 API는 동일하게 유지됨.
  • 변경의 핵심은 내부 메서드 paymentFacade.confirmAndChargePoint(...) 로직이 비동기 기반으로 변경된 점에 있음.

로직 구조 변화

Before(동기식 처리)

public PaymentConfirmResult confirmAndChargePoint(Long userId, PaymentConfirmCommand command) {

    // 유저 검증
    userClient.getUserById(userId);

    Payment payment = null;
    TossConfirmResult tossConfirmResult = null;
    TossCancelResult tossCancelResult = null;

    try {
        // 토스 페이먼츠의 /payments/confirm API 호출 (결제 승인)
        tossConfirmResult = tossClient.confirmPayment(
            command.getPaymentKey(),
            command.getOrderId(),
            command.getAmount()
        );

        // 프론트에서 결제 요청한 금액과, 토스에서 실제로 결제한 금액이 일치하는지 확인
        // 일치하지 않는다면 예외를 터트려서 토스 결제 취소
        paymentService.validatePaymentAmount(tossConfirmResult.getTotalAmount(), command.getAmount());

        // 토스 결제를 완료하고, 금액 검증을 통과하였으면 토스에서 응답받은 값을 이용하여 payment 객체 생성
        payment = paymentService.createPaymentFromConfirm(userId, tossConfirmResult);

        // 포인트 충전
        pointClient.chargePoint(
            userId,
            command.getAmount(),
            "CHARGE",
            tossConfirmResult.getOrderId()
        );

        return PaymentApplicationMapper.toPaymentConfirmResult(payment);

    } catch (RestClientResponseException e) {
        ...
    }
}

 

  • 모든 과정이 순차적 동기 처리
  • 포인트 충전까지 마친 후에 응답 반환 → 상대적으로 느림
  • 결제가 완료되었지만 포인트 충전에서 예외가 발생하였을 시, 결제까지 장애가 전파된다. 

동기식의 응답속도 테스트 결과:

https://ddokyun.tistory.com/62

 

결제 승인 API의 응답속도 테스트 및 분석

테스트 대상 API@PostMapping("/payments/confirm")public ResponseEntity> confirmAndChargePoint( @RequestBody PaymentConfirmRequest request, @AuthenticationPrincipal Auth auth) { long startTime = System.currentTimeMillis(); PaymentConfirmResult paymentCo

ddokyun.tistory.com


After(비동기식 처리)

/**
     * 결제 승인 및 포인트 충전 요청 처리
     * 1. 사용자 검증 -> 2. 토스 결제 승인 -> 3. Payment 객체를 DONE 으로 변경 -> 4. 포인트 충전, 알림 이벤트 발행
     */
    public PaymentConfirmResult confirmAndChargePoint(Long userId, PaymentConfirmCommand command) {

        boolean userVerified = false;
        boolean tossPaymentSucceeded = false;
        TossConfirmResult tossConfirmResult = null;
        Payment payment;

        try {
            // 유저 검증
            userClient.getUserById(userId);
            userVerified = true;

            // 토스 페이먼츠의 /payments/confirm API 호출 (결제 승인)
            tossConfirmResult = tossClient.confirmPayment(
                command.getPaymentKey(),
                command.getOrderId(),
                command.getAmount()
            );
            tossPaymentSucceeded = true;

            // 프론트에서 요청한 결제 금액과 토스에서 실제로 결제한 금액이 일치하는지 확인
            // 일치하지 않는다면 예외를 터트린다.
            // 일치한다면, 토스에서 응답받은 값을 이용하여 payment 객체 생성
            payment = paymentService.markAsSuccess(
                tossConfirmResult,
                command.getAmount()
            );

            // 포인트 충전 및 알림 전송 이벤트 발행
            publishPaymentCompletedEvent(payment);

            return PaymentApplicationMapper.toPaymentConfirmResult(payment);

        } catch (RestClientResponseException e) {
            ...
        } catch (Exception e) {
            ...
        }
    }

 

  • 포인트 충전 부분을 Spring 이벤트를 이용한 비동기 처리로 변경
  • 결과적으로 API 응답 속도가 개선될 수 있고, 포인트에서 일어나는 장애가 결제까지 전파되는 것을 방지한다.

응답속도 테스트 방식

  • 토스 결제는 테스트 코드나 부하 테스트로 검증 불가
  • 실제 결제를 통해 직접 30회 수동 테스트 수행
  • 측정 기준: 컨트롤러 내부에서 System.currentTimeMillis()로 응답시간 계산

 

결과 분석

순번 응답시간 순번 응답시간 순번 응답시간
1 637ms 11 567ms 21 624ms
2 624ms 12 654ms 22 630ms
3 627ms 13 560ms 23 626ms
4 786ms 14 728ms 24 617ms
5 542ms 15 679ms 25 562ms
6 569ms 16 665ms 26 561ms
7 676ms 17 606ms 27 669ms
8 541ms 18 601ms 28 606ms
9 764ms 19 626ms 29 607ms
10 550ms 20 550ms 30 628ms

 

기본 통계 요약

항목 비고
총 샘플 수 30개  
평균 응답시간 621.6ms  
최소 응답시간 541ms 최고 성능
최대 응답시간 786ms 상대적으로 느린 구간
표준편차 약 70.7ms 비교적 안정적

 

응답시간 구간별 분포 요약

구간 (ms) 건수 비율
541–600 12개 40.0%
601–650 10개 33.3%
651–700 6개 20.0%
701–786 2개 6.7%