[MSA] - 2. API Gateway가 필요한 이유

안녕하세요. 이번 글은 MSA에 대한 글을 이어서 API Gateway에 대한 이야기를 하고자 합니다.

지난 MSA 글에서는 MSA를 왜 써야하는지, 어떨 때 필요하고, 무슨 장단점이 있는지를 간략하게 설명해보는 아주 쉬운 이야기를 다뤄봤습니다. 사실 MSA의 깊이는 그것보다 깊기 때문에 제대로 이야기를 하고자 한다면, 많은 이야기가 될 것 같아 짧게 필요한 부분을 설명드린 것이구요. 타 글에서 좀 더 심층적으로 다뤄볼까 합니다.

Spring Cloud를 사용해서 간단히 API를 구성하는 방법도 알았고, 이와 비슷하게 Python의 Django, Flask 등 타 언어, 타 프레임워크에서도 어떻게 구성할 수 있는지 감이 잡혔을 것이라 생각합니다. 

오늘은 이들 API를 그룹화 시켜주는 API Gateway에 대해 알아보도록 하겠습니다.

 

API Gateway

API Gateway? 어디서 많이 들어본 말이다. 아마 AWS에서 Serverless Stack을 다뤄보신 분들이라면, Lambda와 API Gateway를 사용해보면서 경험해보신 분들일 것입니다. 네, 맞습니다. 실제로 해당 솔루션에서 제공하는 API Gateway와 동일한 역할을 하는 것이 바로 MSA의 API Gateway 입니다.

AWS, GCP 등의 클라우드를 이용하여 REST API를 만들고 운영하는 방법에는 대표적인 3가지 방법이 있습니다.

  1. IaaS (EC2, VM Instance 등)를 사용하여 Tomcat, JBoss 등의 WAS 배포를 통한 운영.
  2. PaaS (ElasticBeansTalk 등)를 사용하여 war 혹은 jar 파일의 배포를 통한 운영.
  3. FaaS (Lambda, Functions 등)를 사용하여 코드 배포를 통한 운영.

이 중에서 API Gateway를 필히 사용하여 REST API의 URI를 잡아줘야 하는 것은 3번에 해당합니다. IaaS를 사용할 경우, 웹 애플리케이션 서버나, 웹 서버에서 제공하는 URI를 사용할 수 있는 방법이 있고, PaaS 역시 마찬가지입니다.

하지만 FaaS는 비즈니스 로직이 담겨져 있는 코드만 들어있습니다. 따라서 함수의 이름과 로직만 담겨져 있기 때문에 해당 코드가 어느 URI를 타야하는지에 대한 정보가 전혀 담겨져 있지 않으므로 이에 대한 URI 주소를 매겨줘야 합니다. API Gateway는 이런 URI를 하나로 통합하는 역할을 맡게 됩니다.

그렇다면 MSA에서는 이걸 어떻게 사용하게 될까요? MSA는 큰 서비스를 잘게 쪼개어 각각의 역할을 분리하게 됩니다. 그런데, 이렇게 하게 되면 URI 주소가 전부 달라지게 되고, 이 말은 포트 주소 등을 포함한 모든 주소가 달라지게 되는 것입니다. 이로 인해 생기는 문제점은 다음과 같습니다.

  • 수많은 API 호출의 기록 관리가 용이하지 않음.
  • 내부 비즈니스 로직, 인프라 등 주소가 선명하게 노출되어 보안에 취약.
  • 각 서비스 마다 인증 등의 공통 로직을 중복 구현 해야 하는 문제점 존재.

특히 세 번째에 해당하는 문제점은 서비스 운영에 있어 가장 큰 헛점을 남기게 됩니다. 개발에 있어서 불편한 점보다는 더 크리티컬한 문제일 테니깐요. 

좀 더 쉽게 설명하기 위해 아래의 그림을 보면서 설명을 해보도록 하겠습니다.

지난 Spring Cloud 실습을 그대로 인용해서 Note API를 작성했을 때, 우리는 이렇게 위와 같이 포트 주소를 다르게 매겨서 테스트를 했습니다. 물론 같은 환경이었기 때문에, 같은 IP 주소를 사용하고 있었죠. 그런데, 실제 실무에서는 이를 같은 서버에서 운영한다고 하더라도, 컨테이너화 시켜서 Docker 등으로 운영하게 되면 IP 주소가 달라지게 되고, 경우에 따라서는 진짜 다른 서버를 사용하기도 합니다.

그림처럼 API Gateway는 API 서버 앞단에서 모든 엔드포인트를 단일화 해주는 또 다른 서버의 역할을 합니다. 제가 사용하고 있는 도메인인 neonkid.xyz를 예로 들어서 표현을 한 것입니다. 만약 제가 저런 API를 만들고 API Gateway를 사용해서 단일화 한다면 저렇게도 구현할 수 있다는 것이죠.

