한 줄 정의

오케스트레이션 주도 서비스 지향 아키텍처

엄격한 서비스 분류 체계(business / enterprise / application / infrastructure)와 그 사이를 잇는 중앙 오케스트레이션 엔진(ESB) 을 축으로, 전사 차원의 재사용 을 극단까지 추구한 1990년대 말~2000년대 초의 분산 통합 아키텍처입니다.

쉽게 말하면

여러 사업부와 레거시 시스템이 뒤섞인 대기업이 “앞으로 이 회사의 모든 비즈니스 행동방식은 한 곳에서 정의하고 한 곳에서 조립한다” 고 선언한 결과물입니다.

그래서 회사 곳곳에 흩어진 기능을 잘게 쪼개 엔터프라이즈 서비스 로 만들고, 그것들을 오케스트레이션 엔진(주로 ESB) 이 뽑아 와서 비즈니스 시나리오대로 엮어줍니다. 그림으로 그리면 모든 화살표가 ESB를 향하고 ESB를 통해 다시 흩어지는, 모든 길이 ESB로 통하는 토폴로지가 만들어집니다.

이름에 서비스 가 있다고 해서 마이크로서비스서비스 기반 아키텍처와 같은 부류로 묶으면 안 됩니다. 같은 단어가 시대마다 다른 뜻으로 쓰여 왔기 때문입니다(이른바 의미 확산(semantic diffusion)). SOA의 엔터프라이즈 서비스는 마이크로서비스의 그것과 거의 모든 면에서 다릅니다.

왜 이렇게 설계했는가?

  • 해결하는 문제: 인수합병으로 비대해진 대기업이 부서마다 비슷한 기능(고객 관리, 견적 계산 등)을 중복 구현하는 소프트웨어 자산의 파편화, 그리고 비싼 운영체제·DB 라이선스 환경에서 모든 것을 재사용해서 비용을 절감 해야 한다는 압박입니다.
  • 이게 없다면: 보험회사의 자동차/생명/장애/여행 등 사업부마다 자기 버전의 Customer, PlaceOrder 로직을 따로 가지게 됩니다. 변경 비용이 부서 수만큼 곱해지고, 회사 차원의 비즈니스 룰을 일관되게 적용할 수 없습니다.

이 아키텍처가 사장된 핵심 이유는 단순합니다. “논리적으로 타당해 보이는 조직의 아이디어가 어떻게 개발 프로세스를 무너뜨릴 수 있는지” 를 보여주는 본보기가 되었기 때문입니다. 소프트웨어 아키텍처의 제1법칙 — 모든 것은 트레이드오프 라는 사실을 무시한 결과입니다.

토폴로지

flowchart TB
    subgraph BSL["비즈니스 서비스 계층"]
        direction LR
        BS1[BS] ~~~ BS2[BS] ~~~ BS3[BS] ~~~ BS4[BS] ~~~ BS5[BS]
    end
    subgraph ESBus["엔터프라이즈 서비스 버스 (ESB)"]
        direction TB
        OE["오케스트레이션 엔진"]
        IH["통합 허브"]
    end
    subgraph ESL["엔터프라이즈 서비스 계층"]
        direction LR
        ES1[ES] ~~~ ES2[ES] ~~~ ES3[ES] ~~~ ES4[ES] ~~~ ES5[ES]
    end
    subgraph ASL["애플리케이션 서비스"]
        direction LR
        AS1[AS] ~~~ AS2[AS]
    end
    subgraph ISL["인프라스트럭처 서비스"]
        direction LR
        IS1[IS] ~~~ IS2[IS]
    end
    BSL <--> OE
    OE --- IH
    IH <--> ESL
    ESL <--> ASL
    ESL <--> ISL
각 계층의 역할
계층역할예시
비즈니스 서비스비즈니스 프로세스의 진입점거래실행, 주문 접수
엔터프라이즈 서비스원자적·세분도 높은 재사용 빌딩 블록CreateCustomer, CalculateQuote
애플리케이션 서비스일회성·단일 구현 (재사용 안 함)지리 위치 조회
인프라스트럭처 서비스운영 관심사모니터링, 로깅, 인증, 권한 부여
오케스트레이션 엔진 + 통합 허브위 계층들을 엮고 트랜잭션·매핑·계약 변환ESB

토폴로지의 경계는 흐릿합니다. 같은 도구가 통합 허브와 오케스트레이션 엔진을 동시에 수행할 수도 있고, 서비스 분류 체계의 일부가 애플리케이션 서버 안에 들어가 있을 수도 있습니다.

