스프링 부트(핵심 원리와 활용)

Ch09. 모니터링 메트릭 활용 - 메트릭 등록(예제 만들기)

webmaster 2023. 5. 9. 00:27
728x90

앞서 보았듯이 CPU 사용량, 메모리 사용량, 톰캣 스레드, DB 커넥션 풀과 같이 공통으로 사용되는 기술 메트릭은 이미 등록되어 있다. 우리는 이런 이미 등록된 메트릭을 사용해서 대시보드를 구성하고 모니터링하면 된다.
여기서 더 나아가서 비즈니스에 특화된 부분을 모니터링 하고 싶으면 어떻게 해야 할까? 예를 들어서 주문수, 취소수, 재고 수량 같은 메트릭들이 있다. 이 부분은 공통으로 만들 수 있는 부분은 아니고, 각각의 비즈니스에 특화된 부분들이다.
이런 메트릭들도 시스템을 운영하는데 상당히 도움이 된다. 예를 들어서 취소수가 갑자기 급증하거나 재고 수량이 임계치 이상으로 쌓이는 부분들은 기술적인 메트릭으로 확인할 수 없는 우리 시스템의 비즈니스 문제를 빠르게 파악하는데 도움을 준다.
예를 들어서 택배회사에 문제가 생겨서 고객들이 많이 기다리다가 지쳐서 취소수가 증가해도 CPU, 메모리 사용량 같은 시스템 메트릭에는 아무런 문제가 발생하지 않는다. 이럴 때 비즈니스 메트릭이 있으면 이런 문제를 빠르게 인지할 수 있다.

비즈니스에 관한 부분은 각 비즈니스 마다 구현이 다르다. 따라서 비즈니스 메트릭은 직접 등록하고 확인해야 한다.
여기서는 우리 비즈니스의 실시간 주문수, 취소수 또 실시간 재고 수량을 메트릭으로 등록하고 확인해 보자..

- 주문수, 취소수

  • 상품을 주문하면 주문수가 증가한다.
  • 상품을 취소해도 주문수는 유지한다. 대신에 취소수를 증가한다.

- 재고 수량

  • 상품을 주문하면 재고 수량이 감소한다.
  • 상품을 취소하면 재고 수량이 증가한다.
  • 재고 물량이 들어오면 재고 수량이 증가한다.

주문수, 취소수는 계속 증가하므로 카운터를 사용하자.
재고 수량은 증가하거나 감소하므로 게이지를 사용하자.

OrderService

public interface OrderService {
  void order();
  void cancel();
  AtomicInteger getStock();
}
  • 주문, 취소, 재고 수량을 확인할 수 있는 주문 서비스 인터페이스이다.

OrderServiceV0

@Slf4j
public class OrderServiceV0 implements OrderService {
  private AtomicInteger stock = new AtomicInteger(100);

  @Override
  public void order() {
    log.info("주문");
    stock.decrementAndGet();
  }

  @Override
  public void cancel() {
    log.info("취소");
    stock.incrementAndGet();
  }

  @Override
  public AtomicInteger getStock() {
    return stock;
  }
}
  • new AtomicInteger(100) 초기값을 100으로 설정해둔다. 재고 수량이 100부터 시작한다고 가정한다.

OrderConfigV0

@Configuration
public class OrderConfigV0 {

  @Bean
  public OrderService orderService(){
    return new OrderServiceV0();
  }

}
  • 앞서 만든 OrderService 빈을 직접 등록하는 설정이다.

OrderController

@Slf4j
@RestController
public class OrderController {
  private final OrderService orderService;

  public OrderController(OrderService orderService) {
    this.orderService = orderService;
  }

  @GetMapping("/order")
  public String order(){
    log.info("order");
    orderService.order();
    return "order";
  }

  @GetMapping("/cancel")
  public String cancel(){
    log.info("cancel");
    orderService.cancel();
    return "cancel";
  }

  @GetMapping("/stock")
  public int stock(){
    log.info("stock");
    return orderService.getStock().get();
  }
}
  • 주문, 취소, 재고 수량을 확인하는 컨트롤러이다. 

ActuatorApplication

@Import(OrderConfigV0.class)
@SpringBootApplication(scanBasePackages = "hello.controller")
public class ActuatorApplication {

  public static void main(String[] args) {
    SpringApplication.run(ActuatorApplication.class, args);
  }


  @Bean
  public InMemoryHttpExchangeRepository httpExchangeRepository() {
    return new InMemoryHttpExchangeRepository();
  }
}
  • @Import(OrderConfigV0.class) : OrderServiceV0 를 사용하는 설정이다.
  • @SpringBootApplication(scanBasePackages = "hello.controller") : 컴포넌트 스캔의 대상을 컨트롤러로 제한한다. 그렇지 않으면 이후에 추가할 OrderConfigVX 가 모두 스프링 빈으로 등록되는 문제가 발생한다.
728x90