Eureka?
Spring Cloud Discovery라는 개념을 활용하기 위한 라이브러리로 사용
Health Check, 로드 밸런싱을 하기 위해서 사용하는 서버
MSA에서 서비스의 등록, 발견 및 관리를 위한 Discovery Service

MS를 Eureka에 미리 등록하여 사용 → 게이트웨이는 Eureka에 문의만 하면 된다.
서비스 등록
→ 다른 서비스나 클라이언트가 해당 서비스를 찾을 수 있음.
서비스 감지
→ 동적으로 서비스의 위치를 파악할 수 있습니다.
서비스 상태 감지 (Helath Check 모니터링)
→ 장애가 발생한 서비스를 감지하고 다른 서비스로 요청을 라우팅
동적 서비스 변경
클라이언트 사이드 로드 밸런싱
→ 부하 분산
Eureka Server(Discovery Server) 구동 ↔ Discovery Client (= MS)
서비스 등록
(위 정보에는 서비스 이름, IP주소, 포트 번호 포함)
서비스 감지
다른 MS나 클라이언트가 특정 서비스를 호출하려면
Eureka 클라이언트 라이브러리를 사용하여 Eureka서버에서 해당 서비스의 인스턴스를 찾습니다.
서비스 사용
→ 클라이언트 사이드 로드 밸런싱을 통해 부하 분산
서비스 상태 감시 : 30초에 3번씩 요청 보냄
동적 서비스 변경

yml에서 유레카 서버 설정 등록
```yaml
server:
port: 8761 # 포트번호 겹치지 않는 선에서 맘대로
spring:
application:
name: discovery-server
eureka:
client:
register-with-eureka: false # 해당 서버를 유레카에 등록할 것인가? (클라이언트한테는 true를 줘야 함)
fetch-registry: false # 해당 서버가 다른 서비스의 endpoints에 대한 정보를 다운로드하기 위해 Eureka 서버에 연결을 시도할지 여부를 제어
# ( = 유레카에 등록되는 서비스들의 정보를 갱신하기 위한 용도 )
```
main에 @EnableEurekaServer 어노테이션을 추가해야 유레카 서버가 감시 시작
@EnableEurekaServer // 유레카 대시보드에서 감시 시작
@SpringBootApplication
public class DiscoveryServerApplication {
public static void main(String[] args) {
SpringApplication.run(DiscoveryServerApplication.class, args);
}
}
등록했던 포트 번호로 유레카 서버 동작 확인 가능

- 유레카 서버를 한 번 등록하면
이후 클라이언트를 추가할 때는 유레카 서버를 건들일 필요가 없다
→ 유지보수에 용이
Client로 등록할 MS는 Eureka Discovery Client 의존성 부여 해야 함

yml에서 클라이언트 설정 등르고
server:
port: 8003
spring:
application:
name: discovery-client
eureka:
client:
register-with-eureka: true # 유레카 서버에 등록
fetch-registry: true # 유레카 서버에서 서버 상태 지속적 감시 허락
service-url:
defaultZone: http://192.168.67.1:8761/eureka # 유레카 서버의 주소
main에 @EnableDiscoveryClient 어노테이션을 추가하여 클라이언트로 등록
@EnableDiscoveryClient
@SpringBootApplication
public class DiscoveryClientApplication {
public static void main(String[] args) {
SpringApplication.run(DiscoveryClientApplication.class, args);
}
}
Eureka 서버에 Client가 등록된 모습을 확인할 수 있음



➡️ APPLICATION FAILED TO START
Description: Web server failed to start. Port 8003 was already in use.
Action: Identify and stop the process that's listening on port 8003 or configure this application to listen on another port.
서버 실행 단계에서 포트 값을 새롭게 지정한다. (VM options 설정)
1-1) Edit Configutration에 다시 들어가서 VM options을 추가한다.