핵심 내용

분류 체계 — 추상화와 재사용을 위한 위계

분류 체계(taxonomy of services) 는 잘 정의된 계층과 그에 상응하는 책임으로 구성됩니다. 이 위계의 두 가지 목표는 궁극적인 추상화엔터프라이즈 수준의 재사용 입니다.

비즈니스 서비스

SOA 최상단에 위치하며, 비즈니스 프로세스의 진입점 입니다. 어떤 서비스가 비즈니스 서비스에 해당하는지 가르는 판별 기준 은 다음과 같습니다.

이 서비스가 ~ 비즈니스를 수행하는 게 맞는가?

ExecuteTrade(거래 실행), PlaceOrder(주문 접수) 같은 서비스는 이 기준을 통과합니다. 반면 CreateCustomer는 비즈니스가 아니라 거래 실행에 필요한 절차일 뿐이므로 비즈니스 서비스가 아닙니다.

비즈니스 서비스의 정의에는 코드가 전혀 포함되지 않습니다. 입력·출력·스키마 정보만으로 정의되며, 비즈니스 사용자나 분석가가 직접 서명(signature) 을 정의합니다. 즉, 비즈니스 서비스는 “회사가 무슨 일을 하는가”의 카탈로그에 가깝습니다.

엔터프라이즈 서비스

엔터프라이즈 서비스는 비즈니스 서비스를 만드는 데 쓰는 잘게 쪼갠 부품 입니다.

CreateCustomer(고객 생성), CalculateQuote(견적 계산)처럼 하나의 동작만 깔끔히 수행하는 단위 가 여기에 해당하고, Customer, Order, Lineitem 같은 트랜잭션 엔티티도 포함됩니다. 오케스트레이션 엔진이 이 부품들을 순서대로 엮어서 ExecuteTrade 같은 비즈니스 서비스를 만들어 냅니다.

비즈니스 서비스와 엔터프라이즈 서비스의 차이는 “얼마나 큰 단위인가” 입니다.

단위 크기예시
비즈니스 서비스큼 (회사 단위 비즈니스 한 건)ExecuteTrade, PlaceOrder
엔터프라이즈 서비스작음 (그 비즈니스를 이루는 하나의 동작)CreateCustomer, CalculateQuote

이 아키텍처의 이상은 엔터프라이즈 서비스를 레고 블록 처럼 만들어 두는 것입니다. 한 번 잘 만들어 두면 어떤 비즈니스 시나리오가 와도 블록을 새로 조립하기만 하면 되도록 말입니다.

그러나 레고 블록의 꿈은 깨집니다

문제는 블록의 크기를 정하기가 무척 어렵다 는 점입니다.

  • 너무 잘게 쪼개면 → 새로운 비즈니스마다 수십 개를 조립해야 해서 결국 비즈니스 부서가 자기 코드를 다시 짜는 게 빠르겠다 고 느낍니다.
  • 너무 크게 묶으면 → 다른 부서가 쓰려고 보면 자기 상황에는 안 맞는 부분이 너무 많아서 못 가져다 씁니다.

게다가 도메인은 계속 변합니다. 한번 정해놓은 블록 크기가 6개월 뒤 새로운 비즈니스 요구사항 에는 안 맞을 수 있습니다. 결국 이 두 가지를 모두 잡으려다 둘 다 놓치는 경우가 많습니다.

  • 다시 작성할 필요 없을 만큼 딱 맞는 크기의 부품
  • 시간이 지나도 계속 쓸 수 있게 하는 유연성
애플리케이션 서비스

엔터프라이즈 서비스 수준의 재사용이 필요 없는 일회성 기능을 위한 계층입니다. 예를 들어, 한 애플리케이션이 지리 위치 정보를 필요로 하지만 다른 사업부에선 쓸 일이 없다면, 굳이 재사용 가능한 엔터프라이즈 서비스로 만드는 비용을 들이지 않고 애플리케이션 서비스(보통 그 애플리케이션 팀이 소유) 로 구현합니다.

인프라 서비스

모니터링·로깅·인증·권한 부여 같은 운영상의 횡단 관심사 를 담당합니다. 운영 팀과 협력하는 공유 인프라 팀이 소유하는 것이 자연스럽습니다.

오케스트레이션 엔진과 메시지 버스

