Spring Cloud 환경 구축하기(Eureka)

덤벨로퍼·2024년 3월 6일
1

개인공부

목록 보기
10/11
post-custom-banner

🧱시스템 구조

🍀 Eureka 란?

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에서 받아온 정보를 가지고 요청을 보낼 수 있다.

1. Eureka server

       <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);
	}

}
  • @EnableAdminServer : 어노테이션은 Spring Boot Admin Server를 활성화하는 데 사용, 모니터링 및 관리를 제공하는 도구.
  • @EnableEurekaServer : 현재의 스프링 부트 애플리케이션을 Eureka Server로 설정

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/

2. Eureka client server


		<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);
	}
}
  • @EnableDiscoveryClient : 서비스 디스커버리 시스템에 등록되어 다른 마이크로서비스들과 통신
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/

ec2 4개에 각 Server , Consumer1 , Consumer2 , Producer1 올리고 모니터링


서로 다른 서버의 메소드 호출!

  • User
@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();
	}
	
}
  • producer
	//http://localhost:9009/secondclient
	@GetMapping("/secondclient")
	public String second() {
		System.out.println("Producer의 first() 메소드 호출 ***");
		return "알레스카 사는 김상덕씨";
	}

producer port (9009) , User port (8090)

하지만 user에서 producer의 메소드를 부르고 있음!

profile
💪 점진적 과부하로 성장하는 개발자
post-custom-banner

0개의 댓글