면책조항. 이 글은 전적으로 Uber의 공개 커뮤니케이션 — 엔지니어링 블로그, 컨퍼런스 발표, 오픈소스 저장소, 외부 사례 연구 — 에 기반합니다. 공식 Uber 아키텍처 문서가 아닙니다. 우리는 사천 서비스의 스택이 C4 모델로 어떻게 읽기 쉽게 만들어질 수 있는지를 보여주기 위해 공개적으로 알려진 것을 모델링합니다. 디테일이 Uber에 의해 명시된 것이 아니라 추론된 경우, 이를 명시합니다.

라이드의 해부학: Archyl로 Uber를 C4로 모델링하기

비 오는 금요일 맨해튼에서 오후 7시 23분, 한 승객이 UberX 요청 을 누른다. 8초 후, 0.4마일 떨어진 운전자가 라이드를 수락했고, ETA가 계산되어 렌더링되었으며, 요금이 잠기고, 결제가 사전 승인되었으며, 승객과 운전자 사이에 저지연 실시간 채널이 열렸다. 그가 전화에서 눈을 떼는 동안, 차는 이미 그를 향해 움직이고 있다.

그 한 번의 탭은, 600개 이상의 도시에서 하루 3천만 번 이상 반복되며, 운전자 화면에 첫 프레임이 떨어지기 전에 수십 개의 Uber 시스템과 세 개의 외부 네트워크를 거친다.

2024년에 Uber의 스택은 약 4,000개의 마이크로서비스를 운영했고, 모바일 클라이언트에 초당 100만 요청을 훨씬 초과하는 피크를 제공했으며, 자체 클러스터 매니저 위에 컴퓨트를 스케줄링했고, 자체 MySQL 파생 스토리지 레이어에 상태를 영속화했고, 자체 육각형 그리드로 행성을 인덱싱했고, 자체 상태 머신 엔진에서 수백만 트립 워크플로우를 오케스트레이션했고, 자체 ML 플랫폼에서 ETA 모델을 훈련했다.

그렇게 많은 움직이는 부분을 가진 스택을 어떻게 이해할 것인가? Stripe와 Netflix처럼, 한 번에 이해하지 않는다 — 한 번에는 안 된다. 그것이 정확히 C4 모델이 해결하기 위해 발명된 문제다.

이 포스트에서 우리는 단일 사용자 액션 — 탭부터 운전자 수락까지의 라이드 요청 — 을 따라가며, 4개의 C4 레벨에 걸쳐 Uber의 아키텍처를 통과하는 것을 본다. 모든 제품을 다루지는 않을 것이다; 하나의 라이드를 추적하고, 그 길에서 만나는 선택을 설명하는 ADR을 작성하며, 각 박스를 소유한 팀의 지도로 끝낼 것이다. 그 길에서, 이런 종류의 모델 — 그리고 그 주변의 정책 — 을 실제로 유지보수 가능하게 만드는 모든 Archyl 기능을 투어할 것이다.

레벨 1 — 시스템 컨텍스트: 세 플랫폼, 하나의 마켓플레이스

Uber C4 시스템 컨텍스트: Mobility, Delivery, Freight, Marketplace

시스템 컨텍스트 레벨에서, Uber는 "차량 호출 앱"이 아니다. 공유된 Marketplace와 횡단 Foundation 시스템 스택 위에 앉은 세 개의 제품 플랫폼이다:

  1. Mobility — UberX, Uber Black, Uber Pool, Uber Reserve, Comfort, SUV, Premier, 택시 파트너십
  2. Delivery — Uber Eats(음식), Uber Direct(서드파티 delivery-as-a-service), Postmates, 주류, 식료품
  3. Freight — 장거리 트럭 운송, Uber Freight Loadbuilder, 브로커 도구

그 아래, Marketplace 플랫폼이 실제 두뇌다 — 매칭 엔진, 디스패치 옵티마이저, 동적 가격 시스템, 수요/공급 예측기. Marketplace는 라이드 요청을 라이드로 만드는 것이다.

그 아래에 Foundation 플랫폼이 앉는다: Maps(라우팅, ETA, 거리/시간 매트릭스, 트래픽), Payments, Identity & Risk, Communications(푸시, SMS, 인앱 메시징), Notifications, ML 플랫폼(Michelangelo), Workflow 엔진(Cadence/Temporal), Storage 플랫폼(Schemaless, Docstore, Cassandra, RocksDB 기반 스토어), Streaming 플랫폼(Kafka, uReplicator, Flink), Observability 스택(M3 메트릭, Jaeger 트레이싱, ELK 로그), Compute 플랫폼(역사적으로 Mesos + Aurora → Peloton → 오늘날 Kubernetes 기반).