오케스트레이션 엔진(orchestration engine)메시지 버스(message bus) 가 이 아키텍처의 심장부를 형성합니다. 이 둘은 다음 책임을 동시에 수행합니다.

  • 트랜잭션 조정·메시지 변환
  • 비즈니스 서비스와 엔터프라이즈 서비스의 매핑 정의
  • 트랜잭션 경계 정의
  • 통합 허브 역할 — 맞춤형 코드를 패키지/레거시 시스템과 통합

이 기능 조합이 곧 ESB(Enterprise Service Bus) 의 현대적 활용법입니다.

대부분의 아키텍트는 ESB 중심으로 전체 아키텍처를 짜는 것을 나쁘다고 보지만, 통합이 많은 환경 에서는 ESB가 엄청나게 유용합니다. 통합 허브와 오케스트레이션 엔진을 결합해야 한다면, 둘 다 이미 포함된 도구를 쓰지 않을 이유가 없기 때문입니다.

콘웨이의 법칙으로 본 부작용

오케스트레이션 엔진과 메시지 버스가 심장부라는 점에 콘웨이의 법칙을 적용하면, 이 엔진을 책임지는 통합 아키텍트 팀 은 조직 내에서 하나의 정치적 세력이 되고, 결국에는 관료적 병목 지점 이 되리라는 예측이 자연스럽습니다. 실제로 일어난 일이기도 합니다.

트랜잭션 위임의 환상

트랜잭션 행동방식을 오케스트레이션 도구에 위임하는 게 좋아 보이지만, 실제로는 적절한 세분도 수준을 찾기가 매우 어렵습니다.

분산 트랜잭션으로 감싸도 아키텍처는 점점 더 복잡해지고, 엔티티가 수많은 작업흐름에 관여할수록 서비스 사이의 적절한 트랜잭션 경계 를 파악하기 어려워집니다. 관리자들은 트랜잭션 구축 요소를 엔터프라이즈 서비스 형태로 만들 수 있으리라 기대했지만, 실제로는 어렵다는 점만 판명되었습니다.

메시지 흐름

모든 요청은 오케스트레이션 엔진을 통과합니다. 내부 호출조차 엔진을 거쳐 갑니다. 견적 생성 시나리오로 흐름을 보면 다음과 같습니다.

flowchart TB
    CreateQuote[CreateQuote<br/>비즈니스 서비스] --> ESB1[엔터프라이즈 서비스 버스]
    ESB1 --> CreateCustomer & CalcQuote
    CreateCustomer --> ESB2[엔터프라이즈 서비스 버스]
    CalcQuote --> ESB2
    ESB2 --> AddDriver & AddVehicle & CheckDMV
    AddDriver --> ESB3[엔터프라이즈 서비스 버스]
    AddVehicle --> ESB3
    CheckDMV --> ESB3
    ESB3 --> WriteAudit

서비스 버스가 모든 호출의 중개자(intermediary) 로 작동해서 통합 허브와 오케스트레이션 엔진의 기능을 모두 수행합니다. 이 토폴로지의 의미는 두 가지입니다.

  • 모든 호출이 엔진을 지나가므로 엔진의 특성이 곧 시스템 전체의 특성 이 됩니다(성능, 신뢰성, 가용성 모두).
  • 엔진은 거대한 결합 지점(coupling point) 입니다.

재사용과 결합 — SOA가 약속한 것과 실제로 일어난 일

이 아키텍처를 처음 활용한 아키텍트들은 공격적으로 재사용 기회를 찾으라 는 지시를 받았습니다. 결정적인 본보기는 보험회사의 Customer 추출입니다.

출발: 흩어진 고객 개념
flowchart TB
    Auto[자동차/주택소유자<br/>보험 사업부]
    Life[생명보험 사업부]
    Comm[상업보험 사업부]
    Disab[장애보험 사업부]
    Inj[손해보험 사업부]
    Travel[여행보험 사업부]

여섯 부서가 모두 자체적인 고객 개념을 갖고 있다는 사실을 발견하면, 올바른 SOA 전략으로 보이는 행동은 공통 Customer 서비스 를 추출해 모든 부서가 그것을 참조하게 만드는 것입니다.

결과: 결합으로 변한 재사용
flowchart LR
    Auto[자동차/주택<br/>보험] --> Cust[Customer]
    Life[생명보험] --> Cust
    Comm[상업보험] --> Cust
    Disab[장애보험] --> Cust
    Inj[손해보험] --> Cust
    Travel[여행보험] --> Cust

이 그림은 표면적으로 “명백한 재사용 목표 달성”처럼 보이지만, 실제로는 재사용이 결합을 통해 구현 된다는 본질을 그대로 보여줍니다.

