클라우드가 대세가 되며 많은 서비스가 scale-out을 통해 증가하는 트래픽을 감당하고 있다. 이러한 변화는 개발 패러다임에도 큰 변화를 일으켰는데, 그 중 하나가 MSA(Microservices Architecture)라고 생각한다.
MSA는 보다 작은 단위로 서비스를 구분된 여러 마이크로서비스의 집합으로 구성된다. 이 때문에 하나의 큰 모놀리식한 어플리케이션보다 빠르게 배포되며, 한 기능의 장애가 모든 서비스의 장애로 이어지지 않는 등 다양한 장점이 있다.
여러 서비스가 아무 연관없이 존재한다고 생각해보자.
서비스 A의 기능은 ○○○ IP, ○○ 포트
서비스 B의 기능은 ◇◇◇ IP, ◇◇ 포트로 요청하면 돼
이제 요청하는 누군가가 정해진대로 요청만 하면 된다!

현실은 이렇게 간단하지 않다. 서비스가 A, B 두개뿐이라면 가능하겠지만 마이크로서비스가 늘어날 수록 관리가 매우 복잡해진다.
특히, scale-out이 빈번하게 발생하여 고정된 IP를 사용하지 못하는 클라우드 환경에선 절대 사용하지 못할 방법이다.
이러한 문제를 해결하기 위해 API 게이트웨이가 필요하다.
간단하게 표현하자면, 모든 요청을 받아 각 서비스로 중개해주는 중개자이다. API 게이트웨이가 존재한다면 더이상 모든 서비스의 IP와 포트 번호를 알 필요 없으며 단순히 API 게이트웨이를 통해 요청하면 된다.
API 게이트웨이는 다음과 같은 기능을 제공한다.
여러 마이크로서비스를 사용하는 경우, 클라이언트가 각각의 서비스에 직접 접근하는 것은 복잡하다. API 게이트웨이는 단일 진입점을 제공하여 이러한 복잡성을 줄인다.
트래픽을 여러 서비스 인스턴스에 고르게 분배하여 시스템의 안정성을 높인다.
중앙에서 인증과 인가를 처리할 수 있다. 각 마이크로서비스는 인증과 인가에서 보다 자유로워질 수 있다.
다양한 서비스 간의 통합을 쉽게 할 수 있으며, 서비스 디스커버리와 연동하여 동적으로 라우팅할 수 있다.
필자는 API 게이트웨이를 구현하기 위해 Spring cloud netflix eureka 와 Spring cloud reactive gateway 를 사용했다.
두 기술을 선택한 이유는 다음과 같다.
정보가 많았다. 모든 스프링을 이용한 게이트웨이 예제는 두 기술을 이용한 예제라고 봐도 될 정도로 많은 비중을 차지했다.
reactive gateway를 선택한 이유는 Tomcat이 아닌 netty를 사용하며, 비동기 통신을 지원한다는 것이다.
Spring mvc가 기본적으로 사용하는 Tomcat은 1개의 요청당 1개의 스레드가 할당된다. 앞단에서 많은 요청을 각 서비스로 릴레이하는 API 게이트웨이 특성상 보다 높은 성능이 필요할 것 같았고, 이에 비동기 방식의 netty를 사용하는 reactive gateway를 사용했다.
구현은 잘 설명된 블로그들이 많았다.
Spring Cloud Netflix Eureka & Spring Cloud Gateway
[Spring Cloud] Eureka 개념 및 예제
위 두 블로그를 참고해 프로젝트에 적용했다.
gateway를 구현하는 방법은 크게 2가지로 구분되었다. 자바 코드로 작성하는 방법과 application.yml 등의 설정 파일로 작성하는 방법이다.
Type Safety
컴파일 타임에 타입 검사를 받을 수 있어 오타 등 오류를 사전에 찾아낼 수 있다.
유연성
조건부 로직, 동적 라우팅 등 복잡한 라우팅 로직을 구현하기 편하다.
간편함
설정 파일만으로 간단하고 직관적으로 gateway를 구성할 수 있다.
설정 변경에 강함
코드를 변경하지 않고 설정을 변경할 수 있다. 즉, 게이트웨이 설정이 변경되어도 다시 빌드 할 필요가 없다.
이 중 설정 파일을 통해 구현하는 방법을 선택했다. 이유는 다음과 같다.
진행한 프로젝트는 이곳에서 볼 수 있습니다.
Spring Cloud Netflix Eureka & Spring Cloud Gateway
[Spring Cloud] Eureka 개념 및 예제