시작하며

힐링페이퍼(강남언니)의 미션은 ‘더 좋은 의료서비스를 누구나 누릴 수 있게’ 하는 것입니다.

강남언니 앱을 통해 고객이 좋은 병원을 찾도록 도왔지만, 정보 플랫폼인 강남언니 만으로는 고객이 병원에서 오랫동안 대기하거나 예약 변경을 위해 달력을 보며 언제 예약할 수 있는지 물어보는 등 병원을 선택한 이후 여정의 문제에 개입하기 어려웠고, 병원이 고객 접점에서 더 효율적이고 효과적인 의료 서비스 제공에 온전히 집중할 수 있도록 하기 어려웠습니다.

이러한 고민 끝에 강남언니만으로는 풀기 어려운 문제들을 해결하고자 병원 운영 전반을 책임지는 제품을 만들기로 했습니다.

고객 접점을 탁월하게 개선하고, 병원을 찾는 과정부터 예약, 내원, 고객 관리까지 모두 서포트하는 전반적인 솔루션만이 우리의 미션에 다다를 수 있다고 생각했기 때문입니다. 전통적인 방법이 아닌 더 빠르고, 더 안정적이고, 더 확장 가능하고, 더 애자일한 제품으로 만들어야지만 기존의 틀을 깨고 업계에 새로운 변화를 가져올 수 있다고 믿기에 SaaS 형태로 제공합니다.

그래서 병원운영솔루션(이하 KOS)은 다음과 같은 요건들이 필요했습니다.

  1. 보안과 안정성을 위한 구조
  2. 복잡한 도메인 로직을 빠르게 개발하고 운영할 수 있는 환경
  3. 빠르고 선택적인 개별 업데이트와 독립적 엔터프라이즈 환경

이 글에서는 KOS을 만들기위한 여정과 저희의 인프라, 아키텍처, 그리고 여러 개발적인 요소들이 왜, 어떻게 만들어졌는지 전반적으로 소개합니다.


기술적인 접근

KOS의 고객은 병원 운영자입니다. 병원 운영자가 KOS에 로그인하면 접근 가능한 병원의 목록이 보이고, 병원을 선택해 Workspace에 접속합니다. 병원 Workspace에 접속하면 다른 병원과 격리된 환경의 애플리케이션을 이용할 수 있습니다. 새로운 Workspace를 생성하면 그 즉시 환경이 준비됩니다.

KOS의 제품은 Kubernetes 환경에서 실행됩니다. 사용자 그룹의 접근 제어와 권한 관리를 위해 Kubernetes의 네임스페이스로 분리한 엔터프라이즈 환경을 구축했습니다.

아래 그림은 서비스 구성을 도식화 한 것입니다. 각 네임스페이스에는 각 엔터프라이즈에서 필요한 리소스들이 배치되어 있습니다.

Common 서비스에는 모든 테넌트가 공통적으로 사용하는 리소스가 배치되어 있습니다. 예를들어 인증 서비스나, 서비스 구성에 필요한 정보를 제공하는 메타데이터 서비스가 있습니다.

Tenant 서비스에는 각 병원별로 독립적으로 운영되는 상품 서비스나 예약 서비스가 있습니다.

이 구조를 설계할 때 중요하게 생각한 점은 다음과 같습니다.

1. 보안과 안정성

KOS를 설계할 때 가장 중요하게 생각한 점 중 하나는 보안과 안정성입니다. 병원(Tenant)마다 물리적으로 분리된 네트워크와 개별 데이터베이스를 사용하기 때문에 Tenant A에서 Tenant B의 서비스를 호출하거나 데이터베이스에 접근할 수 없습니다.

엔터프라이즈 환경을 제공받을경우 서비스들이 따로 구동되며, 그에 맞는 인프라도 엔터프라이즈에 맞게 별도로 구동이 되기 때문에 전 서비스 장애를 쉽게 피할 수 있습니다.

개발할 때도 TDD에 기반하여 진행하기 때문에 도메인 논리에 의한 버그 발생 가능성을 최소화 하고 있습니다.