문제구체적 양상
변경 파급Customer를 변경하면 여섯 부서의 모든 서비스로 영향 파급. 점진적 변경조차 위험 요인
엔지니어링 효율 저하배포 조율과 전일적 테스트(holistic testing)가 필수가 되어 속도 저하
무관한 속성의 강제자동차 보험에는 운전면허증 정보가 필요하지만 장애보험에는 무의미. 그러나 회사 전체 단일 정의이므로 장애보험 팀도 이 복잡성을 감당해야 함

이런 경험 때문에 DDD전체론적 재사용(holistic reuse)을 피해야 한다 고 주장합니다.

도메인 개념의 분쇄

가장 해로운 측면은, 기술적 분할에 너무 치중한 아키텍처를 현실적으로 운용 불가능하다 는 점입니다.

CatalogCheckout에 새 주소 행 한 줄을 추가하는 정도의 비교적 간단한 작업조차 SOA에서는 여러 계층에 걸친 수십 개의 서비스와 공통 DB 스키마를 변경 해야 할 수 있습니다.

CatalogCheckout 같은 도메인 개념이 아키텍처 전반에 너무 얇게 펴져 있어 거의 가루가 될 지경 이 됩니다. 엔터프라이즈 서비스가 적절한 트랜잭션 세분도로 정의되어 있지 않다면, 개발자들이 설계나 트랜잭션 행동방식을 변경하려 할 때 기존 서비스와 거의 동일한 서비스를 새로 만들어야 하는 지경에 다다를 수 있습니다.

결론

이 정도라면 재사용은 그만두는 것이 낫습니다. 분리와 재사용 철학의 관점에서는 타당해 보이지만, 실제로는 악몽 같습니다.

데이터 토폴로지

이 책에서 다루는 다른 분산 아키텍처와 달리, 단일(또는 소수)의 관계형 데이터베이스 를 쓰는 경우가 많았습니다. 1990년대 후반에는 분산 아키텍처가 대부분 그런 관행을 따랐기 때문입니다.

흥미로운 점은 트랜잭션성(transactionality)조차 데이터베이스 시스템이 아니라 아키텍처가 담당 했다는 사실입니다. 메시지 버스에 토폴로지 안의 각 엔티티에 대한 선언적 트랜잭션 행동방식 을 두어, 개발자나 아키텍트가 데이터베이스(심지어는 개별 엔티티)의 상황별 재사용과는 독립적으로 트랜잭션 행동방식을 결정할 수 있게 했습니다.

선언형 트랜잭션의 실패

SOA가 유행하던 시절 많은 애플리케이션 서버가 구성 관리자(configuration manager) 를 통해 개별 엔티티의 트랜잭션 범위를 변경할 수 있게 해주었습니다. 엔티티가 어떤 트랜잭션 컨텍스트에서 작동하는지에 따라 범위를 다르게 하는 것이 가능했고, 이 선언은 EntityBeans 같은 자바빈(JavaBean) 형태의 XML로 이루어졌습니다. 작업흐름이 트랜잭션에 포함될지 여부는 아키텍트가 직접 선언했고, 애플리케이션 서버가 데이터베이스와 상호작용해서 그에 부합하는 트랜잭션을 생성·관리했습니다.

이 방식이 실패한 원인은 두 가지입니다.

실패 원인양상
실행 시점 트랜잭션을 모름엔티티들과 의존성이 복잡해져서 트랜잭션 범위만 다른 동일 버전 엔티티를 여러 개 만들어야 함
추상화의 누수메시지 버스에 정교한 기능을 추가해도 예상치 못한 예외 사례 때문에 실패 모드가 많아져 트랜잭션을 깔끔하게 관리하지 못함

추상화에 새는 곳이 많으면 신뢰성을 확보할 수 없습니다. 트랜잭션처럼 복잡하고 다면적인 시스템 기능 중 일부는 깔끔하게 추상화할 수 없다 는 교훈입니다.

일반적인 위험

20세기 말과 21세기 초 이 아키텍처의 가장 큰 위험은 비용, 구현 시간, 유지보수·업데이트의 어려움 이었습니다.

대부분 수년에 걸쳐 진행되는 비싼 사업이었고, 중요한 결정은 회사 고위층이 내렸습니다. 회사들은 이런 프로젝트를 ‘실패’로 돌리는 대신, 경계(boundary)를 개선하고 DDD 의 이상에 정렬되도록 고쳐서 통합 아키텍처로 전환 하곤 했습니다.