그들 주위에는 외부 행위자: 승객, 운전자, eaters, 배달원, 상인, shipperscarriers, 지도 제공자(자체 + 폴백용 서드파티), 결제 네트워크인수 은행, 신원 확인 제공자, SMS와 음성을 위한 통신 사업자, 클라우드 제공자(Uber는 하이브리드로 운영: 자체 데이터 센터 + 특정 워크로드용 AWS/GCP), 도시 수준의 규제기관.

세 개의 제품 플랫폼. 하나의 Marketplace. 열 개의 Foundation 플랫폼. 나머지는 모두 디테일이다.

이것이 레벨 1의 선물이다: 시스템 컨텍스트에서, Mobility가 200개의 마이크로서비스라는 것을 알 필요가 없다. 그것이 존재한다는 것, Marketplace와 대화한다는 것, Marketplace가 Maps와 대화한다는 것, 그리고 Cadence가 그 아래에서 긴 트립 워크플로우를 오케스트레이션한다는 것을 알아야 한다. 다이어그램은 대화의 출발점이지 인벤토리가 아니다.

Archyl 기능. Archyl의 시스템 컨텍스트 다이어그램은 자동 레이아웃, 컨테이너로의 클릭스루 탐색, 부분집합을 음소거/강조할 수 있는 오버레이(예: "Foundation 플랫폼만 표시")가 있는 단일 C4 레벨 1 뷰다. 외부 행위자는 자체 타입을 가진 일급 C4 요소이므로 구별되게 렌더링된다.

ADR-001 · 지리공간 인덱싱을 위한 H3 육각형 그리드

상태 · 수락(2018, 오픈소스화; 2026년에도 여전히 활성)

컨텍스트 · Marketplace의 매칭 엔진은 도시 규모의 동시성에서 밀리초 단위로 "어떤 운전자가 이 승객 근처에 있는가?"에 답하면서, 동시에 surge 존, ETA, 공급 예측 같은 분석을 지원해야 한다. 고전적인 옵션은 직사각형 타일링(Z-order, geohash, Google의 S2 셀)이었지만, 직사각형은 이 도메인에 대한 근본적인 결함이 있다: 각 직사각형은 둘 이상의 이웃 거리를 가진다 — 모서리는 가장자리보다 멀어 불균등한 거리 근사와 비대칭적인 "근처에 무엇이 있는가" 쿼리를 생성한다.

결정 · 대신 행성을 육각형으로 타일링한다. 대륙 규모에서 ~1m²까지 16가지 해상도를 가진 계층적 육각형 그리드(H3)를 구축한다. 각 육각형은 6개의 등거리 이웃을 가져, 최근접 이웃과 링 쿼리를 대칭적이고 빠르게 만든다. 파트너와 Uber 엔지니어가 같은 그리드를 공유하도록 라이브러리를 오픈소스화한다.

결과 · H3는 Marketplace, Maps, ETA, surge, 분석 전반에 걸쳐 Uber의 공간 프리미티브가 되었다. 같은 H3Index가 디스패치 핫 패스와 오프라인 예측 작업에 사용된다. Foursquare, DoorDash, AT&T, 무수한 지오 스타트업이 사용하는 Uber의 가장 성공적인 오픈소스 프로젝트 중 하나이기도 하다. 육각형이 깨끗하게 타일링되지 않는 몇 안 되는 경우(이십면체의 12개 오각형 앵커)는 문서화되어 프로덕션 코드에서 회피된다.

Archyl에서 ADR이 자리를 얻는 방법: 경계가 왜 그렇게 보이는지를 설명한다. 지리공간 상태에 닿는 컨테이너를 클릭하면 H3 ADR은 한 번의 클릭 거리에 있다.

Archyl 기능. Archyl의 ADR은 특정 C4 요소에 연결된 일급 레코드다. 관련 박스에 카드로 나타나며, 상태(proposed, accepted, deprecated, superseded)로 필터링 가능하고, 코드와 함께 살도록 git에 YAML로 전송된다. 누군가 2030년에 H3를 대체하려고 제안할 때, 기존 ADR이 자동으로 관련 컨텍스트로 표시된다.

레벨 2 — 컨테이너: Marketplace의 디스패치 경로 확대

Uber C4 컨테이너: Marketplace 디스패치 내부

승객의 탭은 API 엣지에 도달한다. 박스를 열어보자.

