Handling Partial Failure
(부분적인 실패 처리)

API Gateway에 대해 이전 article에서 논의한 것처럼, 분산 시스템에서는 부분적인 실패에 대한 리스크가 항상 존재한다. Client와 service가 분리되어 있는 프로세스이기 때문에, service는 client의 요청에 대해 적기에 응답할 수 없을지도 모른다. Service는 실패나 유지보수 때문에 다운될지도 모른다. 혹은 service가 과부하로 인해 요청에 대해 극도로 느리게 응답할지도 모른다.

예를 들면, Product details scenario(상품 상세 정보 시나리오) article을 생각해 보라. Recommendation Service(추천 서비스)가 응답하지 못하는 상황을 상상해 보라. Client가 본래 실행할 기능은 응답을 무기한 기다리면서 중단될지도 모른다. 사용자 경험 측면에서 좋지 못한 결과일 뿐만 아니라 많은 어플리케이션에서 thread와 같은 값비싼 리소스를 사용하게 된다. 결국 실행환경에서 thread를 모두 사용하고, 다음 그림에서 보여주는 것처럼 응답할 수 없는 상황이 된다.


사용자 삽입 이미지

이 문제를 예방하기 위해서는 부분적인 실패를 처리할 수 있도록 서비스를 디자인하는 것이 필수적이다.

Netflix에서 설명하고 있는 한가지 방법을 따라가는 것도 좋은 접근 방법이다.
부분적인 실패를 다루기 위한 전략에는 다음 내용들이 포함되어 있다.

  - 네트워크 타임아웃(Network timeouts) : 응답을 기다리고 있는 동안 결코 무한 대기하지 말고, 항상 타임아웃을 사용하라. 타임아웃을 사용하는 것은 리소스가 무한히 묶여 있지 않도록 해준다.
  - 대기 요청 숫자의 제한(Limiting the number of outstanding requests) : Client가 특정 서비스에 가질 수 있는 대기 요청 숫자의 상한선을 정하라. 만약 제한된 숫자에 도달하게 되면, 추가적인 요청을 만드는 것은 무의미할 것이다. 그리고 그러한 시도들은 즉시 실패처리할 필요가 있다.
  - 자동 차단 패턴(Circuit breaker pattern) : 성공적으로 수행된 요청과 실패한 요청의 숫자를 추적하라. 만약 오류 비율(error rate)이 설정된 한계값을 넘어간다면, 자동 차단기를 작동시키고 추가적인 시도들은 즉시 실패하게 된다. 만약 많은 요청들이 실패하게 된다면, 서비스 이용불가로 추측되기 때문에 요청을 보내는 것은 무의미하다. 타임아웃 기간이 지나고 나서 Client는 다시 시도하게 되고, 만약 성공한다면 자동 차단기를 닫는다.
  - 대비책을 제공하라(Provide fallback) : 요청이 실패했을 경우에는 대비하는 로직을 수행하라. 예를 들면, 추천 정보들이 비어있을 경우에는 캐시된 데이터나 기본 값을 리턴하라.

Netflix Hystrix는 이러한 circuit breaker 패턴과 다른 패턴들을 구현한 오픈소스 라이브러리이다. 만약 JVM을 사용한다면, Hystrix를 사용하는 것을 분명히 고려해야 한다. 그리고 non-JVM환경에서 구동하고 있다면, 동등한 라이브러리를 사용해야 한다.
받은 트랙백이 없고, 댓글이 없습니다.

댓글+트랙백 RSS :: http://www.yongbi.net/rss/response/762

Evolving APIs
(API의 발전)

서비스의 API는 시간이 지남에 따라 예외없이 변한다. Monolithic 어플리케이션에서는 일반적으로 API를 변경하고 모든 호출자들을 업데이트하는 것이 쉽다. Microservice 기반 어플리케이션에서는 매우 더 어렵다. 심지어 여러분의 API를 호출하는 모두가 동일 어플리케이션의 다른 서비스들일지라도 쉽지 않다. 일반적으로 모든 client가 서비스에 발맞추어 업그레이드하도록 강제할 수 없다. 또한, 여러분은 아마도 이전 버전의 서비스와 새로운 버전의 서비스가 모두 동시에 돌아가고 있는 상황에서 신규 서비스를 배포하는 경우가 증가할 것이다. 이러한 이슈들을 다루기 위한 전략을 가지고 있는 것이 중요하다.

