Service Discovery
Service Discovery
서비스는 다른 서비스를 호출하거나, 다른 서비스에 의해서 호출을 당한다. monolithic architecture 에서는 메소드 호출이나, 프로시저 호출을 이용하여 호출을 한다.
전통적인 분산 시스템은 고정된 서비스 엔드포인트를 이용하여 접근한다. (서비스 IP/port 를 활용) 그리고 REST API 나, rpc 메커니즘 등을 이용한다.
현대의 마이크로 서비스 시스템은, 가상화 되거나 컨테이너화 된 시스템 에서 수행된다. 이들 위치는 고정할 수 없으며, 특정 순간 동적으로 변화하고 있다.
결론적으로 서비스 클라이언트는 서비스 서버의 동적인 엔드포인트 변경에 상관없이 접근이 가능해야한다.
필요사항
- 서비스 인스턴스는 각각 원격 API인 (REST api, thrift 과 같은 특정 로케이션(IP/PORT) 로 접근해야한다.)
- 서비스 인스턴스의 수와 그들의 위치 정보는 동적으로 변경된다.
- 가상 머신과 컨테이너는 보통 동적인 IP주소를 할당 받는다.
- 서비스 인스턴스의 숫자는 매우 동적이다. 예를 들어 EC2 ASG 는 로드에 따라서 인스턴스의 수를 변경한다.
Client side service discovery
서비스를 요청하는 클라이언트는 Service Registry 에 직접 호출하여 인스턴스의 위치 정보를 조회해 간다. Service Registry 는 모든 서비스 인스턴스의 위치를 알 고 있다.
장점
- Service side discovery 에 비해서 더 적은 네트워크 홉을 가진다.
단점
- 클라이언트는 Service Registry 와 결합 되어 있다.
- 클라이언트 서비스 디스커버리 로직을 구현해야한다.
Service side service discovery
- 클라이언트가 특정 서비스에 요청을 하고 하면 클라이언트는 라우터에 연결을 한다.
- 라우터는 일명 Load Balancer 이라고도 불르며, 이미 알려진 위치 정보를 미리 알고 있다.
- 라우터는 서비스 레지스터리에 쿼리를 보낸다.
- 라우터는 요청을 대상 서비스로 전달한다.
예제
- AWS 의 ELB 는 서버사이드 이스커버리 라우터이다.
- 클라이언트는 HTTP 요청을 생성하여, ELB 에 전달한다.
- ELB 는 대상 그룹에 전달하고, 대상그룹 내 특정 서비스에 요청이 전달되게 된다.
- 몇가지 클러스터링 솔루션인 Kubernetes 와 Marathon 은 각 호스트의 프록시로 동작하며, 이는 server-side discovery router 로 동작한다.
- 서비스에 접근하기 위해서 클라이언트는 할당된 서비스로 접근하기 위해서 로컬 프록시에 연결된다.
- 프록시는 요청을 서비스에 전달한다.
장점
- 클라이언트 사이드 디스커버리에 비해서 클라이언트 코드가 단순해진다. 즉, 클라이언트가 디스커버리를 담당하지 않아도 된다.
- 대신 클라이언트는 라우터에 연동된다.
단점
- 클라우드의 한 부분이 아니라면 라우터는 반드시 다른 시스템 커포넌트로 존재해야하며, 이는 설치 및 설정이 필요함을 의미한다.
- 또한 가용성과 캐퍼시티를 위해서 복제 되어야한다.
- 라우터는 반드시 필요한 커뮤닠이션 프로토콜을 구현해야한다. (HTTP, gRPC, Thrift 등)
- 더 많은 네트워크 홉이 발생한다.
Service Registry
- 서비스 컨텍스트는 클라이언트 혹은 서버 사이드 디스커버리를 이용한다.
- 클라이언트는 서비스 요청을 디스커버리에 호출한다.
-
필요사항
- 서비스 인스턴스는 원격 API 를 드러내어야한다. 이는 HTTP / Thrift / rpc 등이 있을 수 있다.
- 서비스 인스턴스 수와 이들 위치는 동적으로 변경될 수 있다.
- 이를 해결하기 위해서 서비스가 등록되어야한다. 서비스 레지스터리는 서비스의 위치를 저장하는 데이터베이스 역할을 한다.
- 서비스 인스턴스는 서비스 레지스터리에 등록이 되며, 서비스의 시작과 종료시에 등록이 되거나 해제된다.
- 서비스의 클라이언트는 서비스 레지스터리에 요청을 하여 필요한 서비스를 찾아간다.
장점
- 서비스의 클라이언트와 라우터들은 서비스 인스턴스를 자동으로 찾아낸다.
단점
- 인프라스트럭쳐로 등록되지 않으면, 다른 인프라 스트럭처에서는 등록이 되어야한다. 설정되고, 관리가 되어야한다.
- 나아가 서비스 레지스터리는 핵심 시스템 컴포넌트이다.
당신은 다음 3개의 서비스 인스턴스를 결정하기 위해 서비스 디스커버리할 일이 필요하다.
- self registration pattern: 서비스 인스턴스가 스스로 등록이 되어야한다.
- 3th parth registration pattern: 서비스 등록기에 설정된 서비스 인스턴슬를 등록한다.
서비스 레지스터리 클라이언트는 등록된 서비스의 위치와 인스턴스를 알고 있어야한다. 서비스 등록 인스턴스는 반드시 알려진 IP 주소에 의해서 고정되어야한다. 클라이언트는 이 IP 에 접속해서 서비스를 찾아간다.
Self Registration
- Service Discovery 에는 서비스 인스턴스와 로케이션이 등록된다.
-
이때 서비스는 스스로 등록을 해야한다.
- 서비스 인스턴스는 시작/종료시에 서비스 레지스터리에 등록/해제가 되어야한다.
- 서비스 인스턴스들은 크래쉬 되는경우 서비스 레지스터리에서 해제가 되어야한다.
-
서비스 인스턴스가 요청을 처리할 수 없을경우 자동으로 레지스터리에서 해제가 되어야한다.
- 서비스 인스턴스는 스스로 자신을 서비스 레지스터리에 등록을 해야하며, 클라이언트는 특정 주기로 자신이 캐시해둔 서비스 인스턴스 정보를 릴리즈 해야한다.
장점
- 서비스 인스턴스는 자신의 상태를 잘 알고 있으며, 서비스 디스커버리에서 자신이 제외되어야할지, 등록되어야할지를 알고 있다.
단점
- 서비스는 서비스 레지스터리와 커플링 된다.
- 반드시 서비스 등록 로직을 구현해야한다.
- 서비스 인스턴스는 요청을 처리할 수 없는 경우 등록을 보류 해야하며, 서비스 레지스터리로 부터 등록을 해제하기 위해서 스스로 인지해야하며, 이를 구현하기가 쉽지 않다.