우리네 장

[ MSA ] Netflix Eureka 본문

MSA

[ MSA ] Netflix Eureka

qpmi1zm29 2023. 3. 6. 15:22

[ Netfilx Eureka ]

- MSA에서 Service Registry 의 역할과 Discovery Server ( Naming Server ) 를 구현하는데 사용할 수 있는 Spring cloud 내 API이다.

 

- Discovery Server에 마이크로 서비스들이 <서비스 이름> : <위치> 정보를 key:value 형태로 저장하고 있다.

 

- 외부에서 서비스 요청이 들어왔을 때, Load-Balancer나 API Gateway로 요청이 넘어오면, Discovery Server에게 해당 요청에 맞는 서비스가 어디에 있는지 위치를 물어본다. 

 

D/S는 위치 정보를 다시 Load-Balancer나 API Gateway로 넘겨주게 되면 그 정보를 바탕으로 해당하는 서버로 요청 정보를 보내준다.

 

- Discovery Server가 하는 역할은 MSA의 등록/검색 이라고 할 수 있다.

 

- Discovery Server는 웹 서비스의 형태로 기능을 제공한다. 

 

- Discovery Server에 MSA를 등록해야 하므로, pipeline에서 해당 서비스가 제일 먼저 기동이 되어야 할 것으로 생각된다.

 

- naming 서버를 사용했을 때의 장점은 로드 밸러서나 게이트웨이에서 하드코딩으로 msa 서비스의 주소를 관리하지 않아도 된다는 점이다.

 

[ Spring Boot - Netfilx Eureka Server]

spring cloud의 버전은 사용하는 boot 버전에 종속된다.

 

Boot가 기동될 때, main()가 들어있는 해당 Application class가 Bootstrap처럼 가장 먼저 기동이 되는데,

이는 @SpringBootApplication 을 Boot가 인식해 시작 class로 인식하기 때문이다.

 

위 프로젝트가 유레카 서버로 작동하기 위해서는 라이브러리 import 뿐만 아니라, 해당 서버가 유레카 서버임을 부트에게 알려주어야 한다. 이를 위해서 메인 class에 @EnableEurekaServer를 사용해준다.

 

application.yml

부트에서 프로젝트 생성 시 기본으로 제공하는 설정파일인 properties 대신에 yml 파일을 사용하였다.

위 속성 중 [ spring.application.name ] 이 유레카가 어플리케이션을 등록할 때 사용하는 key (ID) = 어플리케이션 이름 이다.

 

또한 eureka 라이브러리를 starter로 등록할 때, client 관련 라이브러리도 같이 주입이 되는데,

부트가 기동 될 때 해당 라이브러리가 존재하면, 그 서버를 자동으로 유레카에 등록하려고 시도 한다. 

( 등록을 위해서는 추가적으로 유레카 서버에 대한 정보가 설정 파일에 있어야 함. )

 

그러나 유레카 서버는 외부 서비스가 호출해서 사용하는 서버가 아니므로 등록할 필요가 없어,

[ eureka.client.fetch-registry / .register-with-eureka ] 속성은 false로 설정한다. 

 

 

 

[ Spring Boot - Netfilx Eureka Client ]

 

유레카 서버에서 @EnableEurekaServer 를 설정해 준 것처럼, 유레카에 등록하고자 하는 어플리케이션에도 위 어노테이션을 붙여 스프링 부트에서 유레카 클라이언트 임을 인지시켜 준다.

 

application.yml 파일에 유레카 클라이언트를 위한 설정을 해준다.

1) server.port : 0

유레카 서버는 클라이언트들이 접속하여 본인들을 등록해야 하고, load-balancer나 api gateway가 찾아갈 수 있어야 하므로 고정 port값이 필요하다. 또한 인스턴스의 개수를 유동적으로 하여 사용할 일도 적다.

 

그러나, msa들은 사용량 증가에 따라 auto scaling 설정을 통해 하나의 서비스의 인스턴스 개수가 증가/감소 할 수 있는데, 이때 띄워진 인스턴스를 이미지로 복사하여 증가/감소를 하므로, 설정 파일에 지정된 포트에 충돌이 일어날 수 있다.

 

그래서 유레카 서버처럼 고정된 포트 값을 사용하는 것이 아닌, 랜덤 포트를 사용하는 것이 권장된다. 

server.port 설정을 0으로 해놓으면 랜덤 포트를 사용하겠다는 의미이다.

 

그런데 위치 정보 표기 시, 서버 장비의 ip를 사용하므로, 동일 서비스의 인스턴스가 각기 다른 ip를 가진 장비에 위치하게 된다면, 굳이 0번을 사용하지 않아도 ip로 구분지을 수 있을 것 같다.

 

 

2) eureka.client.fetch-registry : true

해당 설정은 유레카에 등록된 인스턴스 정보를 주기적으로 가져오겠다는 설정이다.

 

3) service-url : defaultZone : http://localhost:8761/eureka

msa가 유레카 클라이언트로써 유레카 서버에 등록할 때 호출하게 되는 주소이다.

위 eureka라는 context에 추가적인 path를 붙여 어플리케이션을 등록시킨다.

 

 

 

그런데, 유레카는 등록된 서비스의 위치 정보를 application.yml 파일을 이용하기 때문에, 랜덤 포트를 사용하기 위해 위와 같은 정보로 같은 서비스를 제공하는 인스턴스를 여러 개 띄우면  유레카 서버에서 1개로 인식하게 된다.

 

 

 

이를 해결하기 위해, 설정 파일에 인스턴스 고유의 아이디를 할당하는 설정이 있다.

 

반드시 위 환경변수 값으로 해야하는 것은 아니다.

 

설정 후, 유레카를 새로고침 하게되면,

 

위처럼 두 개의 인스턴스가 실행 가능 중인것으로 나온다.

사용하는 포트 정보를 알고 싶으면 클릭을 하거나 마우스를 대면 포트정보가 하단에 노출되게 된다.

 

 

이렇게 msa에 대한 인스턴스들을 discovery server에 등록시켜 놓으면,

관련 서비스 요청이 들어왔을 때, 이에대한 정보를 load-balancer나 api gateway가 discovery server에게 질의하게 되고,

discovery server가 위치 정보를 load-balancer나 api gateway에게 전달해주면, 전달받은 내용을 토대로 사용자 요청을 해당하는 서비스의 인스턴스들 중 하나로 보내게 된다.

 

랜덤 포트를 사용할 때의 장점은,

1) auto scaling 시 port 충돌을 막을 수 있다.

 

2) 포트 정보는 환경 설정 정보로 소스코드 내부가 아닌 외부에서 설정하는 것이 좋은데,

외부에서 설정하기 위해 실행 명령어가 길어지는 것을 방지할 수 있다.

-Dserver.port 옵션 생략 가능