디스패치 경로는 다음과 비슷한 컨테이너를 거친다:

  • Edge 게이트웨이 — 역사적으로 TChannel + Thrift IDL, 오늘날 모바일 클라이언트용 gRPC + HTTP/2 엣지. 인증, 속도 제한, 요청 셰이핑, 라우팅을 한다.
  • Trip 오케스트레이터 — 장기 실행 Cadence/Temporal 워크플로우로 실행. 트립은 결정론적 상태 전이를 가진 워크플로우 인스턴스다: requested → matched → arriving → on-trip → completed. 멱등 재시도와 타이머 기반 에스컬레이션은 빌트인 프리미티브이며, 비스포크 코드가 아니다.
  • 매칭 엔진(DISCO) — 실제 마켓플레이스 옵티마이저. 승객 요청과 몇 개의 H3 링 거리 내의 라이브 운전자 공급이 주어지면, 매 틱마다 제약 할당 문제를 해결한다.
  • 동적 가격 서비스 — 실시간 공급/수요 신호를 결합하여 H3 셀당 surge 승수를 계산한다. 요청 시점에 잠기는 요금 견적을 출력한다.
  • ETA 서비스 — 경로, 트래픽, 도착 예측을 위해 Maps + ML 모델을 공급한다. Uber의 ETA 모델은 2018년경 딥러닝으로 이동했고 이후 매년 정제되었다.
  • Maps 플랫폼 — Uber의 자체 라우팅 엔진, 거리 매트릭스 서비스, 트래픽 인제스트 파이프라인. 일부 시장에서 외부 지도 제공자로 폴백한다.
  • Driver state 서비스 — 각 운전자의 현재 상태(오프라인, 온라인, 트립 중), 위치, 수락 행동을 추적한다. 커스텀 지오 스토어를 통해 핫 패스 위치 데이터에 대한 읽기/쓰기.
  • Schemaless / Docstore — Uber의 MySQL 기반 샤드 스토리지. Schemaless는 오래된 것; Docstore는 더 새롭고, 멀티 리전, 트랜잭셔널한 후계자다. 트립 상태, 결제, 사용자 프로필, 대부분의 라인 오브 비즈니스 데이터가 여기 산다.
  • Kafka 클러스터 — 모든 상태 전이는 이벤트를 발행한다. Marketplace는 분석을 위해 구독; 다운스트림 서비스는 팬아웃(알림, 사기, 회계)을 위해 구독.
  • 실시간 채널 — 매치되면, 위치 업데이트와 채팅을 위한 승객과 운전자 앱 사이의 저지연 양방향 채널. 아래에 long-poll/WebSocket 게이트웨이와 Kafka로 뒷받침된다.

이 레벨의 기술 스택: Go가 대부분의 새로운 고처리량 서비스, Java가 오래된 마켓플레이스 코드, Python이 ML 파이프라인과 ops 스크립트, Node.js가 일부 엣지 레이어, gRPC가 현대 RPC 프로토콜(TChannel/Thrift이 전임자), CassandraRedis가 핫 패스 지연 시간, MySQL이 Schemaless/Docstore 아래, Hadoop/HDFS/Hive/Presto가 데이터 웨어하우스, Spark/Flink가 배치 및 스트리밍 컴퓨트.

전형적인 라이드 요청은 Edge 게이트웨이 → Trip 오케스트레이터(Cadence) → 매칭 엔진(Driver state에 대한 H3 링 쿼리를 가진 DISCO) → 동적 가격 → ETA → 알림 팬아웃(운전자에게 푸시) → driver-accept 콜백 → 실시간 채널 설정에 닿는다. 그 모든 것이, 재시도와 함께, Jaeger를 통해 엔드투엔드로 계측되고 M3을 통해 측정된다.

Archyl 기능. 컨테이너 레벨 다이어그램은 각 컨테이너, 그 타입(api / service / database / message_queue / cache / worker / gateway / library / infrastructure), 그 기술(조직별 기술 카탈로그에서 가져옴), 라벨이 있는 관계를 보여준다. API 컨트랙트는 어떤 컨테이너에든 첨부되어 인라인으로 렌더링될 수 있다 — Uber는 트립 오케스트레이션을 위한 gRPC .proto를 Trip 오케스트레이터 컨테이너에 직접 연결할 것이다.

ADR-002 · Cadence(Temporal) — 워크플로우 엔진을 구축, 상태 보존 마이크로서비스를 쌓지 않는다

상태 · 수락(~2017, Cadence로 오픈소스화; Temporal로 스핀오프)

컨텍스트 · 2017년까지 Uber는 장기 실행 상태 보존 비즈니스 프로세스를 구현하는 수백 개의 마이크로서비스를 가지고 있었다 — 트립, 주문, 가입 플로우, 운전자 온보딩, 사기 검토. 각각 자체 임시 상태 머신을 타이머, 재시도, 멱등성, 복구 코드와 함께 키워왔다. 결과: 모든 팀이 분산 시스템 세금을 지불했고, 장애는 자주 재시도/타임아웃 로직의 미묘한 버그에서 왔다.