우발적 SOA (Accidental SOA) 안티패턴

그런데 통합 아키텍처로 전환하는 과정에서 새로운 함정이 기다리고 있었습니다. ESB를 단순한 통합 기능으로만 도입했는데, 시간이 지나면서 자신도 모르게 점진적으로 완전한 오케스트레이션 주도 SOA를 구축하게 되는 현상입니다. 마치 미끄러운 경사로를 따라 구덩이로 빠져드는 것과 같습니다.

원인은 명확합니다. ESB가 통합 허브 역할을 잘하니까 점점 더 많은 책임을 ESB로 옮기게 되고, 결국 모든 비즈니스 로직이 ESB의 오케스트레이션 정의 안으로 흡수 됩니다. 어느 순간 시스템은 SOA의 모든 단점을 그대로 떠안게 됩니다.

회피 방법
  • 오케스트레이션을 위한 합리적인 캡슐화 경계 를 보장
  • 트랜잭션 경계 와 같은 문제에도 세심한 주의

거버넌스

이 아키텍처가 유행하던 시절 자동화된 거버넌스 라는 개념은 테스트 자동화보다도 더 생소했습니다. 그 시대의 ‘거버넌스’는 무거운 거버넌스 프레임워크와 회의, 코드 검토를 의미했고 모두 수작업 이었습니다.

지금도 ESB는 전략적으로 사용됩니다. 특히 현대적 시스템과 상호작용해야 하는 구식 시스템(legacy system)이 많은 조직에서 그렇습니다. 이때 거버넌스의 핵심은 적합성 함수 로 ESB의 흔한 오용 사례 주위에 가드레일을 설치하는 것입니다.

적합성 함수(fitness function)란?

아키텍처 규칙이 지켜지는지 자동으로 검사하는 코드 입니다. 단위 테스트가 “이 함수가 올바르게 동작하는가?”를 검증한다면, 적합성 함수는 “우리가 정한 아키텍처 약속이 깨지지 않았는가?” 를 검증합니다.

예: “Service A는 Service B를 직접 호출하지 않는다”, “API 응답시간은 200ms 이하다”, “ERP 시스템은 읽기 전용으로만 접근한다” 같은 규칙을 코드로 작성해 CI 파이프라인이나 정기 배치로 실행합니다. 위반이 감지되면 사람의 코드 리뷰가 놓친 침식(architectural erosion) 도 자동으로 알람이 옵니다.

닐 포드(이 책의 저자 중 한 명)와 레베카 파슨스의 Building Evolutionary Architectures 에서 정형화된 개념입니다.

통합 지점 간 통신 적합성 함수 예시

전통적인 ERP 패키지와 온라인 판매 도구, 그리고 마이크로서비스 기반 Accounting(회계) 서비스를 ESB로 조정하는 시스템을 가정합니다. 시스템 의도는 ERP·판매 시스템에는 읽기 전용, Accounting에는 쓰기 전용 으로 접근하는 것입니다. 이 의도가 깨지지 않도록 적합성 함수를 작성합니다.

READ logs for ERP into ERP-logs for past 24 hours
READ logs for Sales into Sales-logs for past 24 hours
FOREACH entry IN ERP-logs
    IF 'operation' is 'update' and 'target' != 'accounting' THEN
        raise fitness function violation
            "Invalid communication between integration points"
    END IF
FOREACH entry IN Sales-logs
    IF 'operation' is 'update' and 'target' != 'accounting' THEN
        raise fitness function violation
            "Invalid communication between integration points"
    END IF

이 적합성 함수는 두 통합 지점의 로그를 읽어, 대상이 Accounting이 아닌 갱신 작업이 발생하지 않도록 보장 합니다. 적합성 함수는 데이터나 경계 컨텍스트가 생태계의 다른 부분으로 ‘누출(leak)‘되는 것을 막는 역할을 합니다.

팀 토폴로지 고려 사항

이 스타일이 유행할 당시 팀 토폴로지는 사람들에게 알려지지 않은 주제 였습니다. 오히려 팀 토폴로지의 원칙들이 발달하게 된 동기 중 하나가 SOA의 엄격한 분류 체계 때문에 발생하는 소통(communication) 안티패턴이었습니다.

