Eureka는 클라우드 환경의 다수의 서비스(예: API 서버)들의 로드 밸런싱 및 장애 조치 목적을 가진 미들웨어서버!
로드 밸런싱 : 특정 서비스를 제공하는 서버가 여러대가 있을 때 트래픽을 한 서버에 몰리지 않게 분산해주는 기술이다.
미들웨어 : 데이터를 주고 받는 양쪽의 서비스(웹의 예로 클라이언트와 API 서버)의 중간에 위치해 매개 역할을 하는 소프트웨어다.
Eureka는 이러한 미들웨어 기능을 하기 위해 각 연결된 서비스의 IP / PORT /InstanceId를 가지고 있고 REST기반으로 작동.
Eureka는 Client-Sever 방식으로 Eureka Server에 등록된 서비스는 Eureka Client로 불린다.
각 서비스를 Eureka Server에 등록하게 되면 Eureka Server는 각 Eureka Client의 IP / PORT / InstanceId를 저장한다.
이후 Eureka Client가 다른 Eureka Client에게 요청을 보낼 때 Eureka에서 받아온 정보를 가지고 요청을 보낼 수 있다.
<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-actuator</artifactId>
</dependency>
<!--Spring Boot Admin Server를 시작하는 데 필요한 라이브러리-->
<!-- 2024-03-04 시점엔 3.2.3 버전 없음 -->
<dependency>
<groupId>de.codecentric</groupId>
<artifactId>spring-boot-admin-starter-server</artifactId>
<version>3.2.2</version>
</dependency>
@EnableAdminServer
@EnableEurekaServer
@SpringBootApplication
public class Step07SpringCloudServerApplication {
public static void main(String[] args) {
SpringApplication.run(Step07SpringCloudServerApplication.class, args);
}
}
application.yml
server:
port: 8761
spring:
application:
name: server
boot: # spring boot admin 모니터링 기능 이용을 위한 설정 부분
admin:
context-path: /admin
management: # 엔트포인트 노출 설정 애플리케이션을 배포하는 경우 인증 없이 모든 액추에이터 끝점에 액세스
endpoints:
web:
exposure:
include: "*"
eureka:
instance:
hostname: <ec2 퍼블릭IP>
prefer-ip-address: true
client:
register-with-eureka: false
service-url:
default-zone: http://<퍼블릭IP>:8761/eureka/
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>de.codecentric</groupId>
<artifactId>spring-boot-admin-starter-client</artifactId>
<version>3.2.2</version>
</dependency>
@EnableDiscoveryClient
@SpringBootApplication
public class Step07SpringCloudClient1ConsumerApplication {
public static void main(String[] args) {
SpringApplication.run(Step07SpringCloudClient1ConsumerApplication.class, args);
}
}
server:
port: 9009
address: <ec2 private ip>
# project 별칭 등록
# 다른 project에서 호출할때 사용되는 이름
spring:
application:
name: PRODUCER-SERVICE
boot:
admin:
client:
instance:
service-url: http://<public ip>:9009
# 애플리케이션의 상태, 메모리 사용량, 데이터베이스 연결 상태 등을 모니터링하고 관리하기 위한 설정
# Spring Boot Actuator를 사용하여 애플리케이션의 상태를 모니터링하고 관리 가능
# 필요한 경우 설정을 조정하여 원하는 엔드포인트를 노출하여 관리 가능
management:
endpoints:
web:
exposure:
include: "*"
eureka:
instance:
prefer-ip-address: true
ip-address: ${server.address}
instance-id: ${server.address}:${spring.application.name}:${server.port} # spring Eureka에 등록되는 status 값
client:
fetch-registry: true
register-with-eureka: true
service-url:
defaultZone: http://<유레카 public ip>:8761/eureka/
@Component
public class DifferentClientLogicConsumer {
@Autowired
private DiscoveryClient client;
public String getClient1ServiceLogic() {
//해당 이름으로 등록된 spring cloud 앱들 반환
List<ServiceInstance> siList = client.getInstances("PRODUCER-SERVICE");
//PRODUCER-SERVICE 로 등록된 기능의 spring cloud client 앱객체
ServiceInstance si = siList.get(0);
//PRODUCER-SERVICE
System.out.println("User 요청 처리 " + si);
String url = si.getUri() + "/secondclient";
System.out.println(url);
RestTemplate rt = new RestTemplate();
String response = rt.getForObject(url, String.class);
return response;
}
}
@Slf4j
@RestController
public class ThirdClientController {
@Autowired
private DifferentClientLogicConsumer consumer;
//http://localhost:<>/secondclient
@GetMapping("/user")
public String first() {
System.out.println("Consumer2의 first() (Get/user) 메소드 ***");
return "Consumer 응답 데이터 " + consumer.getClient1ServiceLogic();
}
}
//http://localhost:9009/secondclient
@GetMapping("/secondclient")
public String second() {
System.out.println("Producer의 first() 메소드 호출 ***");
return "알레스카 사는 김상덕씨";
}
하지만 user에서 producer의 메소드를 부르고 있음!