결정 · 모든 팀이 상태 머신을 발명하도록 요구하지 마라. 결정론적 재생, 영구 타이머, 자동 재시도, 시그널 처리, 워크플로우 코드가 순차적 비즈니스 로직처럼 읽히는 프로그래밍 모델을 가진 일반 워크플로우 엔진을 구축한다. Cadence로 오픈소스화한다. 트립, 가입, 사기 검토, 자금 이동 워크플로우를 몇 년에 걸쳐 거기로 마이그레이션한다.

결과 · Cadence(그리고 그 포크 Temporal, 이제 Uber 안팎에서 사용됨)는 이제 Uber의 모든 장기 실행 상태 보존 플로우의 기반이다. "트립은 워크플로우" 추상화는 비스포크 재시도 코드 수천 줄을 잘 타입된 활동 한 줌으로 압축한다. 엔진은 또한 업계에서 가장 많이 채택된 오픈소스 워크플로우 프로젝트 중 하나가 되었다. 경로 의존적 교훈: 열 팀이 같은 프리미티브를 독립적으로 재구현하고 있을 때, 그 프리미티브를 구축하라.

Archyl 기능. Cadence 같은 결정은 모델 전체에 영향을 미친다. Archyl에서 ADR은 여러 C4 요소를 동시에 연결할 수 있다 — 하나의 결정, 많은 영향받는 박스. 모델 전체에서 "workflow"를 검색하면 Cadence 컨슈머로 주석된 모든 컨테이너를 표면화한다.

레벨 3 — 컴포넌트: 매칭 엔진 내부

Uber C4 컴포넌트: DISCO 매칭 엔진

Uber 스택의 모든 컴포넌트 중에서 매칭 엔진 — 내부적으로 DISCO — 이 컨퍼런스 발표와 엔지니어링 포스트에서 가장 잘 문서화되어 있다.

단일 라이드 요청은 매칭 엔진에 도달하면 다음 컴포넌트를 거친다:

  1. Request normalizer — 승객의 좌표를 여러 해상도의 H3 인덱스로 변환한다(전형적으로 핫 패스용 res 9, 링 확장용 res 6).
  2. Supply scanner — 초기 H3 링(~500m) 내의 모든 자격 있는 운전자에 대해 라이브 driver-state 인덱스를 쿼리한다. 차량 타입, 운전자 수락률, 최근 거절 행동으로 필터링한다.
  3. Ring expander — 안쪽 링에 자격 있는 운전자가 없으면, 후보 세트가 형성되거나 최대 거리 한계에 도달할 때까지 동심원 H3 링으로 바깥쪽으로 확장한다. Uber는 운전자의 가능한 경로를 예측하는 ML 기반 확장을 포함하여 이 확장 전략의 여러 반복을 발표했다.
  4. Candidate ranker — 픽업까지의 ETA, 마켓플레이스 효율(이 운전자를 이 동네에 유지하고 싶은가?), 이 승객/운전자 쌍에 대한 과거 수락 확률로 각 후보를 점수 매긴다.
  5. Assignment solver — 매칭 문제를 로컬 공급 풀에 대한 제약 최적화로 공식화한다. 솔버는 지속적으로 실행되며, 그리디 first-best-match에 커밋하지 않고 가까운 요청을 배치한다.
  6. Notification dispatcher — 매치된 후보에게 짧은 수락 창을 가진 푸시 알림을 보낸다. 수락/거절을 driver-state로 다시 기록한다.
  7. 폴백 경로 — 솔버 타임아웃 또는 자격 있는 후보가 없는 경우, 완화된 제약(더 넓은 차량 타입, 더 긴 ETA)으로 재시도하거나 surge로 에스컬레이션한다.

패턴은 보면 잔인하게 단순하다: 모든 공간 쿼리는 H3 링이다; 모든 비즈니스 결정은 점수 매겨진 후보다; 모든 매치는 로컬 그리디 결정이 아니라 글로벌 솔버 실행의 출력이다. 이 형태는 순진한 디스패치 시스템을 괴롭히는 "첫 번째 운전자가 요금을 가져간다" 안티패턴 전체 클래스를 제거한다.

이것이 컴포넌트 레벨 C4의 모습이다: "여기 코드가 있다"가 아니라, "여기에 비즈니스적으로 의미 있는 프리미티브의 사슬이 있고, 각각이 소유되고, 각각이 교체 가능하고, 각각이 측정 가능하다".

