Home Event-driven Architecture
Post
Cancel

Event-driven Architecture

왜 Event-Driven Architecture인가?

Software Architecture의 진화

소프트웨어 아키텍처는 서비스의 규모가 커짐에 따라 대략적으로 모놀리틱 아키텍처에서 시작하여 컴포넌트 기반 아키텍처, 서비스 지향 아키텍처, 그리고 마이크로서비스 아키텍처로 발전해 왔습니다. 이러한 소프트웨어 아키텍처 진화의 공통적인 특징은 결합도(Coupling)를 낮추고, 응집도(Cohesion)를 올림으로써 확장성을 올리고, 복잡도를 낮추는 방향으로 발전을 해 왔다는 점입니다.

evolution of software architecture

  • 모놀리틱 아키텍처
    • 시기: 소프트웨어 개발의 초기 단계부터 존재했습니다.
    • 애플리케이션의 모든 기능이 단일 코드베이스 내에 통합되어 있습니다.
    • 시작하기 쉽고 초기 개발 속도가 빠르지만, 크기가 커지면 복잡도가 증가하고, 강한 결합으로 인해 유지보수가 어려워지고 확장성이 제한됩니다.
  • 컴포넌트 기반 아키텍처
    • 시기: 1990년대 중반부터 등장하기 시작했습니다.
    • 애플리케이션을 재사용 가능한 컴포넌트로 분리하여 개발하는 방식입니다.
    • 모듈성이 향상되어 유지보수와 확장이 용이해집니다.
    • 컴포넌트 간의 느슨한 결합을 지향하나, 실제 구현에서 의존성 관리에 주의를 하지 않으면, 하나의 컴포넌트를 수정하거나 업데이트할 때 전체 어플리케이션에 영향을 줄 수 있습니다.
    • 크기가 커지면 컴포넌트 간의 의존성을 증가하고, 이로 인해 유지 관리가 어려워지고, 시스템의 유연성이 떨어질 수 있습니다.
  • 서비스 지향 아키텍처
    • 시기: 2000년대 초반에 본격적으로 등장했습니다.
    • 애플리케이션을 독립적인 서비스의 모음으로 구성합니다.
    • 서비스는 정의된 인터페이스를 통해 상호 작용하며, 각 서비스는 독립적으로 개발, 배포, 유지보수될 수 있습니다.
    • 크기가 커지면 서비스간 결합도가 높아지면서 서비스 변경 시 다른 서비스에 미치는 영향이 커지고, 이러한 점은 유지 보수를 어렵게 합니다.
  • 마이크로서비스 아키텍처
    • 시기: 2010년대 초반에 등장하여 빠르게 인기를 얻었습니다.
    • SOA의 개념을 더 발전시켜, 더 작고, 더 독립적인 서비스로 나누어 애플리케이션을 구성합니다.
      • 마틴 파울러가 제시한 MSA의 핵심 원칙
        1. 컴포넌트 서비스화(Componentization via Services): 마이크로서비스는 개별적으로 배포 가능한 서비스로 구성되어야 하며, 각각이 독립적으로 개발 및 배포될 수 있어야 합니다.
        2. 조직화된 데칼의 법칙(Organized around Business Capabilities): 서비스는 특정 비즈니스 기능이나 능력을 중심으로 구성되어야 하며, 각 팀은 데이터베이스, 사용자 인터페이스, 외부 통합 등을 포함한 해당 비즈니스 기능을 완전히 소유하고 있어야 합니다.
        3. 제품처럼 서비스를 운영(Products not Projects): 각 마이크로서비스는 하나의 제품처럼 관리되어야 하며, 개발 팀은 서비스의 전체 수명 주기에 대해 책임을 져야 합니다.
        4. 스마트 엔드포인트와 더미 파이프(Smart endpoints and dumb pipes): 마이크로서비스는 간단한 통신 메커니즘을 사용해야 하며(예: REST over HTTP), 비즈니스 로직은 서비스 내부에 존재해야 합니다.
        5. 분산된 거버넌스(Decentralized Governance): 마이크로서비스는 다양한 기술과 도구를 사용할 수 있어야 하며, 각 팀은 자신의 서비스에 가장 적합한 기술을 선택할 수 있어야 합니다.
        6. 분산된 데이터 관리(Decentralized Data Management): 마이크로서비스는 각자의 데이터베이스를 소유하고 있어야 하며, 데이터는 서비스 간에 공유되기보다는 API를 통해 교환되어야 합니다.
        7. 인프라 자동화(Infrastructure Automation): 마이크로서비스는 배포, 테스팅, 스케일링 등을 자동화하여 운영 효율성을 높여야 합니다.
        8. 빠르게 실패하고 회복하기(Fail Fast and Recover): 마이크로서비스 아키텍처는 서비스가 실패할 경우 빠르게 감지하고 회복할 수 있는 메커니즘을 갖추고 있어야 합니다.
        9. 지속적인 통합 및 배포(Continuous Integration and Continuous Deployment, CI/CD): 마이크로서비스는 지속적인 통합과 배포를 통해 빠르게 변화하는 비즈니스 요구사항에 대응할 수 있어야 합니다.
    • 각 마이크로서비스는 작고, 단일 기능에 초점을 맞추며, 다른 서비스와는 느슨하게 결합됩니다.
    • 마이크로서비스 아키텍처는 서비스 지향 아키텍처 보다 확장성, 유연성을 대폭 향상시키고, 지속적인 배포와 통합을 용이하게 합니다.
    • 크기가 커지면 마이크로서비스 간 동기 통신은 시스템의 전반적인 성능에 영향을 미치며, 특히 서비스가 늘어날 경우 통신 복잡성이 크게 증가합니다.

