Spring Cloud Netflix Eureka
- 우리가 만든 Microservice 는 Spring Cloud Netflix Eureka 에 등록을 해야한다.
- Eureka 가 해주는 역할을 ServiceDiscovery 라고 한다.
- 일종의 전화번호부 책이라고 생각하면 된다. (key:value 형태)
- 즉 어떠한 서비스가 어느 위치에 있는지 알려주는 역할 , 서비스 등록 및 서비스 검색을 해주는게 바로 ServiceDiscovery
- ServiceDiscovery 을 Eureka 로 구현을 한다고 생각하면 된다.
진행 흐름
- 먼저 만든 Micoservice 를 유레카 서버에 등록하는 작업을 먼저 한다.
- 해당 Micoservice 를 사용하고 싶은 클라이언트는 Load Balancer , API Gateway 에다가 요청 정보를 전달한다.
- 해당 요청 정보를 받으면 ServiceDiscovery 에 전달되고 해당 요청을 처리할 Service 가 어디에 있는지를 알려준다.
- 그것을 받은 Load Balancer , API Gateway 는 해당 서비스로 이동을 하고 그 결과값을 클라이언트에게 전달을 해준다.
프로젝트 생성
- 빌드 도구는 Maven 를 선택했고, Spring Cloud 에서 Eureka Server 라이브러리만 의존성을 추가해줬다.
- 그런후 Main 함수가 있는 클래스에 @EableEurekaServer 을 붙혀준다.
- 이것을 붙혀줘야 유레카 서버로 등록을 할 수 있다.
yml 파일
- 유레카 서버를 Web Service 로 포트 번호를 설정해줘야 한다. (8761 로 설정)
- Microservice 아이디를 부여해줘야 하는데 spring:application:name 으로 지정해줘야한다.
- eureka:client 에서 register-with-eureka , fetch-registry 를 모두 false 값을 지정해줬다.
- 기본값은 true 인데 자신의 정보를 자신한테 등록하는 현상이기 때문에 의미가 없어 false 를 준다.
이렇게 설정한 후 서버를 기동하면 Eureka 기본 대시보드가 나오는 것을 확인할 수 있다.
- 여기에 Micoservice 를 등록하면 대시보드에도 추가가 된다.
User Service 프로젝트 생성
새로운 Project 를 만들고 아래와 같은 의존성을 추가했다. (user-service)
- Eureka Discovery Client , Lombok , Spring Web
- 위에서 유레카 서버를 만들고 이제 유레카 클라이언트를 만들었다고 생각하면 된다.
- Main 함수에 @EnableDiscoveryClient 를 붙혀준다.
yml 설정
- port 는 9001 으로 설정했고 application:name 은 user-service 로 지정했다.
- eureka:client: 에서 register-with-eureka , fetch-registry 모두 true 를 설정했다.
- true 를 주게 되면 Eureka 서버로부터 인스턴스(user-service) 의 정보를 주기적으로 가져올 수 있도록 설정한다.
- service-url: defaultZone 도 설정을 해야하는데 여기에는 위에서 만들었던 Eureka Server 의 도메인주소/eureka 를 넣어주면 된다.
- 즉 Eureka Server 의 엔드포인트 정보를 넣어주면 된다.
이렇게 설정하고 user-service 의 서버를 기동한 후 위에서 확인했던 Eureka 기본 대시보드에 들어가면 우리가 만든 user-service 가 등록되어있는 것을 확인할 수 있다.
User Service - 등록
- 또 하나의 user-service 를 만들려고 했지만 위에서 만들었던 user-service 랑 거의 비슷하기 때문에 그대로 가져오고 싶다.
- 직접 또 하나의 프로젝트를 만들어도 되지만 Edit Configuration 에 들어가서 왼쪽 부분에 + - 옆에 카피할 수 있는 버튼이 있다.
- 그것을 누르면 바로 카피가 되고 이름만 user-service 2 로 적절하게 바꿔주면 된다.
이렇게 user-service 2 를 실행하게 되면 port 충돌로 인해 서버가 실행되지 않는다.
- yml 파일에서 다른 port 번호로 바꾸면 된다고 생각하지만 이렇게 하드코딩된 파일을 수정하면 다시 기동해야 하는 문제가 발생한다.
- 이렇게 하지 않고 VM option 으로 -Dserver.port=9002 을 주면 알아서 애플리케이션이 실행될 때 9002 port 로 설정이 된다.
실행해보고 Eureka 대시보드에 들어가보자.
- user-service 에서 Availavility Zones 에서 2개로 업데이트가 됐고, URI 도 9001 , 9002 가 있는 것을 확인했다.
Gateway , RoutingService 에서 이 2개 중에 어디로 갈지 결정하게 된다.
인텔리J 에서 직접 만들고 Run 하는 방식이 아닌 터미널에서 maven 명령어로 실행하는 방법
mvn spring-boot:run -Dspring-boot.run.jvmArguments='-Dserver.port=9003'
터미널에서 위와 같이 실행하면 port 번호가 9003 인 인스턴스가 생기게 된다.
- Eureka 대시보드에 가면 3개가 등록된것을 확인할 수 있다.
이렇게 port 번호를 하나씩 바꿔가면서 인스턴스를 만드는것은 사실 귀찮은 작업일 수 있다.
- 다음에 스프링 부트에서 간단하게 처리할 수 있는 방법을 알아보자.
User Service - Load Balancer
간단한 방법 (Random port)
server:
port: 0
user-service 에서 yml 파일에 위에 처럼 server port 를 0 으로 지정해주면 된다.
- 0 으로 주면 Random port 를 사용하고, 포트의 충돌을 의식하지 않고 계속 서비스 인스턴스를 실행할 수 있는 장점을 가지고 있다.
- 위에서 Edit Configuration 에서 만들었던 인스턴스를 삭제하고 실행해야 한다.
- 그렇게 실행하면 서버가 실행되면서 나오는 로그를 보면 Tomcat started on port 에서 포트 번호를 알 수 있거나, Eureka 대시보드에 들어가보면 0 으로 표시되어 있는데 마우스 커서를 올리면 왼쪽 하단에 포트 번호가 나오기도 한다.
이렇게 하면 터미널에서 mvn spring-boot:run 명령어만 실행해도 인스턴스가 실행이 된다.
- 원래는 포트 번호까지 지정을 해줘야 했지만 Random port 를 사용하기 때문에 해당 명령어만 실행하면 임의의 포트 번호가 할당 된다.
- 이렇게 실행하고 Eureka 대시보드에 들어가보면 2개가 아닌 1개만 실행되고 있다..
- 그 이유는 현재 작동중인 HostAddressIP+ServiceName (yml 파일에 지정한 이름)+포트번호 를 기준으로 표시를 하기 때문이다.
- 그래서 모두 같기 때문에 1개로 나오고 있는 것이다.
eureka:
instance:
instance-id: ${spring.cloud.client.hostname}:${spring.application.instance_id:${random.value}}
- 위와 같은 문제를 해결하기 위해 yml 파일에 위와 같은 설정을 더 추가해야한다.
- 그런후 인스턴스를 다시 실행하고 (mvn spring-boot:run) 다시 대시보드에 들어가보면 2개로 나오는 것을 확인했다.
참고자료