이 아키텍처의 목표는 책임의 극단적인 분리 이고, 팀들도 그 분리를 따라 나뉩니다. 그래서 SOA를 채택한 회사에서는 비즈니스 서비스 팀과 엔터프라이즈 서비스 팀이 대화를 나누는 일이 극히 드물었습니다. 계약·인터페이스 같은 기술적 구성요소를 통해서만 소통하고, 통합 계층이 많아 각 계층마다 다른 팀이 구현하며, 팀 간 소통은 엔터프라이즈급 티켓팅 도구 를 통해 이루어졌습니다. 개발자들이 왜 이 스타일로 기능을 구축하는 데 시간이 오래 걸린다고 생각하는지 쉽게 알 수 있습니다.

팀 유형적합도이유
스트림 정렬 팀 (기능 전담 팀)매우 낮음단일 기능 변경이 BS·ES·AS·IS 모든 계층을 가로지름. 팀 자율성과 빠른 흐름 불가
활성화 팀 (역량 코칭 팀)낮음분류 체계가 외부 코칭 형태와 어울리지 않음
난해한 하위시스템 팀 (전문 도메인 팀)중간오케스트레이션 엔진·통합 허브 같은 전문 영역에 한해 의미 있음
플랫폼 팀 (공통 기반 팀)중간ESB·메시지 버스·인프라 서비스를 플랫폼 형태로 제공할 수 있음. 단, 곧 관료적 병목으로 변질될 위험

장단점

아키텍처 특성평가
전반적인 비용매우높음($$$$)
분할 방식기술적
퀀텀 개수1 이상
단순성★☆☆☆☆
모듈성★★★☆☆
유지보수성★☆☆☆☆
테스트성★☆☆☆☆
배포성★☆☆☆☆
진화성★☆☆☆☆
반응성★★☆☆☆
확장성★★★★☆
탄력성★★★☆☆
내결함성★★★☆☆
분할 방식과 퀀텀

SOA는 이제껏 시도된 범용 아키텍처 중 가장 기술적으로 분할된 아키텍처 일 것입니다. 마이크로서비스 같은 좀 더 현대적인 아키텍처들은 사실상 이 아키텍처의 단점에 대한 반발에서 나왔습니다. 분산 아키텍처임에도 퀀텀이 단 하나 인 이유는 두 가지입니다.

  • 일반적으로 단일 데이터베이스 또는 소수의 데이터베이스만 사용 → 서로 다른 관심사에 걸친 결합 지점이 생김
  • 오케스트레이션 엔진 자체가 거대한 결합 지점 → 엔진이 모든 행동방식을 중재하므로 아키텍처의 모든 부분이 엔진의 특성을 그대로 지님

결과

이 아키텍처는 모놀리스 아키텍처의 단점과 분산 아키텍처의 단점을 모두 가집니다. 분산해서 얻는 장점은 적고, 분산이 강요하는 비용은 그대로 떠안는 셈입니다.

배포성·테스트성·유지보수성·진화성 ★☆☆☆☆

현대적 엔지니어링 목표 대부분이 이 아키텍처에서는 재앙에 가까운 점수를 받습니다. 이 아키텍처가 개발될 당시에는 이런 것들이 중요한 목표(심지어 지향해야 할 목표도)가 아니었기 때문입니다. 한 엔티티의 세부 정보를 갱신하는 평범한 변경조차 서너 개에서 대여섯 개의 계층 을 손대야 할 수 있고, 그 변경 때문에 계층들이 더 강하게 결합하는 부작용까지 따라옵니다. 그래서 이 스타일을 다루는 아키텍트는 변경이라는 단어를 듣기만 해도 두려워합니다.

탄력성·확장성 ★★★★☆ / ★★★☆☆

도구 벤더사들은 애플리케이션 서버 간 세션 복제를 비롯한 기술을 만들어 확장성을 끌어올리는 데 엄청난 노력을 쏟았습니다. 결과적으로 어느 정도는 지원되지만 구현이 어렵습니다.

반응성 ★★☆☆☆

성능이 장점이었던 적은 한 번도 없습니다. 애초에 분산 아키텍처이기 때문입니다. 각 비즈니스 요청이 아키텍처의 너무 많은 부분에 걸쳐 분할되므로 낮은 성능이 필연적 입니다.

비용

단순성과 비용 측면에서 이 스타일은 대부분의 아키텍트가 선호하는 것과 정반대 입니다. 그럼에도 SOA는 아키텍처 발전사의 중요한 이정표로서 의미가 있습니다. 기술적 분할이 현실적으로 어떤 한계를 갖는지, 실제 환경에서 분산 트랜잭션이 얼마나 어려울 수 있는지를 아키텍트들이 깨닫게 한 사례입니다.