1-2) 사용할 포트 번호를 지정한다. (-D = detach모드, 콘솔창을 수믹고 어플리케이션을 가동)

1-3) 2개의 클라이언트가 등록된 것을 볼 수 있다.

각 서버 실행 시마다 랜덤포트를 실행하도록 만든다.
→ 점유 중이지 않은 포트번호를 랜덤하게 배정
= 니가 안 쓰는 번호 알아서 찾아 들어가라

server.port=0 ← 0번 포트는 존재하지 않음
= 랜덤포트 배정


명목 상 port번호를 0으로 배정했기 때문에 인스턴스가 1개만 켜진 것으로 나옴
server:
port: 0
spring:
application:
name: discovery-client
eureka:
client:
register-with-eureka: true # 유레카 서버에 등록
fetch-registry: true # 유레카 서버에서 서버 상태 지속적 감시 허락
service-url:
defaultZone: http://192.168.67.1:8761/eureka # 유레카 서버의 주소
instance: # 인스턴스 식별용 아이디 부여
instance-id: ${spring.application.name}:${spring.application.instance_id:${random.value}}
- 각 인스턴스별로 유레카에 보여주는 표기를 다르게 하기 위한 설정

인스턴스 별로 가져오는 것을 볼 수 있다.
ext {
set('springCloudVersion', "2022.0.4")
}
dependencyManagement {
imports {
mavenBom "org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}"
}
}
// https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-netflix-eureka-client
implementation 'org.springframework.cloud:spring-cloud-starter-netflix-eureka-client'
- build.gradle에 의존성 주입을 해주면 된다.
위 프로젝트의 경우, Spring Boot 3.1.4버젼 / Eureka Client 4.0.3버젼으로 진행했다. 
클라이언트 yml에서 설정한 Application name으로 설정된 것을 Eureka에서 볼 수 있다.
위의 예제를 기반으로 게이트웨이와 MS를 유레카에 등록했다.

이전에 게이트웨이에 직접 등록한 포트번호를 변경해야 한다.
server:
port: 8000 # 게이트웨이의 경우는 당장 랜덤 포트번호를 사용할 필요가 없다
spring:
application:
name: apigateway-service
cloud:
gateway:
default-filters: # 전역필터 세팅
- name: GlobalFilter
args:
message: Global Filter Default Message Test
pre: true
post: true
routes:
- id: first-service
uri: lb://First-Service # Application name이 First-Service인 인스턴스들을 로드밸런싱
predicates:
- Path=/first-service/**
filters:
- CustomFilter
- LogFilter
- id: second-service
uri: lb://Second-Service
predicates:
- Path=/second-service/**
filters:
- AddRequestHeader=s-req,s-req-v
- AddResponseHeader=s-res,s-res-v
eureka:
client:
register-with-eureka: true # 유레카 서버에 등록
fetch-registry: true # 유레카 서버에서 서버 상태 지속적 감시 허락
service-url:
defaultZone: http://192.168.67.1:8761/eureka # 유레카 서버의 주소
instance: # 인스턴스 식별용 아이디 부여
instance-id: ${spring.application.name}:${spring.application.instance_id:${random.value}}
lb://유레카에 등록한 Application명
→ 해당 Application name인 인스턴스들로 로드밸런싱하겠다.
제대로 로드밸런싱 되었는지 확인하기 위해 Controller를 통해 포트 번호 확인
@RestController
@RequestMapping("/first-service")
@RequiredArgsConstructor
public class FirstserviceController {
private final Environment env;
@RequestMapping(value="/port-check", method = RequestMethod.GET)
public String portCheck(){
return env.getProperty("local.server.port");
// server.port로 쓰면 port번호가 0으로 나타난다.
// application.yml파일에 기입된 정보를 얻어와서 자바 자료로 만들어주기 때문
}
}
이름이 First-Service 인스턴스 2개 중 1개의 port번호로 제대로 로드밸런싱이 된다.

