ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 성능 테스트를 위해 외부와 의존성 분리하기
    Project/우아한테크캠프 - 든든킷 2024. 1. 10. 16:20
    우아한테크캠프 6기를 진행하며 최종 프로젝트에서 고생한 내용을 회고하며 정리한 문서입니다.

    프로젝트 소개

    든든킷 메인화면

     

    든든킷 우아한테크캠프 6기 마지막 최종 과제인 쇼핑몰 구축 미션을 위해 제작된 프로젝트입니다.

     

    프로젝트를 준비하는 과정에서 '이왕 하는 김에 제대로 진행해보자' 라는 욕심 가득한 마음에, `토스페이 테스트 API`를 연동해 실제 주문 및 결제 과정 개발을 경험해 보자는 의견이 통과되었고, 제가 해당 부분을 맡아 개발하게 되었습니다.

     

    교육 기간동안 TDD를 의식적으로 연습하고, 테스트의 중요성을 뼈저리게 느꼈기 때문에, 결제 기능도 꼼꼼하게 테스트하기 위해 많은 노력을 했습니다.

    성능 테스트

    nGrinder

    퍼포먼스 테스팅 툴은 nGrinder를 사용했습니다. docker를 이용해 로컬에 controller와 agent를 띄워 진행하였습니다.

    version: '3.8'
    services:
      controller:
        image: ngrinder/controller:3.5.6
        restart: always
        ports: 
          - "9000:80"
          - "16001:16001"
          - "12000-12009:12000-12009"
        volumes:
          - ./ngrinder-controller:/opt/ngrinder-controller
      agent:
        image: ngrinder/agent
        restart: always
        links:    
          - controller

    외부 API 의존성 제거

    테스트를 실행할 때 마다 토스페이 API를 호출하는 것은 좋은 생각이 아니겠죠. 결제 기능은 토스페이 API를 사용하기 때문에, 토스페이 서버에 HTTP 요청하는 부분을 제거하면서도 API를 호출할 때 발생하는 latency는 현실적으로 세팅하고 싶었습니다.

    @Override
    public Mono<Void> validatePayment(
    final String paymentKey,
    final String orderToken,
    final Money totalPrice
    ) {
    	long latancyMs = (long)((LATENCY_AVERAGE + STANDARD_DEVIATION * new Random().nextGaussian()) * 1000);
    	log.info("결제 요청 반환에 {} ms 가 수행됩니다. paymentKey: {}", latancyMs, paymentKey);
    
    	return Mono.delay(Duration.ofMillis(latancyMs))
    		.log("[mono]mono delay에 " + latancyMs + " ms가 수행되었습니다. paymentKey: " + paymentKey)
    		.then();
    }

     

    실제 환경에서 여러번 API를 호출한 결과, 평균적으로 약 1.3초의 지연시간이 발생하는 것을 확인했습니다. 그에 따라 FakePaymentClient validatePayment()메서드의 delay 시간을 평균 1.3초, 표준편차 0.2를 따르는 정규분포에 따라 지연시간을 랜덤으로 설정하도록 하였습니다.

    의존성 역전

    도메인 패키지에 있는 도메인 로직을 최대한 외부 의존성 없이 순수하게 유지하는 것이 중요했습니다. 외부와 통신하는 TossPaymentClient 클래스는 infrastructure 패키지에 두고, 인터페이스인 PaymentClient를 infrastructure패키지에 위치시켰습니다. 이제 infrastructure 패키지가 domain 패키지를 의존하게 되어 도메인을 순수하게 지킬 수 있게 되었습니다.

    production 및 develop 스테이지에 배포할 때는 TossPaymentClient 빈을 주입하여 배포하고, local profile 및 성능 테스트 시에는 FakePaymentClient를 주입하여 실행하도록 하였습니다.

    성능 테스트 결과

    성능 테스트 결과와 성능 문제를 해결한 경험은 아래 포스트에 잘 정리되어 있습니다.

     

    든든킷 결제 성능 개선기

    우아한테크캠프 6기를 진행하며 최종 프로젝트에서 고생한 내용을 회고하며 정리한 문서입니다. 프로젝트 소개 든든킷은 우아한테크캠프 6기 마지막 최종 과제로 진행한 프로젝트입니다. 프로

    baek-devlog.tistory.com

Designed by Tistory.