Skip to content

02. Architecture

목적

APMX를 구성하는 컴포넌트와 각 컴포넌트의 책임 범위, 그리고 컴포넌트 간 통신 방식을 정의한다.

범위

  • Java Agent, Collector, Storage, REST API, Console 각각의 책임
  • 컴포넌트 간 데이터 흐름
  • 장애 격리 원칙 (Agent 장애가 애플리케이션에 영향을 주지 않는 구조)

설계

컴포넌트 책임

  • Java Agent: -javaagent로 대상 애플리케이션에 주입되어 HTTP 요청 단위 Trace를 생성하고, 비동기로 Collector에 전송한다. 애플리케이션 안정성이 최우선이며, 어떤 상황에서도 예외를 애플리케이션 스레드로 던지지 않는다.
  • Collector: Agent로부터 Trace를 수신(HTTP ingest API), 검증 후 Storage에 저장한다. 통계/분석 로직은 포함하지 않는다.
  • Storage: Trace 데이터를 저장한다. MVP는 H2(파일 모드)를 기본으로 하되, Repository/Adapter 구조로 분리되어 있어 PostgreSQL 등으로 교체 가능하다.
  • REST API: Collector 프로세스 안에 함께 배포된다(MVP 기준 별도 프로세스 분리 없음). 서비스 목록/통계/Trace 조회 API를 제공한다.
  • Console: 조회 API 결과를 시각화하고 계정 관리 등 일부 쓰기 작업도 수행하는 화면 (React + TypeScript + Vite, console 모듈). MVP에서는 Collector와 별도의 독립 dev 서버로만 실행하며, REST API를 CORS로 직접 호출한다 (docs/08-console-design.md 참고).
  • common: Agent와 대상 애플리케이션이 함께 컴파일 시점에 참조하는 극히 가벼운 모듈. 현재는 메서드 호출 스택(Span) 계측 대상을 표시하는 @ApmxTrace 어노테이션만 담고 있다 (docs/04-agent-design.md "메서드 호출 스택(Span) 계측" 참고).

프로세스 배치 (MVP)

text
┌─────────────────────┐        ┌───────────────────────────────┐        ┌──────────────┐
│  Target Application  │        │           Collector            │        │  Console      │
│  (example-app 등)     │        │  (Spring Boot 단일 프로세스)     │        │  (Vite dev     │
│                      │        │                                 │        │   서버, MVP)   │
│  ┌────────────────┐  │  HTTP  │  ┌───────────┐   ┌────────────┐ │  HTTP  │              │
│  │  apmx Agent     │──┼───────▶│  │ Ingest API│──▶│  Storage   │ │◀───────┼──  fetch      │
│  │ (javaagent)     │  │        │  └───────────┘   │ (H2/PG)    │ │ (CORS) │  (GET only)   │
│  └────────────────┘  │        │  ┌───────────┐   └────────────┘ │        │              │
│                      │        │  │ Query API │◀───────┘         │        │              │
└─────────────────────┘        │  └───────────┘                  │        └──────────────┘
                                └───────────────────────────────┘

MVP에서는 REST API를 Collector와 같은 Spring Boot 프로세스에 함께 둔다. AGENTS.md의 "불필요한 마이크로서비스 분리 금지" 원칙에 따른 결정이며, 트래픽이 늘어나면 이후 별도 프로세스로 분리할 수 있도록 ingest 관련 코드(io.apmx.collector.ingest)와 조회 관련 코드 (io.apmx.collector.query)를 패키지 단위로 분리해 두었다.

장애 격리 원칙

  • Collector가 죽어도 애플리케이션 요청은 영향받지 않는다 (Agent가 별도 스레드에서 전송).
  • Agent 내부 큐가 가득 차면 새 Trace를 버린다 (드롭 정책, 애플리케이션 스레드는 절대 블로킹하지 않음).
  • Agent 초기화(premain) 자체가 실패해도 애플리케이션 구동에는 영향을 주지 않는다.

예시

실제 검증한 시나리오: Collector 프로세스를 강제 종료한 상태에서 대상 애플리케이션에 요청을 보내면 정상적으로 응답한다 (요청 처리 시간에 변화 없음). 자세한 내용은 docs/04-agent-design.md의 "장애 격리 검증" 참고.

TODO

  • Collector를 ingest/query 두 개의 배포 단위로 분리하는 옵션 검토
  • Console 정적 빌드 결과물을 Collector(또는 별도 정적 호스팅)에 배포하는 옵션 검토 (현재는 독립 dev 서버로만 실행)
  • Python/Node Agent를 위한 공통 ingest 프로토콜 문서화