API 변경을 어떻게 다루는지는 변경의 크기에 달려 있다. 어떤 변경 사항들은 작고, 이전 버전과 호환성을 갖는다. 예를 들어, 여러분이 요청이나 응답에 속성을 추가하려고 할지도 모른다. Client나 service를 디자인하여 robustness principle을 보고 아는 것은 좋다.
(robustness principle : 내가 하는 것은 보수적으로, 상대방의 것을 받아들일 때는 자유롭게)

오래된 API를 사용하는 Client는 서비스의 새로운 버전으로도 잘 동작할 것이다. 서비스는 추가된 속성을 빠뜨린 요청에 대해서 기본값을 보내고, Client는 추가된 응답 속성들은 무시할 것이다. 여러분의 API를 쉽게 발전시키기 위해서 IPC 메커니즘과 messaging format을 사용하는 것은 중요하다.

그러나, 때로는 중요하고 호환 불가능하게 API를 변경해야만 할때도 있다. Client들에게 즉시 업그레이드하도록 강제할 수 없기 때문에 서비스는 어느 일정 기간 동안 이전 버전의 API를 지원해야만 한다. 만약 REST와 같은 HTTP기반 메커니즘을 사용했다면, 한가지 접근 방법은 URL에 버전 숫자를 포함시키는 것이다. 각 서비스 인스턴스는 동시에 여러 가지 버전을 처리할 것이다. 그렇지 않으면 각각의 인스턴스에서 특정 버전을 처리하도록 서로 다른 인스턴스에 배포할 수도 있다.

받은 트랙백이 없고, 댓글이 없습니다.

댓글+트랙백 RSS :: http://www.yongbi.net/rss/response/761

Defining APIs
(API 정의)