적합한 상황

사용하면 좋은 경우

  • 클라우드 서비스와 온프레미스 서비스를 통합 해서 작업흐름에 참여시켜야 할 때 (현대적 용법)
  • 구식 시스템(legacy system)·패키지 소프트웨어·맞춤형 코드가 뒤섞여 있고 상호작용 조정 이 필요한 환경
  • ESB가 제공하는 통신·프로토콜·계약 변환 + 오케스트레이션의 결합 기능이 반드시 필요한 조직

사용하지 말아야 할 경우

  • 새 시스템을 처음부터 설계하는 경우 (마이크로서비스 같은 도메인 분할 스타일이 대부분 더 적합)
  • 빠른 변경과 진화 가 핵심 요구사항인 시스템
  • 단일 도메인을 빠르게 확장하려는 스타트업 또는 중소 조직
  • 자율적 팀 구조DDD 기반 경계 컨텍스트를 추구하는 조직

예시

1990년대~2000년대 초 대기업 통합

수많은 인수합병으로 비대해진 금융·통신·보험 회사들이 가장 많이 채택했습니다. 사업부별로 흩어진 시스템을 묶어 회사 전체에 걸쳐 시스템 구성요소를 효과적으로 재사용 하려는 시도였지만, 엄격하고 정교한 분류 체계 때문에 일반적인 변경과 업데이트가 얼마나 어려운지 깨닫게 되면서 점차 마이크로서비스처럼 더 민첩한 도메인 기반 분산 아키텍처로 대체 되었습니다.

현대의 통합 아키텍처 활용

SOA는 이제 통합 아키텍처로 전략적으로 활용됩니다. ESB에는 통합 허브 기능(통신, 프로토콜, 계약 변환)과 오케스트레이션 엔진의 기능(다양한 통합 종단점 사이에 작업흐름 구축)이 모두 포함되며, 간접층(layer of indirection)이 여러 수준으로 존재합니다. 그래서 엔터프라이즈 서비스를 통합 지점, 패키지 소프트웨어, 맞춤형 코드 등 다양한 방식으로 구현 할 수 있습니다.

flowchart TB
    Client[클라이언트 요청] --> ESB1[ESB]
    BS1[BS] --> ESB1
    BS2[BS] --> ESB1
    ESB1 --> API1[API 계층]
    API1 <--> ES1[ES] & ES2[ES] & ES3[ES] & ES4[ES] & ES5[ES] & ES6[ES]
    ES1 & ES2 & ES3 & ES4 & ES5 & ES6 --> ESB2[ESB]
    ESB2 --> API2[API 계층] & API3[API 계층]
    API2 --> SCs["서비스 컴포넌트들<br/>(모델 + 모델)"]
    API3 --> Mainframe[메인프레임]

클라이언트 요청에 따라 어떤 엔터프라이즈 서비스가 어떤 순서로 호출되고 어떤 정보를 집계할지는 메시지 버스를 통해 결정 합니다. 엔터프라이즈 서비스는 API를 통해 맞춤형 코드, 구식 시스템, 패키지 소프트웨어와 통신합니다.

비교 / 트레이드오프

스타일공통점차이점
Ch14 서비스 기반 아키텍처분산, 서비스 단위, DB 공유 가능서비스 기반은 도메인 분할·단순함이 강점, 오케스트레이션 SOA는 기술 분할·중앙 ESB
Ch15 이벤트 주도 아키텍처비동기 메시징 사용 가능이벤트 주도는 분산된 비동기 흐름이 본질, 오케스트레이션 SOA는 중앙 엔진이 모든 흐름 통제
Ch16 공간 기반 아키텍처분산 아키텍처공간 기반은 캐시·DB 분리로 극단적 확장성, 오케스트레이션 SOA는 통합·재사용에 초점
Ch18 마이크로서비스 아키텍처”서비스” 명칭 공유마이크로서비스는 도메인 분할·서비스별 DB·자율성, SOA는 기술 분할·공유 DB·중앙 엔진. 거의 모든 면에서 정반대
마이크로서비스가 SOA에 진 빚

마이크로서비스는 SOA의 단점에 대한 반발로 등장했다고 해도 과언이 아닙니다. SOA의 다음 교훈이 마이크로서비스의 설계 원칙으로 이어졌습니다.

  • 기술 분할 → 도메인 분할
  • 단일·소수 DB 공유 → 서비스별 DB
  • 중앙 오케스트레이션 → 코레오그래피와 자율 서비스
  • 전체론적 재사용 → 적당한 중복 허용

