ArchyntArchynt.api
블로그로 돌아가기아키텍처

당신에게 거짓말을 하는 의존성 엣지

누군가 프로덕션 시스템을 그린 다이어그램은, 그것을 그린 순간부터 이미 낡기 시작합니다 — 누군가 다이어그램을 갱신하지 않은 채 배포하는 순간부터요. 우리는 이를 이렇게 탐지합니다.

2026년 7월 1일 · 7분 읽기

플랫폼 팀에게 아키텍처 다이어그램을 요청하면 둘 중 하나를 받게 됩니다: "마지막 수정 14개월 전"이라는 도장이 찍힌 Confluence 페이지, 아니면 어깨를 으쓱하며 시작되는 Slack 스레드 — 결제 서비스가 아직도 재고 서비스를 직접 호출하는지, 아니면 아무도 끝까지 문서화하지 못한 3분기 마이그레이션에서 이벤트 버스를 거치게 됐는지를 두고 세 명이 논쟁하는 그런 스레드입니다. 두 답 모두 맞습니다 — 어느 정도 규모를 넘어선 대부분의 팀에서 실제로 벌어지는 일이라는 점에서요.

다이어그램이 틀린 건 누군가 게을러서가 아닙니다. 다이어그램은 누군가 그것을 그린 순간에 시스템에 대해 내린 주장이 그대로 얼어붙은 것이고, 시스템은 그 이후로도 계속 배포되기 때문입니다. 제거하지 않은 모든 의존성, 마감에 쫓겨 추가하고 나중에 정리하려 했던 모든 새 호출, 프로덕션에서만 발동하는 모든 폴백 경로 — 이 모든 건 누군가 다시 돌아가 다이어그램을 고쳐 그리지 않는 한 박스-화살표 다이어그램에 나타나지 않습니다. 그리고 아무도 다시 그리지 않습니다. 문서화된 시스템과 실제로 운영되는 시스템 사이의 이 간극이 바로 저희가 말하는 아키텍처 드리프트이며, 이는 가설이 아닙니다 — 한 명 이상의 엔지니어가 손을 댈 만큼 오래된 시스템이라면 어디서나 나타나는 기본 상태입니다.

두 개의 진실의 원천, 어느 쪽도 그 자체로는 충분하지 않다

정적 분석은 작성된 코드를 읽습니다: 소스를 파싱하고, import를 해석하고, HTTP 클라이언트와 Kafka 리스너를 따라가면 코드상으로 무엇이 무엇을 호출해야 하는지에 대한 그래프를 얻을 수 있습니다. 정확하고 계산 비용도 낮지만, 소스에 존재하는 경로만 알 수 있습니다 — 8개월째 100%로 켜져 있으면서 옛 분기 코드가 한 번도 삭제되지 않은 기능 플래그는 순수한 정적 분석 관점에서는 여전히 "사용 중"으로 보이고, 리플렉션이나 동적으로 조합된 URL을 통해서만 발생하는 호출은 아예 나타나지 않을 수도 있습니다.

런타임 관찰은 정반대입니다. 실제 트래픽을 관찰하면 — 어떤 포트가 어떤 컨테이너와 통신했는지, 얼마나 자주, 얼마나 빠르게 — 해석이 필요 없이 지금 이 순간 실제로 일어나는 일을 정확히 알 수 있습니다. 하지만 런타임 데이터는 의도에 대한 기억이 없습니다. 어떤 호출이 설계된 것인지 아무도 감히 제거하지 못하는 잔재인지 구분할 수 없고, 트래픽 샘플이 하루에 한 번 도는 야간 배치 작업을 놓치면 그 의존성은 보이지 않게 됩니다.

어느 쪽도 정확히 거짓말을 하는 건 아닙니다. 둘 다 서로 다른 질문에 대한 진실을 말하고 있을 뿐입니다.

모든 엣지에 태그를 다는 것이 실제로 주는 가치

유용한 접근은 둘 중 하나를 고르는 게 아니라, 둘 다 유지하면서 레이블 없는 하나의 사실로 뭉뚱그리기를 거부하는 것입니다. Archynt 그래프의 모든 의존성 엣지는 출처를 함께 가지고 있습니다: static(소스에서 발견됐지만 실제로 관찰된 적 없음), runtime(트래픽에서 관찰됐지만 어디에도 쓰여 있지 않음), 또는 both. 세 번째 상태인 confirmed_by: both만이 진짜 확신을 가지고 행동할 수 있는 상태입니다 — 코드와 실제 통신이 일치한다는 뜻이니까요.

흥미로운 발견은 나머지 두 상태에 있습니다. 몇 주째 런타임 트래픽이 없는 static 전용 엣지는 데드 코드 후보입니다 — 아마 삭제해도 될 의존성이고, 이제는 추측이 아니라 근거를 가지고 판단할 수 있습니다. runtime 전용 엣지는 정반대이며, 저희 경험상 더 시급한 쪽입니다: 아무도 기록해두지 않은 살아있는 의존성이라는 뜻이고, 그건 아무도 그것을 소유하지 않고, 아무도 그것에 대해 알림을 받지 않으며, 호출하는 서비스를 다음에 건드리는 사람은 그것이 무너뜨리기 전까지는 자신이 핵심 구조물을 건드리고 있는지조차 모른다는 뜻입니다.

이건 문서화의 문제가 아니라 리스크의 문제인 이유

드리프트를 "문서를 최신 상태로 유지하자"는 항목으로 분류하고 싶은 유혹이 있지만, 바로 그 이유 때문에 대부분의 팀이 이 문제를 절대 고치지 못합니다 — 문서 부채는 티켓과 마감이 있는 다른 모든 일에 우선순위 회의에서 항상 밀립니다. 더 솔직한 관점은, 주인 없는 런타임 의존성이 동시에 모니터링되지 않는 공격 표면이자 계획에 없던 단일 장애점이라는 것입니다. 존재하는지조차 모르는 연결을 위해 대기 중인 온콜 담당자는 없습니다. 저희가 지금 앞세우는 논리가 바로 이것입니다 — 로드맵 검토 회의에서도 살아남는 유일한 논리이기 때문입니다.

직접 시스템에서 확인해보고 싶으신가요?

정적 그래프에는 리포지토리 URL 하나면 충분합니다. 런타임 에이전트는 docker-compose 파일 하나만 있으면 됩니다.