Archyl 기능. 컴포넌트 다이어그램은 컨테이너가 어떻게 구성되었는지 보여준다. 각 컴포넌트는 타입(controller / service / repository / handler / module / job / workflow / activity / entity), 파일 경로, 소유자, 기술을 가진다. 컴포넌트는 User Flow로 구성된다 — Archyl의 플로우 기능은 승객의 여정을 컴포넌트 호출의 순서 있는 시퀀스로 작성하고 단계별 다이어그램으로 렌더링할 수 있게 해준다.

ADR-003 · Schemaless와 Docstore — 스토리지 레이어를 사는 대신 소유한다

상태 · 수락(Schemaless: ~2014; Docstore: ~2020 이후)

컨텍스트 · 2014년까지 Uber의 라이드 볼륨이 단일 PostgreSQL 인스턴스를 넘어섰고, 당시의 기성품 NoSQL 옵션(Cassandra, Couchbase, MongoDB)에는 Uber가 트립과 결제 데이터에 대해 받아들이고 싶지 않은 운영상의 기벽이 있었다. 트립 상태는 강한 일관성의 멀티 리전 쓰기, 낮은 p99 지연 시간, 다운타임 제로 샤딩이 필요하다. 2014년 업계의 대답은 *"NoSQL을 골라 트레이드오프와 함께 살아라"*였다.

결정 · MySQL을 영속적인 기반으로 취급하고 그 위에 구축한다. Schemaless는 트리거 없는 추가 전용 로그, 자동 재샤딩, JSON 문서 API로 샤드된 MySQL을 감싼다. 몇 년 후 Docstore는 같은 MySQL 기반 위에 강한 일관성의 멀티 리전 트랜잭셔널 문서 스토어를 겹친다 — 그리고 새 제품 데이터의 기본이 된다.

결과 · Uber는 비슷한 규모의 여러 회사를 강타한 "NewSQL로 마이그레이션"/"Postgres로 다시 마이그레이션" 호황-불황 사이클에서 벗어나 있었다. 경로는 점진적이다: 새 워크로드는 Docstore를 받는다; 성숙한 워크로드는 마이그레이션될 때까지 Schemaless에 남는다. 둘 다 깊은 MySQL 전문성을 가진 작은 플랫폼 팀에 의해 운영된다. Uber가 Cassandra에 올인했다는 소문? 그들은 Cassandra를 사용하지만, 트립의 시스템 오브 레코드였던 적은 없다.

이 ADR은 경로 의존적 아키텍처의 훌륭한 예다: 2014년에 올바른 답은 MySQL을 확장하는 것이었지, 그것에서 마이그레이션하는 것이 아니었다.

Archyl 기능. 드리프트 감지가 여기서 가장 중요하다. 새 서비스가 "Schemaless"에 쓰기 시작하지만 C4 모델이 여전히 "PostgreSQL"이라고 말할 때, Archyl은 코드베이스에 대한 드리프트 점수를 계산하여 매주 표시한다. ADR은 다음 드리프트를 방지한다: 새 데이터스토어에 쓰는 새 팀은 변경을 제안하는 ADR을 제출해야 하고, 플랫폼 팀이 승인하거나 거부할 수 있다.

Archyl에서 렌더링된 세 개의 Uber ADR 카드

세 가지 결정. Archyl의 세 카드, 각각 그것이 형성하는 C4 요소에 연결됨 — H3는 모든 공간 컨테이너에, Cadence는 모든 장기 실행 워크플로우에, Schemaless/Docstore는 데이터 계층에. 다이어그램은 현재 시제다; ADR은 왜다.

오너십: 모델을 책임으로 바꾸기

Uber 오너십 맵: 시스템에 매핑된 팀

C4 모델은 팀을 매핑하기 전까지는 정적 아티팩트다. Uber는 엔지니어링 구조에 대해 공개적으로 소통한다: 강력한 Foundation 그룹(Storage, Compute, Networking, Observability, Security, ML Platform, Maps), Mobility, Delivery, Freight에 정렬된 제품 조직, 그리고 제품 간 경제 엔진을 소유하는 중앙 Marketplace 조직.

이것들을 C4 모델에 놓는다:

  • Marketplace는 DISCO, 동적 가격 서비스, surge, ETA 플랫폼, 수요/공급 예측기를 소유
  • Mobility Engineering은 승객 및 운전자 앱, 트립 오케스트레이터, 평가 및 팁 플로우, 안전 툴킷을 소유
  • Delivery Engineering은 Eats의 주문 오케스트레이션, 배달원 매칭(DISCO 프리미티브 재사용), 상인 도구, 메뉴/재고 플랫폼을 소유
  • Freight Engineering은 장거리 특정 워크플로우를 소유: 적재 매칭, 브로커 도구, 정산
  • Maps는 라우팅, ETA 모델, 트래픽 인제스트, H3 라이브러리를 소유
  • **ML Platform (Michelangelo)**은 모델 훈련, 피처 스토어, 온라인 서빙, ML 옵저버빌리티 스택을 소유
  • Storage Platform은 Schemaless, Docstore, Cassandra, 백업/복원 도구를 소유
  • Compute Platform은 Kubernetes 시대 클러스터 매니저와 Aurora/Peloton의 후예를 소유
  • Observability는 M3(메트릭), Jaeger(트레이싱), 로그 파이프라인을 소유
  • Security & Identity는 Risk, IAM, 시크릿 플랫폼, Marketplace와 공유되는 남용/사기 신호를 소유
  • Cadence/Workflow Platform은 모든 제품에서 사용되는 영구 워크플로우 런타임을 소유

