외부의 서비스들이 마이크로서비스를 검색하기 위해 사용하는 곳으로, 각각의 마이크로서비스가 어느 위치에 있는지 등록해 놓은 곳이다.
Spring Cloud Netflix Eureka
가 Service Discovery 역할을 제공한다.
요청 정보가 Load Balancer(API Gateway)에 전달되면 다음으로 Service Discovery에 전달된다. 그럼 Service Discovery는 필요한 서비스가 어느 곳에 있는지에 대한 정보를 API Gateway로 반환하고 Api Gateway는 이에 따라 해당 서비스를 호출하고 결과를 받는다.
Dependency에 Spring Cloud Discovery > Eureka Server
를 추가한다.
Maven을 선택했기 때문에 pom.xml에 들어가 dependency를 확인해준다.
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.0.6</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>ecommerce</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>ecommerce</name>
<description>ecommerce</description>
<properties>
<java.version>17</java.version>
<spring-cloud.version>2022.0.2</spring-cloud.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
<repositories>
<repository>
<id>netflix-candidates</id>
<name>Netflix Candidates</name>
<url>https://artifactory-oss.prod.netflix.net/artifactory/maven-oss-candidates</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
</project>
${AppName}Application.java는 spring boot 프로젝트가 시작될 때 제일 먼저 실행되는 파일이다. 해당 파일에서 @EnableEurekaServer
을 추가해 EurekaServer로서의 자격을 명시한다.
@SpringBootApplication
@EnableEurekaServer
public class DiscoveryserviceApplication {
public static void main(String[] args) {
SpringApplication.run(DiscoveryserviceApplication.class, args);
}
}
# 유레카 서버가 웹서비스의 성격으로 구동된다.
server:
port: 8761
# 마이크로서비스를 담당하는 스프링부트 프레임 워크에 각각의 마이크로서비스에 고유한 아이디를 부여하는 설명
spring:
application:
name: discoveryservice
# 현재 프로젝트는 유레카 서버이므로 클라이언트 역할로 자동으로 등록되는 세팅을 막아주는 설정
eureka:
client:
register-with-eureka: false
fetch-registry: false
실행시킨 후 http://localhost:8761/
에 들어가주면 요런 화면이 나온다.
API Gateway는 모든 클라이언트의 요청을 받아 설정해 놓은 라우팅 설정에 따라서 각각의 endPoint로 클라이언트 대신에 요청을 보내고 응답을 받아 클라이언트에게 전달하는 프록시 역할을 한다.
-> 이렇게 되면 시스템 내부 구조는 숨기고 외부의 요청에 대해 적절한 형태로 가공해서 응답할 수 있다는 장점이 있다.
우리가 사용하게 될 구조를 정리해보자면 다음과 같은 순서이다.
이제 마이크로 서비스로 사용할 User Service를 생성해보자.
해당 프로젝트에 필요한 Dependency는 Eureka Discovery Client
이다.
편리하게 사용하기 위해 Spring Boot DevTools
, Lombok
, Spring Web
을 추가한다.
@EnableDiscoveryClient
을 추가해준다.
@SpringBootApplication
@EnableDiscoveryClient
public class UserServiceApplication {
public static void main(String[] args) {
SpringApplication.run(UserServiceApplication.class, args);
}
}
server:
port: 9001
spring:
application:
name: user-service
eureka:
client:
# 유레카에 등록함
register-with-eureka: true
# 유레카 서버로부터 인스턴스들의 정보를 주기적으로 가져올 것인지
fetch-registry: true
# 현재 서비스 등록
service-url:
defaultZone: http://127.0.0.1:8761/eureka
실행한 후 아까 http://127.0.0.1:8761
에 들어가보면 우리가 등록한 서비스 목록이 출력되는 것을 확인할 수 있다.
이제 서비스 하나를 더 생성해볼 것이다.
여러개의 service를 띄울 때 port 지정해주기 굉장히 귀찮아진다.(계속 겹치지 않게 다른 포트값 설정해야함)
이럴 때 그냥 port 값을 0으로 주게 되면 매번 랜덤하게 사용 가능한 포트를 부여해준다고 한다.
따라서 작성했던 application.yml을 수정해주자.
server:
port: 0
spring:
application:
name: user-service
eureka:
instance:
instance-id: ${spring.cloud.client.hostname}:${spring.application.instance_id:${random.value}}
client:
register-with-eureka: true
fetch-registry: true
service-url:
defaultZone: http://127.0.0.1:8761/eureka
instance-id
설정이 추가되었는데 추가된 이유는 다음과 같다.
같은 프로젝트를 여러 개 띄우면 포트번호가 같음 -> 1개만 표시되는 현상이 발생하기 때문에 실행되는 프로젝트마다 구분해주기 위해 설정했다.