내 생각

  • 이 챕터는 “엄격한 분류 체계에 기반한 재사용은 결합 비용으로 변한다” 는 점을 가장 가혹하게 보여주는 사례입니다. 보험회사 Customer 사례를 보면, 단순히 SOA의 문제가 아니라 “공통 모델로 추출하는 것이 항상 좋은가?” 라는 일반적인 질문을 다시 하게 합니다. 사내 공통 라이브러리, 공통 인증 모듈, 공통 결제 SDK 등 일상적으로 만나는 모든 “공통 ~“에 같은 위험이 있습니다.

  • 한국 기업 환경에서 떠올리기 쉬운 사례는 금융 그룹사의 EAI/ESB 통합 플랫폼 입니다. 은행·증권·카드·보험 자회사를 하나의 ESB로 묶어 그룹 통합 고객 정보를 만들고자 하는 시도가 거의 모두 SOA를 거쳐 갔고, 변경 비용 폭발과 통합 아키텍트 팀의 관료화라는 이 챕터의 예측을 그대로 답습했습니다.

  • 우발적 SOA(Accidental SOA) 가 가장 무서운 부분입니다. ESB나 카프카, 심지어 사내 API 게이트웨이도 같은 함정을 가집니다. 처음에는 “통합만 하자”는 의도로 들이지만, 점점 비즈니스 로직이 게이트웨이 설정·라우팅 룰·오케스트레이션 정의 안으로 흡수됩니다. “이 도구는 통합만 한다”는 약속을 코드로(적합성 함수로) 강제 하지 않으면 결국 SOA가 됩니다.

  • 선언형 트랜잭션의 실패 분석은 지금도 유효합니다. 추상화에 새는 곳이 많으면 신뢰성을 확보할 수 없다 — 이는 사가(saga) 패턴, 분산 트랜잭션 코디네이터, 심지어 ORM의 트랜잭션 어노테이션까지 모든 추상화에 적용되는 일반 법칙입니다. EntityBeans는 사라졌지만, “잘 추상화되었으니 트랜잭션 걱정 안 해도 됩니다”라는 약속은 여전히 자주 깨집니다.

  • 흥미로운 역설은 “오케스트레이션 SOA가 통합 아키텍처로는 여전히 합리적” 이라는 점입니다. 이는 도구의 죄가 아니라 사용 범위의 죄였다는 뜻입니다. ESB로 회사 전체 비즈니스 로직을 정의 하면 재앙이지만, ESB로 레거시 시스템과 신규 시스템 사이의 어댑터 만 두면 매우 유용합니다. 도구의 가치를 분별하는 것 자체가 아키텍트의 능력이라는 챕터 말미의 지적이 핵심입니다.

  • 팀 토폴로지 관점에서 보면, SOA가 팀 토폴로지 원칙을 발달시킨 동기였다 는 점이 의미심장합니다. 즉 SOA의 실패가 곧 “기술 계층이 아닌 비즈니스 도메인을 따라 팀을 나누어야 한다”DDD의 정신과 마이크로서비스의 자율 팀 모델로 이어진 셈입니다. 실패에서 출발한 것이 현재의 베스트 프랙티스가 된 사례는 드물지 않지만, SOA는 그중에서도 가장 영향력이 큰 사례입니다.

더 알아볼 것

  • BEA Systems vs Oracle 분쟁 사례 — DB 연결 풀링과 JEE 표준화 다툼의 배경
  • 우발적 SOA 안티패턴을 막는 적합성 함수 패턴 정리 (현대 ESB·API 게이트웨이 환경)
  • EntityBeans와 EJB CMP/BMP의 실패 분석 — 선언형 트랜잭션이 왜 어려운가
  • 메시지 누수(data leak) 방지를 위한 통합 지점 거버넌스 패턴
  • 한국 금융 그룹사 EAI/ESB 통합 플랫폼의 변천사 (2000년대 → 2020년대)
  • DDD 컨텍스트 매핑 패턴(Shared Kernel, Anti-Corruption Layer)으로 SOA의 함정 회피
  • 마이크로서비스에서도 발생하는 “분산 모놀리스”가 SOA의 어떤 측면을 답습하는지

관련 개념

출처

  • 마크 리처즈, 닐 포드, 『소프트웨어 아키텍처 The Basics』, 17장 오케스트레이션 주도 서비스 지향 아키텍처