시스템, 컨테이너, 컴포넌트가 팀 소유자를 가지면, 드리프트 감지가 책임 있게 된다. 새 서비스가 커밋에 나타나고 다이어그램에 없을 때, 특정 팀이 질문을 받는다. 컴플라이언스 규칙이 위반될 때 — "Marketplace 서비스만 surge 캐시에 쓸 수 있다" — 받은편지함에 이름이 있다.

Archyl에서 오너십 맵은 문서 도구가 거버넌스 도구가 되는 순간이다.

Archyl 기능. 모든 C4 요소는 owners.teamsowners.users를 지원한다. 오너십 맵 뷰는 커버리지를 롤업하여 아무도 소유하지 않은 박스를 볼 수 있게(그리고 고칠 수 있게) 한다. 이 크기의 어떤 시스템에서도 커버리지 격차는 받아들일 수 없다 — 그것이 온콜이 아무도 응답하지 않는 Slack 채널로 에스컬레이션되는 방식이다.

드리프트, 컴플라이언스, 4천 서비스 문제

4천 마이크로서비스를 가진 모델은 드리프트한다. 심하게. Mobility가 기능을 출시한다; 새 마이크로서비스가 나타난다; Marketplace 데이터 컨트랙트가 진화한다; 2019년 비추천 서비스가 마침내 은퇴한다. 모든 팀, 모든 분기에 걸쳐 곱하라.

Archyl은 매주 드리프트 점수를 계산한다: 문서화된 C4 모델과 현재 코드베이스에 있는 것 사이의 격차. 숫자는 0과 100 사이로 제한된다. 드리프트 점수 12는 모델에 아직 없는 6개의 새 서비스, 다이어그램에서 삭제된 엔드포인트를 가리키는 3개의 관계, 더 이상 실제 스택과 일치하지 않는 기술로 태그된 한 줌의 컨테이너를 의미할 수 있다.

컴플라이언스 규칙이 정책 레이어를 추가한다. Marketplace 조직이 작성할 수 있는 예:

  • Marketplace 서비스만 surge 캐시에서 읽을 수 있다
  • PII를 처리하는 모든 컨테이너는 pii:true 태그를 가지고 Identity ADR을 참조해야 한다
  • 모든 공개 API는 첨부된 OpenAPI 또는 gRPC 컨트랙트가 있어야 하며 — 그 컨트랙트가 구현이 아닌 진실의 원천이어야 한다
  • 모든 컨테이너는 소유 팀이 필요하다
  • 트립 상태 변경은 Cadence를 통과해야 한다; 직접 데이터베이스 쓰기는 금지
  • 새 데이터스토어는 ADR과 Storage Platform 사인오프를 요구한다

Archyl은 이 규칙을 지속적으로 평가한다. 위반은 다이어그램, 팀의 주간 다이제스트, 그리고 GitHub Action을 연결하면 커밋 시점 검사로 표면화된다.

Archyl 기능.

  • 모든 푸시에서 다시 계산되는, 모델과 코드 사이의 격차에 대한 드리프트 점수
  • YAML로 작성되어 모든 C4 요소에 적용되는 컴플라이언스 규칙
  • Architecture Change Requests — 제안된 모델 변경을 위한 풀 리퀘스트 스타일 리뷰, 아키텍처가 코드와 같은 엄격함을 따르도록
  • Architecture Insights — 드리프트 + 컴플라이언스 신호에서 AI가 표면화한 이상과 권장 사항

Uber 크기의 스택에서 이것은 선택사항이 아니다. 전용 아키텍처 문서 팀 없이 모델을 정직하게 유지하는 유일한 방법이다.

API 컨트랙트, 이벤트, 마켓플레이스의 신경계

Uber의 Marketplace는 고속으로 이벤트를 교환하는 서비스의 그래프다. 트립 상태 전이, 운전자 위치 업데이트, surge 재계산, 요금 견적, 결제 인증 — 모든 변경은 0에서 많은 다운스트림 서비스에 의해 소비되는 Kafka 이벤트를 발행한다. 대부분의 동기 서비스 간 호출은 gRPC다.

