Skip to content

프로젝트 중점 사항

Hyung1Jung edited this page Feb 23, 2022 · 6 revisions

MSA 구조로 설계함으로써 타 서비스와 관계 없이 독립적인 개발, 배포 및 장애 대응

실제 기업에서 여러 팀들이 각기 다른 서비스를 개발한다고 가정했을 때, Monolitic 구조는 전체 시스템이 한 프로젝트로 구성이 되기 때문에 유지보수 비용, 개발 생산성, 커뮤니케이션 비용 등이 많이 증가할 것이라고 생각했습니다.

따라서, 위의 문제를 해결하기 위해 서비스를 MSA 구조로 설계를 하였습니다. 이는 기능 중심의 자율적인 개발, 독립적인 배포, 하나의 서비스에서 발생하는 장애가 전체 시스템 장애로 확장되지 않는 등 여러 이점이 있었고, 이를 통해 위의 문제를 해결 할 수 있었습니다.

Hexagonal Architecture로 도메인 주도 설계를 함으로써 순수한 도메인의 모델과 로직에 집중

기존의 계층형 아키텍쳐는 도메인이 인프라에 의존하게 되면서 도메인 적인 관심사와 기술적인 관심사가 섞이는 경우가 많았습니다.

이를 해결하기 위해 비즈니스 영역을 표현하는 내부 영역과 인터페이스 처리를 담당하는 외부 영역으로 나누어 설계하는 핵사고널 아키텍쳐로 도메인 주도 설계를 진행하였습니다. 비즈니스 영역을 표현하는 내부 영역과 인터페이스 처리를 담당하는 외부 영역으로 분리함으로써, 비즈니스 로직이 표현 로직이나 데이터 접근 로직에 의존하지 않게 되면서 도메인 주도 설계에 많은 도움이 되었습니다.

Single Sign-on 방식을 제공하는 Identity provider 서비스를 구현하여 로그인/인증 과정 통합

로그인/인증 기능 개발 시, 각각 프로세스마다 각각 로그인 관련된 프로세스를 구현하게 되면 개발 생산성이나 유지보수성이 많이 떨어지게 됩니다. 이 문제를 해결하기 위해 로그인/인증 서비스를 따로 두고, 이 서비스에서 로그인/인증과 관련된 부분을 통합 하였습니다. 그 결과, 로그인/인증 서비스에서 로그인 한 번으로 여러 서비스를 이용할 수 있는 큰 이점이 생겼습니다.

API Gateway를 통해 인증/인가 및 엔드포인트를 단일화 함으로써 간편하게 여러 서비스를 호출

여러 클라이언트가 여러 개의 서버 서비스를 각각 호출하게 된다면 매우 복잡한 호출 관계가 만들어질 것입니다.

따라서, 여러 클라이언트가 다양한 서비스에 접근하도록 하기 위해서 API Gateway를 통해 단일 진입 점을 만들어 놓았습니다. 다른 유형의 클라이언트에게 서로 다른 API 조합을 제공할 수도 있고, 각 서비스에 접근할 때 필요한 인증/인가 기능을 한 번에 처리할 있는 이점이 생겼습니다. 또한 로드 밸런싱의 효과도 있습니다.

Docker를 사용하여 어디서나 안정적으로 실행할 수 있는 단일 객체 확보

Docker를 사용하지 않았을 때 매번 다른 웹 서비스를 이용할 때마다 그에 따른 설정을 해야하고, 서버마다 각각의 설정을 해야하기 때문에 많은 자원의 낭비가 생기기 마련입니다. 이 문제를 해결하기 위해 Docker을 사용하여 애플리케이션 운영을 표준화하고, 코드를 더 빠르고 원활하게 전달하고, 리소스 사용률을 높여 자원 낭비의 비용을 절감하였습니다.

Kafka를 이용해 마이크로 서비스간의 데이터를 실시간으로 처리

Kafka가 아닌 일반적인 형태의 네트워크 통신은 참여하는 개체가 많아질수록 서로 일일이 다 연결하고 데이터를 전송하는 다대다 통신의 특성 때문에 확장성 면에서 좋지 않습니다 .

따라서, 메시징 시스템을 중심으로 연결하여 확장성이 용이한Kafka를 사용해서 마이크로 서비스간의 데이터를 실시간으로 처. 리하였습니다. Kafka를 사용함으로써 서비스간의 결합성이 낮아지므로 각자의 비즈니스 로직에만 집중할 수 있게 되었고, 메시징 시스템이 잠깐 다운되어도 각 서비스에는 직접적인 영향을 미치지 않게 되었습니다.

BDD 방법으로 테스트 코드를 작성하여 설계 단계에서 누락된 기획을 확인 및 서비스의 이해가 용이

Kotest의 BehaviorSpec을 사용하여 행동 개발 주도(BDD) 방법으로 테스트 코드를 작성하였습니다. 이는 설계 단계에서 누락된 기획을 확인할 수 있기 때문에, 재설계 시 리스크를 줄일 수 있고, 서비스를 이해하는데 용이한 점이 증가 하였습니다.

Flyway로 데이터베이스의 형상관리

로컬에서 변경한 데이터베이스의 스키마나 데이터를 운영 데이터베이스에 반영하는 것이 누락되지 않게 하기 위해 데이터 베이스 형상관리 툴인 Flyway를 사용하였습니다. 또한 개발 DB와 운영 DB의 스키마를 비교하거나, 운영 DB에 수작업을 가하는 노가다와 위험성을 줄이기 위해 사용하였습니다. 스키마의 변경이나 생성 발생 시, 새로운 형상을 생성하고 DB에 적용하여 마이그레이션 작업을 진행하였습니다.

Service mesh의 대표적인 구현체인 Istio 적용

서비스 디스커버리, 라우팅, 로드 밸런싱, 로깅, 모니터링, 보안, 트레이싱 등의 기능을 제공할 수 있도록 Istio를 적용하였습니다.

이는 스프링 클라우드와 넷플릭스 OSS를 이용해 진행할 수도 있지만, 이 경우에 스프링 클라우드로 각 서비스를 먼저 구축하고 마이크로서비스 애플리케이션 자체도 코드 내부에 스프링 클라우드 사용을 위한 클라이언트 코드가 탑재되어야 합니다.

하지만, Istio를 적용하여 마이크로서비스마다 함께 배포되는 사이드카 프락시에 운영 관리를 위한 기능이 별도로 담겨있기 때문에 Istio를 적용하여 마이크로서비스가 순수 비즈니스 로직에 집중할 수 있게 하였습니다.

특정 서비스의 장애가 전체 서비스의 장애로 확장되지 않도록 Resilience4j 의 서킷 브레이커 패턴을 적용

여러 서비스로 구성된 시스템에서는 한 서비스의 장애가 발생했을 때 다른 서비스가 영향을 받을 수 있습니다. 이때 장애가 발생한 서비스를 격리해서 유연하게 처리할 수 있도록 하기 위해, Resilience4j 의 서킷 브레이커 패턴을 적용하여 다른 정상적인 서비스로 요청 흐름이 변경되게 하였습니다.