2. 복잡한 도메인 로직을 빠르게 개발하고 운영할 수 있는 환경

I/O가 많은 로직, 컴퓨팅이 많은 로직, 병렬처리가 중요한 로직 등 각 로직의 특성에 맞게 기술을 선택하여 개발을 진행하고 있습니다.

이벤트 기반 구조를 이용하여 적절한 도메인 범위에 따라서 모든 로직이 HTTP 호출로 구현하지않고 상황에 맞게 비동기 이벤트 처리 방식으로 구현하기도 합니다.

또한 도메인 기반 설계와 개발을 통해서 복잡성이 큰 영역도 적절한 아키텍처와 모듈화를 가져가서 추후에 있을 변화나 확장에 유연하게 하도록 만들고 있습니다.

3. 개별 배포 지원

엔터프라이즈 환경을 제공할때 하나의 거대한 서비스를 통해서 제공하는것이 아닌, 고객이 원하는 기능을 개별적으로 제공합니다.

이 방식은 다음과 같은 장점이 있습니다.

사용하는 애플리케이션만 리소스를 점유합니다.

  • 인프라 레벨에서 애플리케이션 자체를 분기하기 때문에 인프라 리소스를 아낄 수 있습니다.

제품을 특정 고객사 대상으로 출시할 수 있습니다.

  • 코드 분기를 통해 기능을 감추지 않고 애플리케이션을 직접 배치하므로 쓰이지 않는 코드가 코드베이스에 통합되지 않습니다.

새로운 네임스페이스를 생성하고, 새로운 제품을 출시하고, 새 버전의 업데이트를 배포하는 모든 과정이 코드로 관리되며 자동화되어 있습니다.


위의 예시들을 포함하여 더 좋은 제품을 만들기 위해, 더 빠르고 효율적인 개발을 위해서 저희는 계속해서 여러가지 방법을 고민하고 시도하고 있습니다.

IDL을 사용하여 백엔드와 프론트엔드간의 소통을 획기적으로 바꿔내고, 동시 다발적으로 접속한 계정의 다양한 이벤트 발생과 실시간 데이터 변화를 체크해야하는 고객의 요구사항을 구현하기 위해 소켓통신과 이벤트 소싱 기반의 아키텍쳐를 만들고, 복잡하고 거대한 프로젝트를 운영하는 어려움을 해결하고자 마이크로프론트엔드 구조를 적용하기도 하고, 누구나 편하고 빠르고 다른 시스템에 영향없는 배포를 할 수 있도록 자체적인 배포시스템을 만들었습니다.

그리고 이러한 고객의 문제와 우리의 장기적인 운영과 개발적 문제를 해결해나가는 과정들을 하나씩 정리해서 공유해보려고 합니다.

그동안 쉽게 바뀌지 않던 영역을 변화시켜보고자 하는 저희의 험난한 여정이 어떻게 진행될지 지금은 아무도 모를 겁니다. 하지만 미션과 비전을 가진채로 꾸준히 포기하지않고 도전해보려하니 많은 응원을 부탁드립니다.

감사합니다.

SaaS 시리즈
프론트엔드
Micro Frontends를 위해 Module Federation 적용하기
[TBA] 복잡한 웹 애플리케이션을 위해 복잡하지 않은 구조 만들기
[TBA] TDD로 개발하기
백엔드
Private AWS EKS Cluster With Github Actions Enterprise 환경으로 확장하기 쉬운 Multi-Tenancy 서비스 구축하기 시간여행이 가능한 시스템 아키텍처
[TBA] Enterprise 서비스 비밀 정보 관리하기
[TBA] SaaS 서비스 이벤트 소싱하기
[TBA] TDD로 개발하기
Brown
Head of Solution Biz. & CCO
강남언니팀을 더 멋지게, 더 즐겁게 일할 수 있도록 만드는 일을 하고 있습니다. 마치 매일 새로운 회사를 다니는듯 하게 만드는 것이 꿈입니다.