Archyl에서:

  • 모든 컨테이너는 첨부된 API 컨트랙트(HTTP/OpenAPI, gRPC, GraphQL, AsyncAPI)를 가질 수 있다. 사양은 인라인으로 렌더링된다; 컨슈머는 정확히 그들이 호출하는 것을 본다.
  • 모든 비동기 채널은 브로커(Kafka), 토픽 이름, 스키마 형식(Avro, Protobuf, JSON Schema), 스키마 본문을 가진 이벤트 채널로 모델링될 수 있다. 프로듀서와 컨슈머는 채널에 연결된다.
  • 깨는 변경은 컨트랙트의 diff로 나타난다 — 그리고 버전 범프를 요구하는 컴플라이언스 규칙이 있다면, 변경은 규칙이 충족될 때까지 차단된다.

Uber에게, 그것은 C4 모델과 같은 곳에서 검사 가능해지는 3천 토픽과 수만 컨트랙트다. 더 이상의 *"누가 내 이벤트를 소비하는가?"*는 없다 — 모델이 안다.

Marketplace 규모의 DORA

소유자가 있는 C4 요소를 가지면, 그것들을 배포 텔레메트리에 연결할 수 있다. Archyl의 DORA 모듈은 CI/CD 및 사고 시스템에서 배포 빈도, 변경 리드 타임, 변경 실패율, 평균 복구 시간을 끌어와 C4 요소별 및 팀별로 롤업한다.

Mobility의 Trip Orchestrator에 대해, 그 팀의 배포 케이던스와 안정성을 Pricing과 별도로 볼 것이다. 전체 Marketplace에 대해, 전체 플랫폼의 MTTR이 어떻게 추세를 보이는지 볼 것이다. MTTR이 급증하면, 문제 컨테이너로 드릴 다운; 배포 빈도가 정체되면, 특정 하위 트리에 귀속할 수 있다.

Archyl 기능. Archyl의 DORA 대시보드는 팀 및 요소 분석과 추세선으로 네 가지 메트릭을 렌더링하고, 사고를 영향을 미친 아키텍처 요소에 묶는다. 그것이 "우리는 옵저버빌리티가 있다"가 "우리는 엔지니어링 건강이 있다"가 되는 방식이다.

그리고 AI 계층

4,000 서비스 스택은 AI 코딩 에이전트 — Claude Code, Cursor, Windsurf, 나머지 — 의 자연 서식지다. 모든 Uber 엔지니어는 같은 문제를 가진다: "서비스 X는 서비스 Y와 어떻게 대화하고, surge 승수는 실제로 어디에 영속되는가?"

Archyl에서 모델은 MCP 서버를 통해 노출된다. 엔지니어 노트북의 어떤 AI 에이전트도 물을 수 있다:

  • "H3 라이브러리에 의존하는 모든 서비스를 나열해"
  • "dispatch.MatchService의 API 컨트랙트를 보여줘"
  • "어떤 ADR이 스토리지 결정을 다루는가?"
  • "소유 서비스 전반에서 Cadence에서 Temporal SDK v2로의 마이그레이션 계획 생성"

에이전트는 엔지니어와 같은 아키텍처 컨텍스트를 얻는다. 온보딩이 줄어든다. 팀 간 코드 리뷰가 *"이게 도대체 뭘 하는 거야?"*가 되는 것을 멈춘다. 머릿속에 살던 컨텍스트가 이제 쿼리 가능한 모델에 산다.

Archyl 기능. AI 에이전트를 위한 MCP 서버, archyl YAML, Structurizr DSL, LikeC4, IcePanel JSON, Backstage 카탈로그 형식의 임포트/익스포트 — 기존 아키텍처 데이터가 재작성 없이 흘러들어오도록. 프로젝트 문서, 사용자 플로우, 아키텍처 인사이트가 표면을 마무리한다.

이 규모 조직을 위한 전체 기능 표면

