2. Using an API Gateway

Building Microservices: Using an API Gateway

Using an API Gateway에 대한 요약이다.

  • Client와 Microservices 간에 어떻게 통신을 할 것인가?
  • 모놀리틱(monolithic) 어플리케이션은 엔드포인트가 하나만 존재하는 반면에,
    MSA 어플리케이션은 서비스마다 다른 엔드포인트를 갖는한다.
  • API Gateway를 사용하여 client-application간 통신 문제를 해결해보자.

Introduction

fig
모놀로틱 어플리케이션이었으면 한번의 Rest 호출(~/productdetails/{productId})로 모든 정보를 받아왔을 것이다.
하지만, MSA라면 여러 서비스로부터 각 정보를 받아와야 한다.

Client와 Microservice간 직접(direct) 통신

fig
각 서비스가 public 엔드포인트를 가지고 있다면, client에서 직접 서비스들을 호출할 수 있다.
하지만, 다음과 같이 많은 문제가 있어, 직접 통신하는 경우는 매우 드물다.

직접 통신의 문제점

  1. 클라이언트가 원하는 정보를 얻기 위해 각 서비스의 잘게 나눠놓은(fine-grained) API들을 너무 많이 호출하게 될 수도 있다.
  • 이런 요청이 LAN이 아닌 공공 internet을 통하기 때문에 비효율 적이고, 특히 모바일 네트워크는 더욱 심하다.
  • 클라이언트 코드가 매우 복잡해 질 것이다.
  1. HTTP 프로토콜을 사용하지 않는 서비스가 있는 경우 클라이언트가 직접 통신하기 어렵다.(Thrift, AMQP..)
  2. 서비스를 여러개로 나누거나, 혹은 합치거나 하는 등.. 필요에 의해 변경해야 할 경우 반영하기 힘들다.

API Gateway 사용하여 통신

fig

  • API Gateway는 단일 엔트리포인트를 제공하는 서버이다.
  • OOP의 Facade Pattern과 유사하다.
  • 각 클라이언트에 적절한 API를 노출시키고, 내부 시스템 아키텍쳐는 숨길 수 있다.

API Gateway가 할 수 있는 일

  • request routing: 모든 요청은 API Gateway를 통해서 들어와 적절한 서비스로 라우팅된다.
  • 클라이언트 별로 알맞게 변경한 API를 제공할 수 있다. 여러 서비스를 호출해서 클라이언트별로 필요한 항목만 조합해서 API를 만들 수 있다.
  • composition: 여러 서비스를 호출하고 결과를 모아(aggregate) 한번에 전달 할 수도 있다.
  • protocol translation: 다른 프로토콜을 사용하는 경우 Web 프로토콜(HTTP, WebSocket..)로 변환해서 보낼 수 있다.
  • 이외에도.. Message Exchange Pattern, 인증, 모니터링, 로드밸런싱, 캐싱, QoS, Metering 등 여러가지 일을 할 수 있다.

장점: single entry point

  • 내부 구조를 숨길(encapsulate) 수 있다.
  • client와 어플리케이션간 통신을 줄 일수 있다.
  • 클라이언트 코드가 단순해 진다.

단점: highly available component

  • API Gateway 역시 개발,배포,관리 되어야하고 매우 높은 수준의 가용성을 보장해야하는 컴포넌트이다.
  • 각 서비스의 API를 외부로 노출하기 위해서 반드시 API Gateway를 update해야 된다. 이는 개발의 병목이 될 수 도 있다.

API Gateway 구현(혹은 설계 이슈)

구현시 고려해야하는 여러 설계 이슈를 알아보자.

Performance and Scalability

  • asynchronous, non-blocking I/O 를 지원해야 한다.
  • JVM NIO-based frameworks: Netty, Vertx, Spring Reactor, JBoss Undertow
  • non-JVM: Node.js

Reactive Programming Model

여러 요청을 서비스로 라우팅하거나, 그 결과를 조합해야 하는 경우에 응답시간을 최소화 하기위해서 동시에 독립적으로 수행할 수 있어야 한다.
API Gateway를 asynchronous하고, reactive하게 구현하는 것이 좋다.

  • Future in Scala
  • CompletableFuture in Java 8
  • Promise in JavaScript
  • RxJava, RxJS…

Service Invocation

MSA는 분산 환경이기 때문에 다양한 내부 프로세스간 통신 메카니즘이 필요하다.

  • asynchronous, messaging-based mechanism: JMS, AMQP, Zeromq..
  • synchronous mechanism: HTTP, Thrift

Service Discovery

  • API Gateway는 각 서비스의 위치(IP, Port)를 알고 있어야한다.
  • Message Broker나 Database와 같은 인프라 서비스는 고정(static) 위치를 가지고 있지만,
    어플리케이션 서비스는 주로 동적(dynamic) 위치를 할당 받고 scale in/out 되는 경우 자주 변경될 수 있다.
  • 따라서 service discovery 메카니즘이 필요하다.
  • 각 서비스 인스턴스의 위치는 Service Registry에 등록되어 있어야 하고,
    API Gateway는 서비스의 위치를 조회하여 라우팅한다.

Handling Partial Failures

분산 환경에서 서비스가 다른 서비스를 호출하는 경우, 응답이 느리거나 안올 수 있다. 이런 경우에 API Gateway는 해당 서비스를 계속 기다리며 block되서는 안된다. 특정 서비스에 장애가 있는 경우, 미리 지정된 시나리오에 따라 처리될 수 있어야 한다.

  • 장애난 서비스의 결과는 비워두고 남은 서비스의 데이터가 사용자에게 의미있다면 그것 만이라도 결과를 응답해야 한다.
  • 사용자에게 의미있거나 꼭 필요한 서비스가 장애난 경우에는 error를 리턴해야 된다.
  • 자주 변경되지 않는 데이터의 경우, 정상적인 상황에 리턴했던 결과가 cache에 있다면 그것을 리턴할 수도 있다.
  • Netflix Hystrix: circuit breaker, default value 리턴 등 가능..

결론

  • MSA기반의 어플리케이션에서 API Gateway를 사용하는 것은 single entry point를 제공한다는 측면에서 의미가있다.
  • 요청에 대한 라우팅, 조합, 프로토콜 변환 등의 작업을 하거나 클라이언트별로 custom API를 제공할 수도 있다.
  • API Gateway를 통해 캐싱된 값이나 기본값을 리턴하는 등, 장애에 대응 할 수 있다.
Share