Medical Platform · Multi-service Backend
실패한 작업은 다시 돌리고 실시간 상담은 빠르게 반응하면서도 엉뚱한 발화를 덮지 않게 만들었습니다.
Gateway·SSO를 공유하는 의료 MSA에서 주문·재고는 실패한 후속 작업만 다시 실행하게 만들고, 실시간 상담은 발화 감지·중간 전사·확정 판단·세션 종료를 서로 다른 경계로 나눴습니다.
- Role
- 주문·재고 주도 · 실시간 상담 공동 기여
- Scope
- Async · Realtime · Domain
- Stack
- FastAPI · RabbitMQ · WebSocket
- Context
- Express Gateway · NestJS SSO
외부 연동이나 실시간 session의 실패가 핵심 병원 업무 transaction 전체를 중단시키지 않게 합니다.
Problem & constraints
왜 이 문제를 풀어야 했는가
병원 운영에는 즉시 응답해야 하는 업무, 실패 후 재처리가 필요한 작업, 연결 상태가 계속 변하는 실시간 session이 동시에 존재했습니다.
모든 workload를 같은 runtime과 transaction에 묶지 않으면서도 인증·지점·권한 context는 service 사이에서 일관되게 전달해야 했습니다.
Failure boundary
실패하면 어디에서 멈추고, 어떻게 복구하는가
Decisions
핵심 기술 판단
Service Boundary
공통 Gateway·SSO와 product backend를 분리하고, 각 service가 자신의 업무 상태를 소유하게 했습니다.
Async Runtime
async FastAPI 실행 모델에 맞춰 Celery 처리를 TaskIQ·RabbitMQ로 전환했습니다.
Realtime Signals
realtime STT가 내보내는 VAD·DELTA·COMPLETE를 분기해, DELTA는 도메인 키워드 기반의 빠른 조언에, COMPLETE는 문맥 판단과 저장에 사용했습니다.
Realtime Lifecycle
session 생성·유지·종료와 provider adapter를 분리하고, 종료 뒤 남은 reconnect timer가 세션을 다시 살리지 않도록 stop guard와 GC 경계를 보강했습니다.
System flow
판단을 실제 시스템으로 옮긴 구조
API Gateway · SSO
공통 진입점과 인증 context 전달
FastAPI product services
예약·주문·재고·병원 운영의 업무 상태 소유
RabbitMQ · TaskIQ
실패 가능한 외부 작업의 상태·retry·재처리
WebSocket runtime
상담 session과 STT/LLM provider lifecycle
Evidence
운영에서 확인한 결과
API·worker flow·retry boundary
4분 37초 replay의 DELTA / COMPLETE / ADVICE · seq 1—25 무결성
reconnect race 8개 · GC TTL 5개
WER·CER·용어 보존율·latency 비교 환경
무음 200·350·500ms 비교 · 모델 추론 약 80%
재고 연동·multi-service session policy