왜 Event-Driven Architecture로 진화하는가?

현재 웹 서비스에서 Event-Driven Architecture가 주목 받는 이유는 여러 가지가 있습니다.

효율적인 데이터 처리, 높은 시스템 유연성, 마이크로서비스 아키텍처와의 상호 운용성, 향상된 장애 격리와 시스템 안정성, 재사용성, 낮은 결합도 등을 제공하여, 현대 웹 서비스가 직면한 다양한 도전 과제와 요구 사항을 해결할 수 있는 유망한 해결책입니다.

Event-Driven Architecture란?

이벤트 기반 아키텍처는 이벤트의 제작, 감지, 소비, 반응을 제고하는 소프트웨어 아키텍처 패턴이다.

evolution of software architecturewikipidia

Event 란?

  • 이벤트 기반 아키텍처에서 “이벤트(Event)”는 “상태의 상당한 변화”로 정의 됩니다.
  • 이벤트는 주로 시스템의 다른 부분이나 서비스가 반응해야 할 어떤 사건이 발생했음을 알리는 데 사용됩니다.
  • 이러한 이벤트는 사용자의 행동, 시스템의 변화, 외부 서비스로부터의 입력 등 다양한 원인에 의해 발생할 수 있습니다.

Command와 Event의 차이는?

  • Command: 명령은 수행해야 할 특정 작업이나 동작을 요청하는 것 입니다. 명령은 상대가 “무엇을 해야 함(What to do)”에 초점을 맞춥니다.
  • Event: 이벤트는 상태 변화나 사건을 나타냅니다. 이벤트는 나에게 “무엇이 일어났음(What happened)”에 초점을 맞춥니다.

command vs event

Event-Driven Architecture의 주요 구성 요소

  1. 이벤트 프로듀서 (Event Producers): 이벤트를 생성하고 발행하는 역할을 하는 컴포넌트입니다. 사용자 액션, 시스템 상태의 변화, 외부 시스템의 입력 등 다양한 원인에 의해 이벤트를 생성할 수 있습니다.
  2. 이벤트 컨슈머 (Event Consumers): 이벤트를 수신하고 이에 대한 반응으로 특정 작업을 수행하는 컴포넌트입니다. 컨슈머는 하나 이상의 이벤트에 대해 반응할 수 있으며, 이벤트의 내용에 따라 다양한 처리를 실행합니다.
  3. 이벤트 브로커 (Event Brokers): 이벤트 프로듀서와 컨슈머 사이에서 이벤트를 중개하는 역할을 합니다. 이벤트 브로커는 이벤트를 수신, 저장하고 적절한 이벤트 컨슈머에게 전달합니다.

Event-Driven Architecture의 주요 구성 요소Meaning of Event-Driven Architecture

Event-Driven Architecture의 장점

  • 비동기성 (Asynchrony)
    • EDA는 비동기적 통신을 사용합니다. 이벤트 프로듀서는 이벤트를 발행한 후, 이벤트 처리의 완료를 기다리지 않고 즉시 다음 작업을 진행할 수 있습니다. 이러한 비동기 통신은 시스템의 처리량을 증가시키고, 리소스 사용을 최적화할 수 있다
  • 느슨한 결합 (Loose Coupling)
    • EDA에서 컴포넌트들은 서로 직접적으로 연결되지 않고, 대신 이벤트를 통해 간접적으로 통신합니다.
    • 이로 인해 시스템의 유연성이 증가하고, 컴포넌트 간의 의존성이 줄어듭니다.
    • 이로 인해, 시스템의 각 부분을 독립적으로 개발하고 수정, 배포할 수 있으며, 시스템 전체의 유연성이 향상됩니다.

    느슨한 결합 (Loose Coupling)

  • 향상된 장애 격리와 시스템 안정성
    • EDA를 사용하면, 시스템의 한 부분에 문제가 발생해도 해당 이벤트를 처리하는 부분에만 영향을 미치고, 전체 시스템의 다운타임을 방지할 수 있습니다. 이는 서비스의 가용성과 안정성을 향상시킵니다.

    장애 격리

  • 확장성 (Scalability)
    • EDA는 시스템을 쉽게 확장할 수 있게 해줍니다. 이벤트 브로커를 통해 여러 이벤트 컨슈머에게 이벤트를 분산시킬 수 있으며, 부하에 따라 시스템의 다른 부분에 영향없이 컨슈머의 인스턴스 수를 조정할 수 있습니다.
  • 재사용성 (Reusability)
    • 특정 이벤트가 여러 컨슈머에서 사용이 되거나, 혹은, 하나의 컨슈머가 여러 이벤트가 처리할 수도 있습니다.

    서비스 재사용

    이벤트 재사용

  • 마이크로서비스 아키텍처와의 상호 운용성
    • EDA는 마이크로서비스 간의 비동기 이벤트 기반 통신을 자연스럽게 지원하여, 서비스 간의 느슨한 결합과 독립적인 배포를 가능하게 합니다.

