작업 의존성 매핑

도미노가 쓰러지기 전에 막는 법

by 전규현 Raymond
015-6-task-dependency-mapping.png


"로그인 기능 하나 수정했을 뿐인데요..."

단순한 로그인 UI 개선이었습니다. 버튼 색깔을 바꾸고 레이아웃을 조금 수정했을 뿐인데, 72시간 후 결제 시스템 전체가 마비됐습니다. 서비스는 3일간 중단됐고, 손실액은 50억 원을 넘었습니다.

사후 분석 결과는 충격적이었습니다. 로그인 모듈에서 세션 관리자로, 세션 관리자에서 인증 서버로, 인증 서버에서 결제 보안 모듈로 이렇게 깊은 연쇄 관계를 아무도 완전히 파악하지 못했던 겁니다. 처음엔 간단해 보였던 변경이었는데, 막상 진행하니 예상치 못한 곳에서 문제가 발생했습니다. "왜 여기까지 영향을 주지?" 하며 당황했습니다.

MIT 연구에 따르면, 소프트웨어 프로젝트 실패의 38%가 의존성 관리 실패 때문입니다. 더 놀라운 건, 개발자의 67%가 자신이 작업하는 코드의 의존성을 절반 이상 모른다는 사실입니다. 우리는 보이지 않는 거미줄 위에서 춤을 추고 있는 셈이죠.

의존성이 보이지 않는 이유

암묵적 의존성의 함정이 있습니다. "이 버튼 색깔 바꾸는데 왜 백엔드 팀 승인이 필요하죠?" 신입 디자이너의 당연한 질문입니다. 그런데 그 버튼은 A/B 테스트 시스템과 연결되어 있고, 분석 대시보드에 영향을 주며, 머신러닝 추천 엔진의 입력값이었습니다. 코드에는 import 문으로 명시적 의존성이 보이지만, 비즈니스 로직의 의존성은 보이지 않습니다.

의존성의 전이성도 문제입니다. A가 B에 의존하고, B가 C에 의존하면, A는 C에도 의존합니다. 간단한 수학이지만, 실제 프로젝트에서는 이런 전이적 의존성이 수십 단계를 거치며 복잡하게 얽힙니다. 한 연구에 따르면, 평균적인 엔터프라이즈 시스템은 7단계 이상의 의존성 체인을 가지고 있습니다.

순환 의존성의 악몽도 있습니다. A에서 B로, B에서 C로, C에서 A로 돌아오는 순환 구조가 생기면 어디서부터 시작해야 할지 알 수 없습니다. 하나를 수정하면 모든 것을 수정해야 하는 상황이 됩니다.

의존성을 가시화하는 방법

의존성 그래프를 그리면 시각화만으로도 절반은 해결됩니다. 프론트엔드 UI에서 인증 모듈로, 인증 모듈에서 세션 관리로, 세션 관리에서 캐시로, 인증 모듈에서 API 게이트웨이로, API 게이트웨이에서 데이터베이스와 캐시로 연결되는 복잡한 관계가 한눈에 들어오기 시작합니다.

의존성 매트릭스를 작성하면 체크 표시가 많은 행은 많은 것에 의존하고 있어 취약하고, 체크 표시가 많은 열은 많은 것이 의존하고 있어 중요합니다.

크리티컬 패스를 식별하면 의존성 체인에서 가장 긴 경로를 찾을 수 있습니다. 로그인에서 인증으로 2일, 인증에서 세션으로 3일, 세션에서 권한 체크로 1일, 권한 체크에서 API 호출로 2일, API 호출에서 DB 조회로 4일, DB 조회에서 응답으로 2일, 응답으로 1일이면 총 15일입니다. 이 경로의 어느 하나라도 지연되면 전체가 지연됩니다.

의존성 관리 전략

의존성 역전 원칙(DIP)은 고수준 모듈이 저수준 모듈에 직접 의존하지 않도록 합니다. 직접 의존 대신 인터페이스를 통한 의존을 사용하면 결합도가 낮아집니다.

의존성 주입(DI)은 의존성을 외부에서 주입받아 결합도를 낮춥니다. 테스트 시에는 목(Mock) 객체를 주입하여 격리된 테스트가 가능합니다.

레이어 분리는 의존성이 한 방향으로만 흐르도록 합니다. Presentation Layer(UI)에서 Application Layer(비즈니스 로직)로, Application Layer에서 Domain Layer(핵심 로직)로, Domain Layer에서 Infrastructure Layer(DB, 외부 서비스)로 흐릅니다. 상위 레이어는 하위 레이어에만 의존하고, 역방향 의존은 금지합니다.

의존성 리스크 관리

영향도 분석으로 각 모듈의 의존성 영향도를 점수화합니다. 직접 의존, 간접 의존, 피의존도를 합산하여 리스크 점수를 계산합니다. 리스크 점수가 높은 모듈은 변경 시 주의가 필요합니다.

의존성 차단점 설정으로 도미노 효과를 막습니다. Circuit Breaker 패턴을 사용하여 실패가 일정 횟수 이상 발생하면 자동으로 차단하고 대체 응답을 반환합니다.

의존성 모니터링으로 실시간으로 의존성 상태를 모니터링합니다. 데이터베이스, 캐시, 외부 API의 헬스체크를 주기적으로 수행하여 문제를 조기에 발견합니다.

실전 의존성 관리 도구

코드 레벨 분석으로는 Madge(JavaScript)로 순환 의존성을 탐지하고, Dependency Cruiser로 의존성 규칙을 검증하고, JDepend(Java)로 패키지 의존성을 분석합니다. 아키텍처 레벨 분석으로는 Structure101로 아키텍처 복잡도를 시각화하고, Lattix로 의존성 매트릭스를 관리하고, SonarQube로 기술 부채를 추적합니다. 런타임 분석으로는 Jaeger로 분산 추적을 하고, Zipkin으로 서비스 간 의존성을 매핑하고, AppDynamics로 애플리케이션 토폴로지를 확인합니다.

의존성 리팩토링 전략

1단계로 현황을 파악하여 모든 의존성을 문서화하고 시각화합니다. 2단계로 문제를 식별하여 순환 의존성, 과도한 의존(Fan-out > 5), 과도한 피의존(Fan-in > 7)을 찾습니다. 3단계로 점진적 개선을 하여 한 번에 모든 것을 바꾸지 말고, 가장 위험한 부분부터 하나씩 개선합니다. 4단계로 자동화하여 CI/CD 파이프라인에 의존성 검증을 추가합니다.

핵심 정리

"측정할 수 없으면 관리할 수 없다" - 피터 드러커

의존성도 마찬가지입니다. 보이지 않으면 관리할 수 없고, 관리하지 않으면 언젠가 폭발합니다. 작은 변경이 시스템 전체를 마비시키는 도미노 효과를 막으려면, 의존성을 가시화하고 관리해야 합니다. 복잡해 보이지만, 한 번 체계를 잡아놓으면 프로젝트의 안정성이 크게 향상됩니다.

기억하세요. 모든 것은 연결되어 있습니다. 그 연결을 이해하고 관리하는 것이 현대 소프트웨어 개발의 핵심입니다. 다음 프로젝트부터 의존성을 시각화하는 것부터 시작해보세요. 작은 노력이 큰 차이를 만듭니다.

복잡한 프로젝트 의존성을 체계적으로 관리하고 싶으신가요? Plexo를 확인해보세요.

keyword
작가의 이전글양자 컴퓨팅으로 프로젝트 최적화하기