Archyl을 평가하는 Uber 형태의 엔지니어링 조직이라면, 일상에서 그것이 자기 몫을 하는 부분에 매핑된 표면이 여기 있다:

  • 네 레벨 모두를 가진 C4 모델 — 시스템 컨텍스트, 컨테이너, 컴포넌트, 코드 — 자동 레이아웃, 오버레이, 클릭스루 탐색과 함께. 모든 다이어그램 도구가 잘 하는 것; 우리는 그것을 잘 그리고 계속 한다.
  • AI 아키텍처 발견 — Archyl을 저장소에 가리키면 C4 요소를 자동으로 발견한다. 분기가 아닌 한 시간 안에 0에서 첫 모델로.
  • Architecture-as-Code — git에 체크인되고, 파싱되고, 검증된 archyl.yaml. GitHub Action을 통해 CI/CD 준비. 코드와 같은 엄격함.
  • 다중 형식 임포트 — Backstage 카탈로그(JSON), Structurizr DSL, LikeC4, IcePanel JSON, 그리고 Archyl의 네이티브 YAML.
  • 전체 라이프사이클(proposed / accepted / deprecated / superseded)로 C4 요소에 연결된 ADR.
  • 마크다운, 첨부 파일, 특정 요소 연결을 가진 프로젝트 문서 — 살아있는 아키텍처 핸드북.
  • HTTP/gRPC/GraphQL/AsyncAPI를 위한 API 컨트랙트, 생성 컨테이너에 대해 인라인으로 렌더링.
  • 브로커, 토픽, 스키마, 프로듀서, 컨슈머를 가진 이벤트 채널 — 아키텍처의 비동기 측면.
  • 릴리스 & 환경 — 아키텍처에 묶인 버전 관리된 배포, 다이어그램에 표시.
  • 모든 레벨에서 팀 및 사용자 할당을 가진 오너십 맵.
  • 모든 푸시에서 다시 계산되는, 모델과 실제 코드베이스 사이의 드리프트 점수.
  • 모델 위의 정책으로서의 컴플라이언스 규칙 — 작성, 평가, 시행.
  • 제안된 모델 변경을 위한 풀 리퀘스트 스타일 리뷰의 Architecture Change Requests.
  • AI가 표면화한 이상, 위험, 권장 사항의 Architecture Insights.
  • 추세선과 사고 귀속을 가진, 요소별 및 팀별로 롤업된 DORA 메트릭.
  • 팀의 소유 경계로 범위가 지정된 주간 팀별 요약의 Architecture Team Digest.
  • MCP 통합 — 팀의 모든 AI 코딩 에이전트가 같은 아키텍처 컨텍스트를 공유.
  • GitHub PR 리뷰 — Archyl의 리뷰 봇이 드리프트, 컴플라이언스, ADR 컨텍스트로 아키텍처에 영향을 미치는 PR에 댓글.
  • 공유 & 임베딩 — 공개 링크, 팀 전용 링크, 내부 위키용 임베드 가능한 iframe.
  • 이미지/PDF 익스포트 — 프레젠테이션, 공식 문서, 인쇄 슬라이드용 PNG, SVG, PDF.
  • 다국어 — 문서와 에이전트 프롬프트를 포함하여 9개 언어로 사용 가능한 모든 Archyl 표면.

그것이 완전한 도구 상자다. Uber 같은 스택이라면 거의 모든 것을 사용할 것이다. 50 서비스 스택이라면, 성숙도와 일치하는 절반을 사용하고 — 나머지로 성장할 것이다.

4천 서비스가 필요하지 않다

당신은 Uber가 아니다. 대부분의 엔지니어링 조직은 그렇지 않다.

그러나 교훈은 축소된다. 컨텍스트를 컨테이너에서, 컨테이너를 컴포넌트에서 분리하는 규율, 경로 의존적 결정(우리는 H3를 구축했다, 우리는 Cadence를 구축했다, 우리는 MySQL을 교체하는 대신 확장했다)을 설명하는 ADR을 작성하는 규율, 모든 박스에 오너십을 첨부하는 규율 — 그 규율이 50 서비스의 스택을 4천처럼 느끼지 않게 하는 것이다.

C4 + ADR + 오너십 + 드리프트 + 컴플라이언스 + API 컨트랙트 + DORA + MCP — 그것이 Archyl이 즉시 제공하는 것이다. Uber 예시는 마켓플레이스-그리고-물류 도메인에서 모델의 가장 큰 그럴듯한 스트레스 테스트일 뿐이다.

자신의 아키텍처를 연다. 10개의 제품을 스케치한다(3개가 있다면 3개). 가장 놀라운 과거 결정을 가진 것을 골라 그 컨테이너를 줌인한다. 신입을 당황시킬 것을 설명하는 세 개의 ADR을 작성한다. 모든 컨테이너에 팀을 매핑한다.

대부분의 엔지니어링 조직이 1년에 도달하는 곳보다 앞서 있을 것이다.


자신의 아키텍처를 C4로 모델링하고 싶은가? Archyl로 시작. 왜 ADR과 C4가 함께 더 잘 작동하는지 또는 Architecture Change Requests가 풀 리퀘스트 엄격함을 C4 모델에 가져오는 방법을 더 읽어보라. 이전 사례 연구는 Stripe를 C4로 — 결제의 해부학Netflix를 C4로 — 재생의 해부학을 모델링했다.