마이크로서비스 설계, 구축 및 배포에 대한 이 7부작 시리즈의 첫 번째 기사에서는 마이크로 서비스 아키텍처 패턴을 소개했습니다. 마이크로서비스를 사용하는 것의 이점과 단점, 그리고 마이크로서비스의 복잡성에도 불구하고 일반적으로 복잡한 애플리케이션에 이상적인 선택인 방법에 대해 논의했습니다. 이 기사는 시리즈의 두 번째 기사이며 API 게이트웨이를 사용하여 마이크로서비스를 구축하는 방법을 논의합니다.
애플리케이션을 마이크로서비스 세트로 빌드하기로 선택한 경우 애플리케이션의 클라이언트가 마이크로서비스와 상호 작용하는 방식을 결정해야 합니다. 모놀리식 애플리케이션에는 (일반적으로 복제되고 로드 밸런싱된) 엔드포인트 세트가 하나뿐입니다. 그러나 마이크로서비스 아키텍처에서 각 마이크로서비스는 일반적으로 세분화된 엔드포인트 세트를 노출합니다. 이 문서에서는 이것이 클라이언트-애플리케이션 통신에 어떤 영향을 미치는지 살펴보고 API Gateway를 사용하는 접근 방식을 제안합니다 .
소개
쇼핑 애플리케이션을 위한 네이티브 모바일 클라이언트를 개발하고 있다고 가정해 보겠습니다. 주어진 제품에 대한 정보를 표시하는 제품 세부 정보 페이지를 구현해야 할 가능성이 높습니다.
예를 들어, 다음 다이어그램은 Amazon Android 모바일 애플리케이션에서 제품 세부 정보를 스크롤할 때 표시되는 내용을 보여줍니다.

스마트폰 앱이긴 하지만, 제품 세부 정보 페이지에는 많은 정보가 표시됩니다. 예를 들어, 기본적인 제품 정보(예: 이름, 설명, 가격)뿐만 아니라 이 페이지에는 다음도 표시됩니다.
- 장바구니에 담긴 상품의 개수
- 주문 내역
- 고객 리뷰
- 재고 부족 경고
- 배송 옵션
- 이 제품과 함께 자주 구매되는 다른 제품, 이 제품을 구매한 고객이 구매한 다른 제품, 이 제품을 구매한 고객이 본 다른 제품 등 다양한 추천
- 대체 구매 옵션
모놀리식 애플리케이션 아키텍처를 사용할 때 모바일 클라이언트는 애플리케이션에 단일 REST 호출( )을 하여 이 데이터를 검색합니다. 로드 밸런서는 요청을 N개의 동일한 애플리케이션 인스턴스 중 하나로 라우팅합니다. 그런 다음 애플리케이션은 다양한 데이터베이스 테이블을 쿼리하고 클라이언트에 응답을 반환합니다.GET api.company.com/productdetails/productId
반면, 마이크로서비스 아키텍처를 사용할 때 제품 세부 정보 페이지에 표시된 데이터는 여러 마이크로서비스가 소유합니다. 다음은 예시 제품 세부 정보 페이지에 표시된 데이터를 소유하는 잠재적인 마이크로서비스 중 일부입니다.
- 쇼핑카트 서비스 – 쇼핑카트에 담긴 품목 수
- 주문 서비스 – 주문 내역
- 카탈로그 서비스 - 제품명, 이미지, 가격 등 기본 제품 정보 제공
- 리뷰 서비스 – 고객 리뷰
- 재고 서비스 – 재고 부족 경고
- 배송 서비스 – 배송 옵션, 마감일 및 비용은 배송 제공업체의 API에서 별도로 추출됩니다.
- 추천 서비스(들) - 제안된 항목