아마 기존 인프라를 운영하시던 분들이시라면, 리버스 프록시(Reverse Proxy) 기술을 연상할 것입니다. 맞습니다. 그것과 거의 비슷한 역할을 하는 존재입니다.

여기에 API Gateway는 인증 서비스를 추가로 가지고 있어, 요청, 응답에 따라 애플리케이션 내부에 있는 마이크로 서비스로 라우팅하는 역할도 포함합니다.

이 외에도 다양한 기능이 존재합니다.

 

 

API Gateway의 주요 기능

 

1. 인증/인가 서비스

인증/인가 서비스는 서비스 호출에 있어서 매우 중요한 역할 중 하나입니다. 관리자와 사용자가 분리되어 있는 웹 서비스들이 대부분인데, 그들의 호출이 자유롭다면 문제가 있겠죠. 

그런데, 서비스가 분리된다면, 이러한 보안 처리는 어떻게 해줘야 할까요? 기존 모놀리틱 아키텍처에서는 고민할 필요도 없이 이러한 보안처리를 디펜던시를 사용해서 처리했겠죠. 하지만 서비스가 각각 분리되어 있다면? 그들 디펜던시를 각 API마다 만들어준다면 소스가 중복되고, 그게 심해지면 유지 보수가 정말 힘들어집니다. 

Spring으로 예를 들자면, 각 서비스에 Spring Security 디펜던시 넣고, 만들어주는 거랑 같죠...

API Gateway에서는 이러한 인증, SSL 등의 서비스를 오프로드해주기 때문에 이러한 불편함을 해소시켜줄 수 있습니다.

 

2. 라우팅과 로드밸런싱

대용량 처리 서비스에 있어 가장 필수인 로드 밸런싱은 이제는 거의 백엔드 개발에 필수가 되어버렸죠. 다만 장점이 있다면, 모놀리틱 아키텍처에서는 모든 서비스들에 대해 로드 밸런싱을 해줬다면, 마이크로 서비스 아키텍처에서는 실제로 요청이 많은 서비스에 대해서만 로드 밸런싱을 수행할 수 있다거나 스케일 업-아웃의 자유도가 증가했다고 볼 수 있겠네요.

또한 API 서버를 업그레이드 하거나 테스트 중에 다른 URI로 리다이렉트 할 수 있도록 라우팅 기능을 제공해줍니다.

 

3. 서비스 디스커버리 (Service Discovery)

MSA에 있어 가장 필요한 기능 중 하나입니다. 서비스가 분리되어 있는 상황에서 각 서비스를 호출하기 위해서는 서비스마다 고유적으로 가지고 있는 IP와 포트 주소를 알고 있어야 합니다. API 갯수가 그리 많지 않다면 큰 문제가 되지 않겠지만 API 갯수가 기하급수적으로 많고, 로드 밸런싱을 통해서 여러 서비스가 움직이고 있다면, 쉽지 않을 것입니다.

서비스 디스커버리는 내가 원하는 서비스의 IP, 포트 주소를 찾아주는 역할을 합니다. 실제로 이 기능을 많이 사용하고 있는 곳이 바로 클라우드인데, 클라우드의 경우는 스케일 업-다운이 자주 발생하고, 그렇게 되면 컨테이너 생성, 소멸에 따라 IP, 포트 주소가 달라질 뿐더러 또 고정된 값이 아니기 때문에 원하는 서비스를 검색하여 이들 정보를 제공해주는 것은 그야 말로 필수라고 할 수 있죠.

 

마치며...

여기까지, API Gateway에 대한 이야기를 몇 가지 다뤄봤습니다. 자세히 훑어보면, 기존 인프라 환경에서 편하게 쓰던 몇 가지 기능이 보일 것이고, 백엔드 개발을 해보신 분들이라면, 한 번 쯤 경험해 본 고민들일 것입니다. 

이 글을 쓰면서 참고한 글이 있습니다. 거기에 있는 내용 중에는 SOA 프로젝트의 실패 사례 큰 까닭이 적혀있는데요. 그 중에 하나가 바로 ESB 내부 로직 처리에 사용한 데이터 구조였습니다. 과거에는 웹 애플리케이션의 대부분의 요청/응답을 XML로 처리했는데, XML을 한 번 파싱해보거나 써보신 분들이라면 느끼시겠지만 굉장히 파싱도 어렵고, 처리 속도 또한 무진장 느립니다..

지금은 JSON, GraphQL을 많이 사용하고 있고, 저 또한 그것을 많이 지향하고 있습니다. 앞으로 갈수록 대용량 처리 서비스의 수요는 계속 늘어날 것이고, 이러한 오버헤드 감소, 효율적인 아키텍처의 설계는 큰 과제 거리로 남게 될지도 모르겠네요.

다음 포스트에서는 Spring Cloud를 이용하여 이 게이트웨이를 구현하는 것에 대해 적어보도록 하겠습니다.

 

Ref: MSA 제대로 이해하기 - Velopert 님 포스트

comments powered by Disqus

Tistory Comments 0