Event-Driven Architecture의 단점

  • 복잡성 증가
    • 이벤트 흐름 추적: 이벤트가 여러 서비스나 컴포넌트를 통해 흐를 때, 이벤트의 경로를 추적하고 디버깅하는 것이 복잡해질 수 있습니다. 이벤트의 소스와 소비자가 느슨하게 결합되어 있기 때문에, 시스템의 흐름을 시각화하고 이해하기 어려울 수 있습니다.
    • 이벤트 관리: 대규모 시스템에서 수많은 이벤트를 관리하고, 이벤트의 스키마를 일관되게 유지하는 것이 도전적일 수 있습니다.
  • 비동기 통신
    • 테스트와 디버깅의 어려움: 이벤트 기반 시스템은 비동기적으로 작동하기 때문에, 전통적인 동기식 시스템에 비해 테스트와 디버깅이 더 복잡할 수 있습니다. 이벤트가 예상대로 처리되지 않거나 순서에 영향을 받는 경우, 문제의 원인을 찾기 어려울 수 있습니다.
    • UX 변경: 동기로 처리되던 서비스가 비동기로 처리되면서 고객 경험이 변경됩니다. 그에 따른 학습 및 서비스 변경도 동반됩니다.
      • 커머스에서 주문시 결제가 동기로 일어날 경우 —> 결제 실패 > 주문 실패
      • 커머스에서 주문시 결제가 비동기로 일어날 경우 —> 주문 성공 > 결제 실패 > SMS 알림, 장바구니에 다시 담아 주기 등 고객 경험 차원의 로직 필요.
  • 데이터 일관성 유지
    • 이벤트 순서: 이벤트가 발생하는 순서가 중요한 경우, 시스템이 이벤트를 정확한 순서대로 처리하도록 보장하는 것이 어려울 수 있습니다. 이는 특히 분산 시스템에서 더욱 도전적입니다.
      • 동기와 비동기를 동시에 사용하며, 데이터를 바꾼다면?
  • 추가적인 인프라스트럭처와 툴
    • 인프라스트럭처: EDA를 구현하고 운영하기 위해서는 이벤트 브로커 등의 추가적인 인프라스트럭처가 필요합니다. 이는 초기 설정 비용과 유지보수 비용을 증가시킬 수 있습니다.
    • 모니터링 및 로깅: 이벤트 기반 시스템을 효과적으로 모니터링하고 로깅하기 위해서는 추가적인 툴이 필요할 수 있으며, 이는 추가 비용과 복잡성을 의미합니다.

    모니터링

  • 보안 고려사항
    • 이벤트 데이터 보안: 이벤트 데이터는 안전한 전송을 위해 이벤트 버스에 저장됩니다. 이벤트가 민감한 정보를 포함할 수 있기 때문에, 데이터 보안과 프라이버시를 보장하는 추가 조치가 필요할 수 있습니다.

결론

Event-Driven Architecture는 현대 소프트웨어 설계와 개발에서 중요한 역할을 합니다. 이벤트 기반의 접근 방식은 비동기성, 느슨한 결합, 확장성, 재사용성 등의 이점을 제공하여, 복잡하고 동적인 비즈니스 요구 사항을 효율적으로 충족시킬 수 있게 해줍니다. Event-Driven Architecture는 마이크로서비스 아키텍처와 함께 사용될 때 특히 강력하며, 서비스 간의 상호작용을 자연스럽게 지원하고 시스템의 전체적인 유연성과 가용성을 향상시킵니다.

그러나 Event-Driven Architecture를 구현하고 관리하는 과정은 복잡성 증가, 테스트 및 디버깅의 어려움, 데이터 일관성의 유지, 추가적인 인프라스트럭처와 툴링, 보안 고려사항 등의 도전 과제를 수반합니다. 이러한 도전 과제를 극복하기 위해서는 명확한 설계 원칙, 체계적인 이벤트 관리, 효과적인 모니터링 및 로깅 전략, 그리고 강력한 보안 정책이 필요합니다.

결론적으로, Event-Driven Architecture는 확장 가능한 시스템을 구축하는 한 방안입니다. 향후 서비스에 Event-Driven Architecture를 적극적으로 학습하고 도입한다면, 서비스의 확장 및 유지 보수 관점에서 많은 이득을 얻을 수 있을 것으로 판단됩니다.

This post is licensed under CC BY 4.0 by the author.

Spring Batch 5

-