모바일 클라이언트가 이러한 서비스에 어떻게 접근할지 결정해야 합니다. 옵션을 살펴보겠습니다.
클라이언트 대 마이크로서비스 직접 통신
이론적으로 클라이언트는 각 마이크로서비스에 직접 요청을 할 수 있습니다. 각 마이크로서비스에는 퍼블릭 엔드포인트( https:// serviceName .api.company.name )가 있습니다. 이 URL은 마이크로서비스의 로드 밸런서에 매핑되며, 로드 밸런서는 요청을 사용 가능한 인스턴스에 분산합니다. 제품 세부 정보를 검색하기 위해 모바일 클라이언트는 위에 나열된 각 서비스에 요청을 합니다.
안타깝게도 이 옵션에는 어려움과 한계가 있습니다. 한 가지 문제는 클라이언트의 요구 사항과 각 마이크로서비스에서 노출된 세분화된 API 간의 불일치입니다. 이 예에서 클라이언트는 7개의 별도 요청을 해야 합니다. 더 복잡한 애플리케이션에서는 훨씬 더 많은 요청을 해야 할 수도 있습니다. 예를 들어, Amazon은 수백 개의 서비스가 제품 페이지를 렌더링하는 데 어떻게 관련되어 있는지 설명합니다. 클라이언트가 LAN을 통해 그렇게 많은 요청을 할 수 있지만, 공용 인터넷에서는 너무 비효율적일 것이고 모바일 네트워크에서는 확실히 비실용적일 것입니다. 또한 이 접근 방식은 클라이언트 코드를 훨씬 더 복잡하게 만듭니다.
클라이언트가 마이크로서비스를 직접 호출하는 또 다른 문제는 일부는 웹 친화적이지 않은 프로토콜을 사용할 수 있다는 것입니다. 한 서비스는 Thrift 바이너리 RPC를 사용하는 반면 다른 서비스는 AMQP 메시징 프로토콜을 사용할 수 있습니다. 어느 프로토콜도 브라우저나 방화벽에 특별히 친화적이지 않으며 내부적으로 사용하는 것이 가장 좋습니다. 애플리케이션은 방화벽 외부에서 HTTP 및 WebSocket과 같은 프로토콜을 사용해야 합니다.
이 접근 방식의 또 다른 단점은 마이크로서비스를 리팩토링하기 어렵게 만든다는 것입니다. 시간이 지남에 따라 시스템을 서비스로 분할하는 방식을 변경하고 싶을 수 있습니다. 예를 들어 두 서비스를 병합하거나 서비스를 두 개 이상의 서비스로 분할할 수 있습니다. 그러나 클라이언트가 서비스와 직접 통신하는 경우 이러한 종류의 리팩토링을 수행하는 것이 매우 어려울 수 있습니다.
이런 종류의 문제 때문에 클라이언트가 마이크로서비스와 직접 통신하는 것은 거의 의미가 없습니다.
API 게이트웨이 사용
일반적으로 훨씬 더 나은 접근 방식은 API Gateway 라고 알려진 것을 사용하는 것입니다 . API Gateway는 시스템에 대한 단일 진입점인 서버입니다. 객체 지향 설계의 Facade 패턴과 유사합니다. API Gateway는 내부 시스템 아키텍처를 캡슐화하고 각 클라이언트에 맞게 조정된 API를 제공합니다. 인증, 모니터링, 로드 밸런싱, 캐싱, 요청 셰이핑 및 관리, 정적 응답 처리와 같은 다른 책임이 있을 수 있습니다.
다음 다이어그램은 API 게이트웨이가 일반적으로 아키텍처에 어떻게 적용되는지 보여줍니다.

API Gateway는 요청 라우팅, 구성 및 프로토콜 변환을 담당합니다. 클라이언트의 모든 요청은 먼저 API Gateway를 거칩니다. 그런 다음 요청을 적절한 마이크로서비스로 라우팅합니다. API Gateway는 종종 여러 마이크로서비스를 호출하고 결과를 집계하여 요청을 처리합니다. HTTP 및 WebSocket과 같은 웹 프로토콜과 내부적으로 사용되는 웹에 친화적이지 않은 프로토콜 간에 변환할 수 있습니다.
API Gateway는 각 클라이언트에 사용자 지정 API를 제공할 수도 있습니다. 일반적으로 모바일 클라이언트에 대한 거친 API를 노출합니다. 예를 들어 제품 세부 정보 시나리오를 생각해 보세요. API Gateway는 모바일 클라이언트가 단일 요청으로 모든 제품 세부 정보를 검색할 수 있는 엔드포인트( /productdetails?productid= xxx )를 제공할 수 있습니다. API Gateway는 다양한 서비스(제품 정보, 추천, 리뷰 등)를 호출하고 결과를 결합하여 요청을 처리합니다.
API 게이트웨이의 좋은 예는 Netflix API Gateway 입니다 . Netflix 스트리밍 서비스는 텔레비전, 셋톱 박스, 스마트폰, 게임 시스템, 태블릿 등 수백 가지 종류의 기기에서 사용할 수 있습니다. 처음에 Netflix는 스트리밍 서비스에 대한 단일 API를 제공하려고 시도했습니다. 그러나 다양한 기기와 고유한 요구 사항으로 인해 제대로 작동하지 않는다는 것을 알게 되었습니다. 오늘날 그들은 기기별 어댑터 코드를 실행하여 각 기기에 맞게 조정된 API를 제공하는 API Gateway를 사용합니다. 어댑터는 일반적으로 평균 6~7개의 백엔드 서비스를 호출하여 각 요청을 처리합니다. Netflix API Gateway는 하루에 수십억 개의 요청을 처리합니다.
API 게이트웨이의 이점 및 단점
예상하셨겠지만 API Gateway를 사용하면 이점과 단점이 모두 있습니다. API Gateway를 사용하는 주요 이점은 애플리케이션의 내부 구조를 캡슐화한다는 것입니다. 특정 서비스를 호출할 필요 없이 클라이언트는 단순히 게이트웨이와 통신합니다. API Gateway는 각 종류의 클라이언트에 특정 API를 제공합니다. 이렇게 하면 클라이언트와 애플리케이션 간의 왕복 횟수가 줄어듭니다. 또한 클라이언트 코드도 간소화합니다.
API Gateway에도 몇 가지 단점이 있습니다. 개발, 배포 및 관리해야 하는 또 다른 고가용성 구성 요소입니다. API Gateway가 개발 병목 현상이 될 위험도 있습니다. 개발자는 각 마이크로서비스의 엔드포인트를 노출하기 위해 API Gateway를 업데이트해야 합니다. API Gateway를 업데이트하는 프로세스는 가능한 한 가벼워야 합니다. 그렇지 않으면 개발자는 게이트웨이를 업데이트하기 위해 줄을 서서 기다려야 합니다. 그러나 이러한 단점에도 불구하고 대부분의 실제 애플리케이션에서는 API Gateway를 사용하는 것이 합리적입니다.
API 게이트웨이 구현
API 게이트웨이를 사용하는 동기와 장단점을 살펴보았으니 이제 고려해야 할 다양한 설계 문제를 살펴보겠습니다.
성능 및 확장성
Netflix 규모로 운영되고 하루에 수십억 개의 요청을 처리해야 하는 회사는 극소수에 불과합니다. 그러나 대부분의 애플리케이션에서 API Gateway의 성능과 확장성은 일반적으로 매우 중요합니다. 따라서 비동기, 비차단 I/O를 지원하는 플랫폼에서 API Gateway를 빌드하는 것이 합리적입니다. 확장 가능한 API Gateway를 구현하는 데 사용할 수 있는 다양한 기술이 있습니다. JVM에서는 Netty, Vertx, Spring Reactor 또는 JBoss Undertow와 같은 NIO 기반 프레임워크 중 하나를 사용할 수 있습니다. 인기 있는 비 JVM 옵션 중 하나는 Chrome의 JavaScript 엔진에 구축된 플랫폼인 Node.js입니다. 또 다른 옵션은 NGINX Plus를 사용하는 것입니다 . NGINX Plus는 쉽게 배포, 구성 및 프로그래밍할 수 있는 성숙하고 확장 가능하며 고성능 웹 서버와 역방향 프록시를 제공합니다. NGINX Plus는 인증, 액세스 제어, 요청 부하 분산, 응답 캐싱을 관리하고 애플리케이션 인식 상태 검사 및 모니터링을 제공합니다.
반응형 프로그래밍 모델 사용
API Gateway는 일부 요청을 적절한 백엔드 서비스로 라우팅하여 처리합니다. 여러 백엔드 서비스를 호출하고 결과를 집계하여 다른 요청을 처리합니다. 제품 세부 정보 요청과 같은 일부 요청의 경우 백엔드 서비스에 대한 요청은 서로 독립적입니다. 응답 시간을 최소화하기 위해 API Gateway는 독립적인 요청을 동시에 수행해야 합니다. 그러나 때로는 요청 간에 종속성이 있습니다. API Gateway는 요청을 백엔드 서비스로 라우팅하기 전에 먼저 인증 서비스를 호출하여 요청을 검증해야 할 수 있습니다. 마찬가지로 고객의 위시리스트에 있는 제품에 대한 정보를 가져오려면 API Gateway는 먼저 해당 정보가 포함된 고객 프로필을 검색한 다음 각 제품에 대한 정보를 검색해야 합니다. API 구성의 또 다른 흥미로운 예는 Netflix Video Grid 입니다 .
기존의 비동기 콜백 방식을 사용하여 API 구성 코드를 작성하면 콜백 지옥에 빠르게 빠질 수 있습니다. 코드가 꼬이고 이해하기 어렵고 오류가 발생하기 쉽습니다. 훨씬 더 나은 방식은 반응형 방식을 사용하여 선언적 스타일로 API Gateway 코드를 작성하는 것입니다. 반응형 추상화의 예로는 Scala의 Future , Java 8의 CompletableFuture , JavaScript의 Promise가 있습니다. 원래 Microsoft에서 .NET 플랫폼용으로 개발한 Reactive Extensions (Rx 또는 ReactiveX라고도 함) 도 있습니다 . Netflix는 API Gateway에서 사용하기 위해 JVM용 RxJava를 만들었습니다. 브라우저와 Node.js에서 모두 실행되는 JavaScript용 RxJS도 있습니다. 반응형 방식을 사용하면 간단하면서도 효율적인 API Gateway 코드를 작성할 수 있습니다.
서비스 호출
마이크로서비스 기반 애플리케이션은 분산 시스템이며 프로세스 간 통신 메커니즘을 사용해야 합니다. 프로세스 간 통신에는 두 가지 스타일이 있습니다. 한 가지 옵션은 비동기 메시징 기반 메커니즘을 사용하는 것입니다. 일부 구현은 JMS 또는 AMQP와 같은 메시지 브로커를 사용합니다. Zeromq와 같은 다른 구현은 브로커가 없고 서비스가 직접 통신합니다. 다른 프로세스 간 통신 스타일은 HTTP 또는 Thrift와 같은 동기 메커니즘입니다. 시스템은 일반적으로 비동기 및 동기 스타일을 모두 사용합니다. 각 스타일의 여러 구현을 사용할 수도 있습니다. 결과적으로 API Gateway는 다양한 통신 메커니즘을 지원해야 합니다.
서비스 발견(Discovery)
API Gateway는 통신하는 각 마이크로서비스의 위치(IP 주소 및 포트)를 알아야 합니다. 기존 애플리케이션에서는 위치를 하드와이어링할 수 있지만, 최신 클라우드 기반 마이크로서비스 애플리케이션에서는 이는 사소한 문제가 아닙니다. 메시지 브로커와 같은 인프라 서비스는 일반적으로 정적 위치를 가지며, 이는 OS 환경 변수를 통해 지정할 수 있습니다. 그러나 애플리케이션 서비스의 위치를 결정하는 것은 그렇게 쉽지 않습니다. 애플리케이션 서비스에는 동적으로 할당된 위치가 있습니다. 또한 자동 확장 및 업그레이드로 인해 서비스 인스턴스 세트가 동적으로 변경됩니다. 결과적으로 API Gateway는 시스템의 다른 서비스 클라이언트와 마찬가지로 시스템의 서비스 검색 메커니즘인 서버 측 검색 또는 클라이언트 측 검색을 사용해야 합니다 . 이후 문서에서 서비스 검색에 대해 더 자세히 설명합니다. 지금은 시스템에서 클라이언트 측 검색을 사용하는 경우 API Gateway가 모든 마이크로서비스 인스턴스와 해당 위치의 데이터베이스인 서비스 레지스트리를 쿼리할 수 있어야 한다는 점에 유의하는 것이 좋습니다 .
부분적 실패 처리
API Gateway를 구현할 때 해결해야 할 또 다른 문제는 부분적 실패 문제입니다. 이 문제는 모든 분산 시스템에서 한 서비스가 느리게 응답하거나 사용할 수 없는 다른 서비스를 호출할 때마다 발생합니다. API Gateway는 다운스트림 서비스를 기다리며 무기한 차단되어서는 안 됩니다. 그러나 실패를 처리하는 방법은 특정 시나리오와 실패하는 서비스에 따라 달라집니다. 예를 들어, 추천 서비스가 제품 세부 정보 시나리오에서 응답하지 않으면 API Gateway는 사용자에게 여전히 유용하므로 나머지 제품 세부 정보를 클라이언트에 반환해야 합니다. 추천은 비어 있거나 예를 들어 하드와이어된 상위 10개 목록으로 대체될 수 있습니다. 그러나 제품 정보 서비스가 응답하지 않으면 API Gateway는 클라이언트에 오류를 반환해야 합니다.
API Gateway는 캐시된 데이터가 사용 가능한 경우 이를 반환할 수도 있습니다. 예를 들어, 제품 가격이 자주 변경되지 않으므로 가격 서비스를 사용할 수 없는 경우 API Gateway는 캐시된 가격 데이터를 반환할 수 있습니다. 데이터는 API Gateway 자체에서 캐시하거나 Redis 또는 Memcached와 같은 외부 캐시에 저장할 수 있습니다. 기본 데이터 또는 캐시된 데이터를 반환함으로써 API Gateway는 시스템 장애가 사용자 경험에 영향을 미치지 않도록 합니다.
Netflix Hystrix 는 원격 서비스를 호출하는 코드를 작성하는 데 매우 유용한 라이브러리입니다. Hystrix는 지정된 임계값을 초과하는 호출을 시간 초과합니다. 이는 클라이언트가 응답하지 않는 서비스를 불필요하게 기다리지 않도록 하는 회로 차단기 패턴을 구현합니다. 서비스의 오류율이 지정된 임계값을 초과하면 Hystrix가 회로 차단기를 작동시키고 모든 요청은 지정된 기간 동안 즉시 실패합니다. Hystrix를 사용하면 캐시에서 읽거나 기본값을 반환하는 것과 같이 요청이 실패할 때 대체 작업을 정의할 수 있습니다. JVM을 사용하는 경우 Hystrix를 사용하는 것을 고려해야 합니다. 그리고 비 JVM 환경에서 실행하는 경우 동등한 라이브러리를 사용해야 합니다.
요약
대부분의 마이크로서비스 기반 애플리케이션의 경우, 시스템에 대한 단일 진입점 역할을 하는 API Gateway를 구현하는 것이 합리적입니다. API Gateway는 요청 라우팅, 구성 및 프로토콜 변환을 담당합니다. 각 애플리케이션 클라이언트에 사용자 지정 API를 제공합니다. API Gateway는 캐시된 데이터나 기본 데이터를 반환하여 백엔드 서비스의 오류를 마스크할 수도 있습니다. 이 시리즈의 다음 기사에서는 서비스 간 통신을 살펴보겠습니다.
위 내용과 같이 NGINX Plus 를 활용하여 Demo 가 필요하시면 하단의 전문가에게 상담받기 버튼을 클릭해주세요
전문가에게 상담받기
마이크로서비스 설계, 구축 및 배포에 대한 이 7부작 시리즈의 첫 번째 기사에서는 마이크로 서비스 아키텍처 패턴을 소개했습니다. 마이크로서비스를 사용하는 것의 이점과 단점, 그리고 마이크로서비스의 복잡성에도 불구하고 일반적으로 복잡한 애플리케이션에 이상적인 선택인 방법에 대해 논의했습니다. 이 기사는 시리즈의 두 번째 기사이며 API 게이트웨이를 사용하여 마이크로서비스를 구축하는 방법을 논의합니다.
애플리케이션을 마이크로서비스 세트로 빌드하기로 선택한 경우 애플리케이션의 클라이언트가 마이크로서비스와 상호 작용하는 방식을 결정해야 합니다. 모놀리식 애플리케이션에는 (일반적으로 복제되고 로드 밸런싱된) 엔드포인트 세트가 하나뿐입니다. 그러나 마이크로서비스 아키텍처에서 각 마이크로서비스는 일반적으로 세분화된 엔드포인트 세트를 노출합니다. 이 문서에서는 이것이 클라이언트-애플리케이션 통신에 어떤 영향을 미치는지 살펴보고 API Gateway를 사용하는 접근 방식을 제안합니다 .
소개
쇼핑 애플리케이션을 위한 네이티브 모바일 클라이언트를 개발하고 있다고 가정해 보겠습니다. 주어진 제품에 대한 정보를 표시하는 제품 세부 정보 페이지를 구현해야 할 가능성이 높습니다.
예를 들어, 다음 다이어그램은 Amazon Android 모바일 애플리케이션에서 제품 세부 정보를 스크롤할 때 표시되는 내용을 보여줍니다.
스마트폰 앱이긴 하지만, 제품 세부 정보 페이지에는 많은 정보가 표시됩니다. 예를 들어, 기본적인 제품 정보(예: 이름, 설명, 가격)뿐만 아니라 이 페이지에는 다음도 표시됩니다.
모놀리식 애플리케이션 아키텍처를 사용할 때 모바일 클라이언트는 애플리케이션에 단일 REST 호출( )을 하여 이 데이터를 검색합니다. 로드 밸런서는 요청을 N개의 동일한 애플리케이션 인스턴스 중 하나로 라우팅합니다. 그런 다음 애플리케이션은 다양한 데이터베이스 테이블을 쿼리하고 클라이언트에 응답을 반환합니다.GET api.company.com/productdetails/productId
반면, 마이크로서비스 아키텍처를 사용할 때 제품 세부 정보 페이지에 표시된 데이터는 여러 마이크로서비스가 소유합니다. 다음은 예시 제품 세부 정보 페이지에 표시된 데이터를 소유하는 잠재적인 마이크로서비스 중 일부입니다.
모바일 클라이언트가 이러한 서비스에 어떻게 접근할지 결정해야 합니다. 옵션을 살펴보겠습니다.
클라이언트 대 마이크로서비스 직접 통신
이론적으로 클라이언트는 각 마이크로서비스에 직접 요청을 할 수 있습니다. 각 마이크로서비스에는 퍼블릭 엔드포인트( https:// serviceName .api.company.name )가 있습니다. 이 URL은 마이크로서비스의 로드 밸런서에 매핑되며, 로드 밸런서는 요청을 사용 가능한 인스턴스에 분산합니다. 제품 세부 정보를 검색하기 위해 모바일 클라이언트는 위에 나열된 각 서비스에 요청을 합니다.
안타깝게도 이 옵션에는 어려움과 한계가 있습니다. 한 가지 문제는 클라이언트의 요구 사항과 각 마이크로서비스에서 노출된 세분화된 API 간의 불일치입니다. 이 예에서 클라이언트는 7개의 별도 요청을 해야 합니다. 더 복잡한 애플리케이션에서는 훨씬 더 많은 요청을 해야 할 수도 있습니다. 예를 들어, Amazon은 수백 개의 서비스가 제품 페이지를 렌더링하는 데 어떻게 관련되어 있는지 설명합니다. 클라이언트가 LAN을 통해 그렇게 많은 요청을 할 수 있지만, 공용 인터넷에서는 너무 비효율적일 것이고 모바일 네트워크에서는 확실히 비실용적일 것입니다. 또한 이 접근 방식은 클라이언트 코드를 훨씬 더 복잡하게 만듭니다.
클라이언트가 마이크로서비스를 직접 호출하는 또 다른 문제는 일부는 웹 친화적이지 않은 프로토콜을 사용할 수 있다는 것입니다. 한 서비스는 Thrift 바이너리 RPC를 사용하는 반면 다른 서비스는 AMQP 메시징 프로토콜을 사용할 수 있습니다. 어느 프로토콜도 브라우저나 방화벽에 특별히 친화적이지 않으며 내부적으로 사용하는 것이 가장 좋습니다. 애플리케이션은 방화벽 외부에서 HTTP 및 WebSocket과 같은 프로토콜을 사용해야 합니다.
이 접근 방식의 또 다른 단점은 마이크로서비스를 리팩토링하기 어렵게 만든다는 것입니다. 시간이 지남에 따라 시스템을 서비스로 분할하는 방식을 변경하고 싶을 수 있습니다. 예를 들어 두 서비스를 병합하거나 서비스를 두 개 이상의 서비스로 분할할 수 있습니다. 그러나 클라이언트가 서비스와 직접 통신하는 경우 이러한 종류의 리팩토링을 수행하는 것이 매우 어려울 수 있습니다.
이런 종류의 문제 때문에 클라이언트가 마이크로서비스와 직접 통신하는 것은 거의 의미가 없습니다.
API 게이트웨이 사용
일반적으로 훨씬 더 나은 접근 방식은 API Gateway 라고 알려진 것을 사용하는 것입니다 . API Gateway는 시스템에 대한 단일 진입점인 서버입니다. 객체 지향 설계의 Facade 패턴과 유사합니다. API Gateway는 내부 시스템 아키텍처를 캡슐화하고 각 클라이언트에 맞게 조정된 API를 제공합니다. 인증, 모니터링, 로드 밸런싱, 캐싱, 요청 셰이핑 및 관리, 정적 응답 처리와 같은 다른 책임이 있을 수 있습니다.
다음 다이어그램은 API 게이트웨이가 일반적으로 아키텍처에 어떻게 적용되는지 보여줍니다.
API Gateway는 요청 라우팅, 구성 및 프로토콜 변환을 담당합니다. 클라이언트의 모든 요청은 먼저 API Gateway를 거칩니다. 그런 다음 요청을 적절한 마이크로서비스로 라우팅합니다. API Gateway는 종종 여러 마이크로서비스를 호출하고 결과를 집계하여 요청을 처리합니다. HTTP 및 WebSocket과 같은 웹 프로토콜과 내부적으로 사용되는 웹에 친화적이지 않은 프로토콜 간에 변환할 수 있습니다.
API Gateway는 각 클라이언트에 사용자 지정 API를 제공할 수도 있습니다. 일반적으로 모바일 클라이언트에 대한 거친 API를 노출합니다. 예를 들어 제품 세부 정보 시나리오를 생각해 보세요. API Gateway는 모바일 클라이언트가 단일 요청으로 모든 제품 세부 정보를 검색할 수 있는 엔드포인트( /productdetails?productid= xxx )를 제공할 수 있습니다. API Gateway는 다양한 서비스(제품 정보, 추천, 리뷰 등)를 호출하고 결과를 결합하여 요청을 처리합니다.
API 게이트웨이의 좋은 예는 Netflix API Gateway 입니다 . Netflix 스트리밍 서비스는 텔레비전, 셋톱 박스, 스마트폰, 게임 시스템, 태블릿 등 수백 가지 종류의 기기에서 사용할 수 있습니다. 처음에 Netflix는 스트리밍 서비스에 대한 단일 API를 제공하려고 시도했습니다. 그러나 다양한 기기와 고유한 요구 사항으로 인해 제대로 작동하지 않는다는 것을 알게 되었습니다. 오늘날 그들은 기기별 어댑터 코드를 실행하여 각 기기에 맞게 조정된 API를 제공하는 API Gateway를 사용합니다. 어댑터는 일반적으로 평균 6~7개의 백엔드 서비스를 호출하여 각 요청을 처리합니다. Netflix API Gateway는 하루에 수십억 개의 요청을 처리합니다.
API 게이트웨이의 이점 및 단점
예상하셨겠지만 API Gateway를 사용하면 이점과 단점이 모두 있습니다. API Gateway를 사용하는 주요 이점은 애플리케이션의 내부 구조를 캡슐화한다는 것입니다. 특정 서비스를 호출할 필요 없이 클라이언트는 단순히 게이트웨이와 통신합니다. API Gateway는 각 종류의 클라이언트에 특정 API를 제공합니다. 이렇게 하면 클라이언트와 애플리케이션 간의 왕복 횟수가 줄어듭니다. 또한 클라이언트 코드도 간소화합니다.
API Gateway에도 몇 가지 단점이 있습니다. 개발, 배포 및 관리해야 하는 또 다른 고가용성 구성 요소입니다. API Gateway가 개발 병목 현상이 될 위험도 있습니다. 개발자는 각 마이크로서비스의 엔드포인트를 노출하기 위해 API Gateway를 업데이트해야 합니다. API Gateway를 업데이트하는 프로세스는 가능한 한 가벼워야 합니다. 그렇지 않으면 개발자는 게이트웨이를 업데이트하기 위해 줄을 서서 기다려야 합니다. 그러나 이러한 단점에도 불구하고 대부분의 실제 애플리케이션에서는 API Gateway를 사용하는 것이 합리적입니다.
API 게이트웨이 구현
API 게이트웨이를 사용하는 동기와 장단점을 살펴보았으니 이제 고려해야 할 다양한 설계 문제를 살펴보겠습니다.
성능 및 확장성
Netflix 규모로 운영되고 하루에 수십억 개의 요청을 처리해야 하는 회사는 극소수에 불과합니다. 그러나 대부분의 애플리케이션에서 API Gateway의 성능과 확장성은 일반적으로 매우 중요합니다. 따라서 비동기, 비차단 I/O를 지원하는 플랫폼에서 API Gateway를 빌드하는 것이 합리적입니다. 확장 가능한 API Gateway를 구현하는 데 사용할 수 있는 다양한 기술이 있습니다. JVM에서는 Netty, Vertx, Spring Reactor 또는 JBoss Undertow와 같은 NIO 기반 프레임워크 중 하나를 사용할 수 있습니다. 인기 있는 비 JVM 옵션 중 하나는 Chrome의 JavaScript 엔진에 구축된 플랫폼인 Node.js입니다. 또 다른 옵션은 NGINX Plus를 사용하는 것입니다 . NGINX Plus는 쉽게 배포, 구성 및 프로그래밍할 수 있는 성숙하고 확장 가능하며 고성능 웹 서버와 역방향 프록시를 제공합니다. NGINX Plus는 인증, 액세스 제어, 요청 부하 분산, 응답 캐싱을 관리하고 애플리케이션 인식 상태 검사 및 모니터링을 제공합니다.
반응형 프로그래밍 모델 사용
API Gateway는 일부 요청을 적절한 백엔드 서비스로 라우팅하여 처리합니다. 여러 백엔드 서비스를 호출하고 결과를 집계하여 다른 요청을 처리합니다. 제품 세부 정보 요청과 같은 일부 요청의 경우 백엔드 서비스에 대한 요청은 서로 독립적입니다. 응답 시간을 최소화하기 위해 API Gateway는 독립적인 요청을 동시에 수행해야 합니다. 그러나 때로는 요청 간에 종속성이 있습니다. API Gateway는 요청을 백엔드 서비스로 라우팅하기 전에 먼저 인증 서비스를 호출하여 요청을 검증해야 할 수 있습니다. 마찬가지로 고객의 위시리스트에 있는 제품에 대한 정보를 가져오려면 API Gateway는 먼저 해당 정보가 포함된 고객 프로필을 검색한 다음 각 제품에 대한 정보를 검색해야 합니다. API 구성의 또 다른 흥미로운 예는 Netflix Video Grid 입니다 .
기존의 비동기 콜백 방식을 사용하여 API 구성 코드를 작성하면 콜백 지옥에 빠르게 빠질 수 있습니다. 코드가 꼬이고 이해하기 어렵고 오류가 발생하기 쉽습니다. 훨씬 더 나은 방식은 반응형 방식을 사용하여 선언적 스타일로 API Gateway 코드를 작성하는 것입니다. 반응형 추상화의 예로는 Scala의 Future , Java 8의 CompletableFuture , JavaScript의 Promise가 있습니다. 원래 Microsoft에서 .NET 플랫폼용으로 개발한 Reactive Extensions (Rx 또는 ReactiveX라고도 함) 도 있습니다 . Netflix는 API Gateway에서 사용하기 위해 JVM용 RxJava를 만들었습니다. 브라우저와 Node.js에서 모두 실행되는 JavaScript용 RxJS도 있습니다. 반응형 방식을 사용하면 간단하면서도 효율적인 API Gateway 코드를 작성할 수 있습니다.
서비스 호출
마이크로서비스 기반 애플리케이션은 분산 시스템이며 프로세스 간 통신 메커니즘을 사용해야 합니다. 프로세스 간 통신에는 두 가지 스타일이 있습니다. 한 가지 옵션은 비동기 메시징 기반 메커니즘을 사용하는 것입니다. 일부 구현은 JMS 또는 AMQP와 같은 메시지 브로커를 사용합니다. Zeromq와 같은 다른 구현은 브로커가 없고 서비스가 직접 통신합니다. 다른 프로세스 간 통신 스타일은 HTTP 또는 Thrift와 같은 동기 메커니즘입니다. 시스템은 일반적으로 비동기 및 동기 스타일을 모두 사용합니다. 각 스타일의 여러 구현을 사용할 수도 있습니다. 결과적으로 API Gateway는 다양한 통신 메커니즘을 지원해야 합니다.
서비스 발견(Discovery)
API Gateway는 통신하는 각 마이크로서비스의 위치(IP 주소 및 포트)를 알아야 합니다. 기존 애플리케이션에서는 위치를 하드와이어링할 수 있지만, 최신 클라우드 기반 마이크로서비스 애플리케이션에서는 이는 사소한 문제가 아닙니다. 메시지 브로커와 같은 인프라 서비스는 일반적으로 정적 위치를 가지며, 이는 OS 환경 변수를 통해 지정할 수 있습니다. 그러나 애플리케이션 서비스의 위치를 결정하는 것은 그렇게 쉽지 않습니다. 애플리케이션 서비스에는 동적으로 할당된 위치가 있습니다. 또한 자동 확장 및 업그레이드로 인해 서비스 인스턴스 세트가 동적으로 변경됩니다. 결과적으로 API Gateway는 시스템의 다른 서비스 클라이언트와 마찬가지로 시스템의 서비스 검색 메커니즘인 서버 측 검색 또는 클라이언트 측 검색을 사용해야 합니다 . 이후 문서에서 서비스 검색에 대해 더 자세히 설명합니다. 지금은 시스템에서 클라이언트 측 검색을 사용하는 경우 API Gateway가 모든 마이크로서비스 인스턴스와 해당 위치의 데이터베이스인 서비스 레지스트리를 쿼리할 수 있어야 한다는 점에 유의하는 것이 좋습니다 .
부분적 실패 처리
API Gateway를 구현할 때 해결해야 할 또 다른 문제는 부분적 실패 문제입니다. 이 문제는 모든 분산 시스템에서 한 서비스가 느리게 응답하거나 사용할 수 없는 다른 서비스를 호출할 때마다 발생합니다. API Gateway는 다운스트림 서비스를 기다리며 무기한 차단되어서는 안 됩니다. 그러나 실패를 처리하는 방법은 특정 시나리오와 실패하는 서비스에 따라 달라집니다. 예를 들어, 추천 서비스가 제품 세부 정보 시나리오에서 응답하지 않으면 API Gateway는 사용자에게 여전히 유용하므로 나머지 제품 세부 정보를 클라이언트에 반환해야 합니다. 추천은 비어 있거나 예를 들어 하드와이어된 상위 10개 목록으로 대체될 수 있습니다. 그러나 제품 정보 서비스가 응답하지 않으면 API Gateway는 클라이언트에 오류를 반환해야 합니다.
API Gateway는 캐시된 데이터가 사용 가능한 경우 이를 반환할 수도 있습니다. 예를 들어, 제품 가격이 자주 변경되지 않으므로 가격 서비스를 사용할 수 없는 경우 API Gateway는 캐시된 가격 데이터를 반환할 수 있습니다. 데이터는 API Gateway 자체에서 캐시하거나 Redis 또는 Memcached와 같은 외부 캐시에 저장할 수 있습니다. 기본 데이터 또는 캐시된 데이터를 반환함으로써 API Gateway는 시스템 장애가 사용자 경험에 영향을 미치지 않도록 합니다.
Netflix Hystrix 는 원격 서비스를 호출하는 코드를 작성하는 데 매우 유용한 라이브러리입니다. Hystrix는 지정된 임계값을 초과하는 호출을 시간 초과합니다. 이는 클라이언트가 응답하지 않는 서비스를 불필요하게 기다리지 않도록 하는 회로 차단기 패턴을 구현합니다. 서비스의 오류율이 지정된 임계값을 초과하면 Hystrix가 회로 차단기를 작동시키고 모든 요청은 지정된 기간 동안 즉시 실패합니다. Hystrix를 사용하면 캐시에서 읽거나 기본값을 반환하는 것과 같이 요청이 실패할 때 대체 작업을 정의할 수 있습니다. JVM을 사용하는 경우 Hystrix를 사용하는 것을 고려해야 합니다. 그리고 비 JVM 환경에서 실행하는 경우 동등한 라이브러리를 사용해야 합니다.
요약
대부분의 마이크로서비스 기반 애플리케이션의 경우, 시스템에 대한 단일 진입점 역할을 하는 API Gateway를 구현하는 것이 합리적입니다. API Gateway는 요청 라우팅, 구성 및 프로토콜 변환을 담당합니다. 각 애플리케이션 클라이언트에 사용자 지정 API를 제공합니다. API Gateway는 캐시된 데이터나 기본 데이터를 반환하여 백엔드 서비스의 오류를 마스크할 수도 있습니다. 이 시리즈의 다음 기사에서는 서비스 간 통신을 살펴보겠습니다.
위 내용과 같이 NGINX Plus 를 활용하여 Demo 가 필요하시면 하단의 전문가에게 상담받기 버튼을 클릭해주세요
전문가에게 상담받기