서비스의 API는 서비스와 Client 사이의 계약이다. 여러분이 어떤 IPC 메커니즘을 선택했느냐에 상관없이 서비스의 API가 어떤 종류의 IDL(Interface Definition Language)을 사용하도록 정확하게 정의되었느냐가 중요하다. 서비스를 정의하기 위해 API-first Approach를 사용하는데 대한 좋은 논쟁들이 있다.(https://www.programmableweb.com/news/how-to-design-great-apis-api-first-design-and-raml/how-to/2015/07/10)

여러분은 서비스의 인터페이스를 정의하고, Client 개발자들과 함께 그것을 리뷰하면서 서비스 개발을 시작한다. 그것은 여러분이 구현한 서비스의 API 정의를 반복하는 것이다. 먼저 이렇게 디자인함으로써, Client의 요구사항을 더 많이 만족시킬 수 있는 여러분의 서비스를 구현할 수 있다.

이번 article의 후반부에서 볼 수 있겠지만, API 정의의 본질적인 부분은 여러분이 사용한 IPC 메커니즘에 달려 있다. 여러분이 messaging을 사용했다면, API는 message channel과 message type으로 구성되어 있다. 만약 HTTP를 사용했다면, API는 URL과 request, response format으로 구성되어 있다. 나중에 IDL에 대해 더 자세히 정리할 것이다.

받은 트랙백이 없고, 댓글이 없습니다.

댓글+트랙백 RSS :: http://www.yongbi.net/rss/response/760

Interaction Styles
(상호작용 형태)

서비스에 대한 IPC 메커니즘을 고르느느 경우, 서비스가 어떻게 상호작용 하는지를 먼저 생각보면 유용하다. Client와 서비스간 상호 작용 형태는 다양하다. 2가지 관점에 따라 카테고리지어질 수 있다. 첫번째 관점은 상호작용이 one-to-one 인지, one-to-many 인지에 대한 것이다.
 
  - One-to-one : Client의 각 요청은 정확하게 하나의 서비스 인스턴스에 의해 처리된다.
  - One-to-many : 각 요청은 여러 서비스 인스턴스에 의해 처리된다.

두번째 관점은 상호작용이 Syncronous(동기)인지 Asynchronous(비동기)인지에 대한 것이다.

  - Synchronous : Client는 서비스로부터 시기적절한 응답을 기대하고, 기다리는 동안은 대기한다.
  - Asynchronous : Client는 응답을 기다리는 동안 대기하지 않는다. 그리고 만약에 있다면 즉시 응답을 보낼 필요가 없다.

다음 표는 다양한 상호작용 형태를 보여준다.

 One-to-OneOne-to-Many
SynchronousRequest/Response-
AsynchronousNotificationPublish/Subscribe
Request/Async ResponsePublish/Async Responses

One-to-One 상호작용에는 다음과 같은 종류가 있다.

  - Request/Response : Client는 서비스로 요청을 보내고, 응답을 기다린다. Client는 시기 적절하게 응답을 받을 수 있기를 기대한다. Thread기반 어플리케이션에서는 thread가 요청을 하고, 기다리는 동안 대기하고 있을 것이다.
  - Notification (단방향 요청으로도 알려짐): Client는 비동기적으로 응답하는 서비스로 요청을 보낸다. Client는 기다리는 동안 대기하지 않는다. 그리고 얼마 동안은 응답이 도착하지 않는다고 가정하고 설계된다.

One-to-Many 상호작용에는 다음과 같은 종류가 있다.

  - Publish/Subscribe : Client는 0개 이상의 관련된 서비스에서 소비되는 Notification message를 발행한다.
  - Publish/Async Responses : Client는 요청 메시지르르 발행하고, 관련된 서비스로부터의 응답을 정해진 시간 동안 기다린다.

각 서비스는 일반적으로 이러한 상호작용 형태를 조합하여 사용한다. 어떤 서비스들에 대해서는 하나의 IPC 메커니즘으로도 충분하다. 다른 서비스들은 IPC 메커니즘의 조합을 사용하는 것이 필요하다. 다음 다이어그램은 택시 호출 어플리케이션에서 사용자들이 이동을 요청했을 때, 어떻게 서비스들이 상호작용 하는지를 보여준다.

사용자 삽입 이미지


서비스들은 Notification, request/response, publish/subscribe를 조합하여 사용한다. 예를 들면, 승객의 스마트폰은 pickup을 요청하기 위해 Trip Management Service에 Notification을 보낸다. Trip Management Service는 Passenger Service를 호출하기 위해서 request/response를 사용하여 승객의 계정이 활성화되어 있는지 검증한다. 그리고 나서 Trip Management Service는 택시호출을 생성하고, Dispatcher(차량 배치 담당 서비스)를 포함하여 가용가능한 운전사 위치를 다른 서비스들에게 알리기 위해 publish/subscribe를 사용한다.

지금까지 우리는 상호작용 형태에 대해서 살펴보았는데, 이제 어떻게 API를 정의하는지에 대해서 알아보자.
받은 트랙백이 없고, 댓글이 없습니다.

댓글+트랙백 RSS :: http://www.yongbi.net/rss/response/759

Building Microservices: Inter-Process Communication in a Microservices Architecture

Introduction

Monolithic Application에서 컴포넌트들은 language-level method나 function call을 통해 서로를 호출한다. 반대로, microservice기반 application은 여러 대의 machine에서 동작하고 있는 분산 시스템이다. 각 서비스 인스턴스는 일반적으로 프로세스이다. 결과적으로 다음 다이어그램에서 보는 것처럼, 서비스들은 inter-process communication(IPC) 메커니즘을 사용하여 상호작용해야만 한다.

사용자 삽입 이미지




나중에 특정 IPC 기술들에 대해서 들여다보겠지만, 먼저 다양한 디자인 이슈에 대해서 먼저 분석해 보자.

받은 트랙백이 없고, 댓글이 없습니다.

댓글+트랙백 RSS :: http://www.yongbi.net/rss/response/758