Skip to main content

Command Palette

Search for a command to run...

Command Bus는 반드시 비동기를 지원해야할까?

Updated
3 min read

배경

CQRS(Command Query Responsibility Segregation) Pattern은 명령(Command)과 조회(Query)를 분리하여 각각 독립적으로 최적화할 수 있는 강력한 아키텍처 패턴이다. 이를 통해 시스템의 확장성과 유지보수성을 높일 수 있다.

CQRS에서 명령을 처리하는 과정에서 Command Bus라는 개념이 등장하는데, 많은 자료에서 이를 비동기 방식으로 처리하는 예시를 주로 다루고 있다. 그러나 반드시 비동기 처리가 요구되는 것은 아니며, 오히려 동기 방식을 기본으로 시작하는 것이 더 적절할 수 있다.

이번 글에서는 Command Bus의 동기 및 비동기 방식에 대한 선택 기준을 알아보고, 어떤 경우에 비동기 방식을 도입하는 것이 적절한지에 대해 다뤄보려한다.

반드시 비동기를 지원해야하는가?

CQRS 패턴에서 Command Bus가 반드시 비동기로 동작해야 하는 것은 아니다.

실제로 많은 시스템에서 Command Bus는 기본적으로 동기적으로 동작하며, 필요에 따라 비동기 방식으로 전환하는 것이 더 바람직하다.

반 버논(Vaughn Vernon)의 Implementing Domain-Driven Design 책에서는 다음과 같이 언급된다.

"커맨드를 비동기식 메시지로 보내며, 이는 전용 스타일로 설계된 핸들러로 전달된다. 이는 각 커맨드 처리기 컴포넌트가 특정 타입의 메시지를 받도록 할 뿐만 아니라, 커맨드 프로세싱 부하를 처리할 수 있도록 주어진 타입의 처리기를 추가할 수 있다. 그러나 이 접근법에는 좀 더 복잡한 설계가 필요하기 때문에 이를 기본으로 사용하면 안 된다. 일단은 동기식 커맨드 처리기로 선택해 시작하자. 확장성(Scalability)의 요구가 있을 때에만 비동기식으로 변경하자."

즉, 비동기 처리는 기본값이 아니라 필요할 때 적용하는 것이 적절하다.

그렇다면 기본적으로 동기 방식이 적절한 이유는 무엇일까?

일관성 유지가 용이하다

  • 동기적으로 커맨드를 처리하면, 명령 실행 후 즉시 조회 모델이 최신 상태로 유지될 가능성이 높아진다.

  • 이는 사용자가 커맨드 실행 후 변경 사항을 즉시 확인할 수 있음을 의미한다.

    • 예를들어, 고객이 쇼핑몰에서 주문하면 주문 정보가 즉시 반영되어 보여주기를 기대한다. 만약 비동기 방식이라면, 메세지 큐에 의해 주문이 나중에 처리될 수 있으므로 즉시 조회했을 때 아직 데이터가 반영되지 않았을 가능성이 존재한다.

트랜잭션 관리가 단순하다

  • 동기 방식에서는 하나의 트랜잭션 내에서 명령을 실행하고 필요 시 쉽게 롤백할 수 있다.

    • 예를들어, 은행 계좌 이체를 수행할 때 하나의 트랜잭션으로 송금과 입금을 처리하면, 실패 시 쉽게 복구할 수 있다.
  • 반면 비동기 시스템에서는 비동기 방식에서는 분산 트랜잭션(Distributed Transaction) 처리가 필요해지는 복잡성이 초래된다.

디버깅이 용이하다

  • 동기 방식에서는 문제가 발생한 시점과 원인을 즉시 파악할 수 있다. 요청을 보낸 후 응답이 즉시 오기 때문에, 에러 발생 시 트레이스를 쉽게 따라갈 수 있다.

  • 반면 비동기 시스템에서는 메시지 지연이나 실패 시 추적이 어려울 수 있다.

그럼 언제 비동기 방식을 고려해야할까?

확장성이 요구될 때

  • 사용자가 많아지면 동기 방식의 커맨드 처리는 서버 부하를 증가시키고, 응답 속도가 느려질 수 있다.

  • 커맨드 처리를 메세징 서비스(e.g. Kafka)를 통해 비동기로 분산하면 수평 확장이 쉬워지고, 부하를 분산할 수 있다.

고성능이 요구되는 시스템일 때

  • 대량의 트래픽을 처리하는 시스템에서는 동기 방식으로 인해 성능 병목(Bottleneck)이 발생할 수 있다.

    • 예를들어, 실시간 데이터 스트리밍이 필요한 시스템에서는 빠른 응답을 위해 비동기 방식이 적절할 수 있다. 대규모 로그 처리 시스테에서 Kafka와 같은 서비스를 이용하여 이벤트를 비동기로 수집하는 사례까 대표적이다.

즉각적인 응답이 필요하지 않은 경우

  • 일부 도메인에서는 명령 실행 후 즉시 결과를 제공할 필요없는 경우가 있다.

위 케이스 외에도 더 다양한 트레이드 오프가 존재할것이라 생각한다. 만약 비동기로 명령을 처리하고 프론트쪽에서는 폴링 기법을 활용하여 처리가 완료될 때 까지 조회를 진행하는 방식을 채택할 수도 있다.

CQRS Pattern는 다양한 비지니스 요구사항을 만족할 수 있는 좋은 기법이라 생각하지만, 이번글에서 다룬 명령 처리 부분 외에도 읽기 모델(Read Model)을 가공하는 부분에서 대게 결과적 일관성 방식으로 구현되어 지연(Lag)과 실패에 대한 핸들링이 필요해진다.

More from this blog

리텐션이 0에 수렴해서 데이터부터 다시 들여다봤더니

Foundry는 백엔드 엔지니어를 위한 기초 지식 학습 플랫폼입니다. 시험을 보고, 틀린 문제를 오답노트에 정리하고, 개념을 복습하는 서비스인데요. 베타 오픈 후 커뮤니티에 올려서 유저도 좀 모았고, 기능도 하나하나 잘 만들어놨다고 생각했습니다. 그런데 GA4를 열어보니 현실은 달랐거든요. 문제: 숫자가 말해주는 현실 GA4 리포트를 열어봤더니 대시보드 페

Mar 15, 20265 min read30

극한 프로그래밍?

XP(Extreame Programming, 이하 XP)는 애자일 방법론 중 하나이다. 고객의 요구가 자주 변하는 환경에서 소프트웨어 품질을 높이고, 변화에 빠르게 대응하기 위해 고안된 개발 방법을 말한다. 1990년대, 켄트 백(kent back)이 chrysler c3 프로젝트에서 처음 체계화했다고하며, 짧은 개발 주기와 강한 피드백 루프, 협업 중심 문화를 특징으로 한다. XP는 “가치를 극대화하려면 좋은 활동들을 극단으로 끌어올리자”라는...

Dec 13, 20253 min read9
극한 프로그래밍?

물음표 엔지니어

20 posts

기술적 접근에 있어 트레이드 오프에 대한 고민을 다뤄보려합니다.

(Deprecated Blog: https://jeongkyun-it.tistory.com)