프로젝트 (Java)/예약마켓

[프로젝트] 46. 주문 결제 처리 API 비동기 방식 구현

hihyuk 2024. 2. 13. 10:18

AsyncConfig

@Configuration
@EnableAsync
public class AsyncConfig {

    @Bean
    public Executor taskExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(2);
        executor.setMaxPoolSize(5);
        executor.setQueueCapacity(100);
        executor.setThreadNamePrefix("OrderAsync-");
        executor.initialize();
        return executor;
    }
}
  • Spring의 @EnableAsync 어노테이션을 사용하여 비동기 처리를 활성화합니다.
  • ThreadPoolTaskExecutor를 사용하여 비동기 작업을 위한 Executor를 설정합니다. 이는 비동기 작업 실행을 위한 스레드 풀의 크기와 관련 설정을 정의합니다.

 

OrderController

    @PostMapping("/pay/{orderId}")
    public CompletableFuture<?> processOrder(@PathVariable Long orderId) {
        return orderService.processOrderAsync(orderId)
                .thenApply(orderStatus -> {
                    return Map.of("orderId", orderId, "status", orderStatus);
                })
                .exceptionally(ex -> {
                    System.out.println("Order processing failed: " + ex.getMessage());
                    return Map.of("error", "Order processing failed", "message", ex.getMessage());
                });
    }
  • @PostMapping을 사용하여 결제 처리 요청을 받는 엔드포인트를 정의합니다.
  • processOrder 메소드는 주문 ID를 기반으로 주문 처리를 비동기적으로 실행하며, 처리 결과를 CompletableFuture로 반환합니다.
  • 성공적인 처리 결과나 예외 발생 시 적절한 응답을 반환합니다.

 

OrderService

    @Async
    public CompletableFuture<OrderStatus> processOrderAsync(Long orderId) {
        try {
            Order order = findByOrderId(orderId);

            boolean paymentSuccess = Math.random() < 0.8; // 80% 확률로 결제 성공

            if (!paymentSuccess) {
                order.updateStatus(OrderStatus.FAIL);
            } else {
                order.updateStatus(OrderStatus.ORDER);
            }
            orderRepository.save(order);
            return CompletableFuture.completedFuture(order.getStatus());
        } catch (Exception ex) {
            System.out.println("Error processing order: " + ex.getMessage());
            return CompletableFuture.failedFuture(ex);
        }
    }
  • @Async 어노테이션을 사용하여 비동기 메소드로 processOrderAsync를 정의합니다. 이 메소드는 주문의 결제 처리를 시뮬레이션하며, 성공 또는 실패 상태를 업데이트합니다.
  • 결제 성공 확률을 무작위로 설정하여, 실제 결제 처리의 성공 또는 실패를 시뮬레이션합니다.
  • 주문 상태를 업데이트하고, 최종 상태를 CompletableFuture로 반환합니다.

 

결론

이 구현 방식은 비동기 처리를 통해 시스템의 응답성을 향상시키고, 리소스 사용을 최적화합니다. 특히, 대규모 트래픽이 발생하는 상황에서 시스템의 부하를 분산시키는 데 유용합니다. 또한, CompletableFuture를 사용함으로써 비동기 작업의 결과를 유연하게 처리할 수 있으며, 성공적인 처리와 예외 상황을 쉽게 관리할 수 있습니다.