효율적인 MSA 통합: Adapter 서비스 아키텍처
1. 프로젝트 배경 및 기술 선택
Adapter 서비스는 외부 의료 정보 시스템과 내부 마이크로서비스(계정, 문진, 이미지 시스템 등) 간의 복잡한 통신을 중개하는 서비스입니다. 다수의 외부/내부 시스템이 얽힌 환경에서 데이터의 일관성을 유지하고, 보안 수준을 강화하기 위해 다음과 같은 기술 스택을 전략적으로 선택하였습니다.
- Java 21 & Spring Boot 3.5.7: 가상 스레드 지원 등 최신 런타임 효율성과 Spring 생태계의 안정성을 확보하였습니다.
- Spring Cloud 2025.0.0 (OpenFeign): 마이크로서비스 간 동기 통신을 선언적 방식으로 처리하여 가독성과 유지보수성을 높였습니다.
- OAuth2 & Keycloak: 분산 환경에서의 통합 인증(SSO) 및 인가를 위해 업계 표준인 OAuth2 프로토콜을 적용하였습니다.
2. 핵심 기술 적용 및 아키텍처 설계
2.1 도메인 중심의 멀티 모듈 및 헥사고날 아키텍처
본 시스템은 비즈니스 로직을 보호하고 기술적 의존성을 격리하기 위해 도메인 중심의 멀티 모듈 구조를 채택했습니다. 이는 헥사고날 아키텍처 사상을 반영한 것으로, 핵심 로직은 domain 모듈에 응집시키고 DB(JPA)나 외부 연동(proxy)은 어댑터화하여 교체 가능한 구조로 설계했습니다.
2.2 DB-Less 아키텍처를 통한 순수 어댑터 역할 수행
본 서비스의 가장 큰 특징은 자체 데이터베이스를 보유하지 않는(DB-Less) 설계입니다.
- 배경: 어댑터 서비스가 데이터를 직접 관리할 경우, 원본 마이크로서비스와의 데이터 동기화 이슈가 발생할 수 있습니다.
- 적용: DataSourceAutoConfiguration 등을 제외 설정하여 불필요한 리소스 낭비를 줄이고, 모든 데이터를 타 서비스의 API 호출을 통해 실시간으로 처리하도록 구현하였습니다.
2.3 OpenFeign과 Interceptor를 활용한 인증 자동화
MSA 구조에서 서비스 간 호출 시 발생하는 인증 문제를 FeignClientInterceptor로 해결하였습니다. client_credentials 방식을 사용하여 호출 시마다 토큰을 자동 주입함으로써, 비즈니스 로직이 보안 코드로부터 자유로워지도록 설계했습니다.
3. 주요 기능 구현 및 문제 해결 경험
3.1 외부 시스템 사용자 연동 프로세스 (GrantAccessFlow)
기존 병원 시스템 사용자가 신규 환자 문진 시스템에 접근할 때 발생하는 인증 격차를 해소하기 위해 Proxy 패턴을 활용했습니다.
- 가입 여부 확인: AccountLoadProxy를 통해 내부 시스템에 사용자 정보가 있는지 먼저 확인합니다.
- 자동 프로비저닝: 미가입자인 경우, 사용자가 별도 가입 절차를 거치지 않도록 인증 서버(Keycloak)와 내부 계정 시스템에 실시간으로 데이터를 동기화(자동 가입)합니다.
- 심리스한 접속: 가입 직후 즉시 토큰을 발행하여 사용자 경험(UX)의 단절 없는 시스템 전환을 구현하였습니다.
3.2 레거시 문진 템플릿의 자동 변환 (FormAction)
기존 시스템의 데이터를 신규 시스템에 이식하기 위한 데이터 파싱 로직을 구현하였습니다.
- 데이터 변환: 서로 다른 JSON 스키마 간의 호환성을 위해, 레거시 템플릿 구조를 분석하여 표준 문진 템플릿 포맷으로 변환하는 변환기(Converter)를 구축했습니다.
- 멀티미디어 처리: 문진 내 포함된 이미지를 별도의 ImageFlowProxy를 통해 이미지 서버에 선행 업로드한 뒤 반환된 ID를 매핑하는 로직을 도입하여 데이터 정결성을 확보했습니다.
4. 인프라 및 운영 효율화
4.1 Apache Kafka를 통한 최종 일관성 확보
CQRS(명령 및 조회 책임 분리) 패턴에 따라 명령 모델(CM)에서 데이터 변경(CUD) 발생 시 Kafka 이벤트를 발행하고, 이를 조회 모델(QM)에서 구독하여 데이터를 동기화합니다. 이를 통해 서비스 간 결합도를 해소하고 분산 환경에서의 최종 일관성(Eventual Consistency)을 보장하였습니다.
4.2 인프라 활용 (Redis & ShedLock)
- Redis: 분산 캐싱을 통해 공통 데이터의 조회 성능을 높였습니다.
- ShedLock: 다중 인스턴스 환경에서 스케줄러가 중복 실행되는 것을 방지하여 작업의 유일성을 확보했습니다.
4.3 Multi-Tenancy 및 CI/CD 전략
- Multi-Tenancy: 추후 도입 사이트가 늘어나는 것에 대응하기 위해, 설정과 데이터 레이어의 확장만으로 신규 사이트 대응이 가능한 유연한 아키텍처를 설계했습니다.
- Nexus 활용: 서비스 간 통신 규약을 담은 Client-Proxy 모듈을 사내 Nexus 저장소에 Publish-Subscribe하는 방식으로 배포하여 API 연동의 안정성을 높였습니다.
5. 결론 및 성과
Adapter 서비스는 단순한 API 전달자를 넘어, 복잡한 비즈니스 프로토콜을 정제하고 보안 가이드라인을 준수하여 강력한 미들웨어로서의 기능을 구현하였습니다.
- 생산성 향상: 자동화된 인증 Interceptor 및 Nexus 기반 모듈 공유로 개발 및 연동 시간을 단축했습니다.
- 확장성 확보: 헥사고날 기반의 멀티 모듈 구조를 통해 향후 타 시스템 연동 시에도 핵심 로직 수정 없이 유연하게 대응할 수 있는 기반을 마련했습니다.
본 프로젝트를 통해 얻은 MSA 환경에서의 보안 및 서비스 통합 경험은 향후 다양한 시스템 설계와 구축에 핵심적인 자산이 될 것입니다.
conley