![[코드가 환경을 모르는 구조 4/7] 타임머신 — 시간 축을 교체한다](/_next/image?url=https%3A%2F%2Fcdn.sanity.io%2Fimages%2Fv31psllp%2Fproduction%2F6a70f8e2c090762cbd4b1a9d470f573cbc0fc038-1684x1030.png%3Fauto%3Dformat%26fit%3Dmax%26w%3D1200&w=3840&q=75)
헥사고날 아키텍처로 구현한 시간 격리와 비동기 전파 전략
이 아티클은 비즈니스 로직에서 가장 다루기 까다로운 요소인 '시간'을 어떻게 교체 가능한 컴포넌트로 만들었는지 다룹니다. 시스템 시계라는 절대적인 환경 변수를 Port와 Adapter 구조로 추상화하여, 운영 환경에서도 안전하게 시뮬레이션을 수행하는 구체적인 메커니즘을 소개합니다. 단순한 구현 기술을 넘어 아키텍처 규율이 팀의 개발 문화와 검증 속도에 어떤 영향을 미치는지 보여줍니다.
시간 기반의 복잡한 정산 로직을 다루는 엔지니어나, 헥사고날 아키텍처의 실무 적용 사례를 찾고 있는 시니어 개발자에게 강력히 추천합니다.
HR SaaS에서 시간은 단순한 기록용 타임스탬프가 아니라 급여 및 연차 계산 등의 결과를 결정짓는 핵심적인 비즈니스 로직의 입력값입니다. 시스템 시계에 의존하는 구조에서는 미래 시점의 퇴직금이나 급여 시뮬레이션을 위해 실제 그 날짜가 될 때까지 기다려야 하는 테스트의 한계가 존재합니다.
모든 비즈니스 로직이 시스템 시계를 직접 호출하는 대신 'Clock' 인터페이스를 주입받아 사용하도록 규율화하고, 요청 헤더를 통해 시간 컨텍스트를 주입하는 '타임머신' 기능을 구현했습니다. ThreadLocal을 통해 요청별 시간을 격리하며, 코루틴 컨텍스트와 Kafka 메시지 헤더를 활용해 비동기 경계 너머까지 시간 정보를 일관되게 전파하는 구조를 채택했습니다.
별도의 코드 수정 없이 HTTP 헤더 하나만으로 특정 요청의 시간 축을 자유롭게 조작하여 미래나 과거 시점의 로직을 안전하게 검증할 수 있게 되었습니다. 이는 2020년부터 실무에서 신뢰할 수 있는 QA 도구 및 버그 재현 장치로 기능하며 개발 생산성을 크게 향상시켰습니다.
Trade-off
시스템 시계를 직접 호출하는 서드파티 라이브러리나 ORM의 자동 타임스탬프 기능까지는 완벽히 제어할 수 없어 시뮬레이션 시점과 실제 시점이 섞이는 미묘한 틈이 발생할 수 있습니다. 또한 Kafka 재처리 시 과거 헤더의 시간 정보가 의도치 않게 적용될 수 있어 별도의 예외 처리가 필요합니다.
시스템 시계에 직접 접근하는 대신 현재 시간을 추상화하여 제공하는 인터페이스로, 테스트나 시뮬레이션 시 임의의 시간을 주입할 수 있게 합니다.
하나의 작업 단위가 실행되는 동안 스레드나 프로세스 경계를 넘나들며 특정 상태 정보를 유지하고 전달하는 기술입니다.
애플리케이션의 핵심 비즈니스 로직을 외부 인프라나 환경으로부터 격리하기 위해 인터페이스를 사용하는 아키텍처 패턴입니다.









