서비스 디스커버리 (Eureka)

johaS2·2025년 2월 6일
0

서비스 디스커버리란?

  • MSA에서 각 서비스의 위치를 자동으로 찾는 기능
  • MSA에서는 여러 개의 마이크로서비스가 각각 독립적으로 실행되는데, 각 서비스의 IP주소나 포트가 변경될 수도 있기 때문에 서버 주소를 일일이 설정하는 것은 비효율적이다. 그래서 서비스 디스커버리를 사용해서 동적으로 서비스 위치를 찾을 수 있다

서비스 디스커버리의 방식 - 2가지

  1. 클라이언트 사이드 디스커버리
  • 클라이언트가 직접 서비스 레지스트리에서 서비스 정보를 조회한 후, 요청을 보냄
  • 대표적인 예 : Netflix Eureka
  1. 서버 사이드 디스커버리
  • 클라이언트가 직접 서비스 주소를 찾지 않고, 로드 밸런서(Nginx, API Gateway 등)가 서비스 레지스트리에서 서비스 위치를 조회
  • 대표적인 예 : Kubernetes, AWS ALB (Application Load Balancer)
  • 클라이언트가 서비스의 위치를 몰라도 되고, 로드 밸런서가 자동으로 트래픽을 분배

서비스 레지스트리란?

  • 마이크로서비스들의 주소를 저장하고 관리하는 중앙 저장소

Spring Cloud Netflix Eureka 실습

  1. Eureka Server 프로젝트 생성 - Eureka 의존성 추가
dependencies {
	implementation 'org.springframework.cloud:spring-cloud-starter-netflix-eureka-server'
    } 
  1. Eureka Server 설정
spring.application.name=server

server.port=19090

eureka.client.register-with-eureka=false
eureka.client.fetch-registry=false
  1. Eureka Server 활성화
    @EnableEurekaServer 어노테이션 추가 !
@SpringBootApplication
@EnableEurekaServer
public class ServerApplication {

	public static void main(String[] args) {
		SpringApplication.run(ServerApplication.class, args);
	}

}
  1. Euraka 서버 실행 확인

Eureka Client 설정

  1. Eureka Client 프로젝트 생성 - 의존성 추가
dependencies {
    implementation 'org.springframework.cloud:spring-cloud-starter-netflix-eureka-client'
}
  1. Eureka Client 설정 - yml로 해보기
spring:
  application:
    name: order-service
server:
  port: 19091
eureka:
  client:
    service-url:
      defaultZone: http://localhost:19090/eureka/
spring:
  application:
    name: product-service
server:
  port: 19092
eureka:
  client:
    service-url:
      defaultZone: http://localhost:19090/eureka/
  1. Eureka Client 활성화
    @EnableFeignClients 어노테이션 추가 !

  2. Eureka Dashboard에서 확인
    Instances currently registered with Eureka 부분에 order-service, product-service가 등록된 것 확인!

서비스 간 통신 방법 (RestTemplate vs Feign Client)

  1. RestTemlate
@Bean
public RestTemplate restTemplate() {
    return new RestTemplate();
}
```java
@Autowired
private RestTemplate restTemplate;

public ProductResponse getProductById(Long id) {
    return restTemplate.getForObject(
        "http://product-service/products/" + id, 
        ProductResponse.class
    );
}
  • 서비스의 주소를 직접 설정해야 함
  • 코드가 길고 복잡
  • 로드 밸런싱이 자동 지원되지 않음
  1. Feign Client
  • Feign 의존성 추가
dependencies {
    implementation 'org.springframework.cloud:spring-cloud-starter-openfeign'
}
  • Feign 활성화
@SpringBootApplication
@EnableFeignClients
public class OrderApplication {

	public static void main(String[] args) {
		SpringApplication.run(OrderApplication.class, args);
	}

}
  • Feign Client 인터페이스 작성
@FeignClient(name="product-service")
public interface ProductClient {
    @GetMapping("/product/{id}")
    String getProduct(@PathVariable("id") String id);
}
  • Feign으로 서비스 호출
@Service
@RequiredArgsConstructor
public class OrderService {
    private final ProductClient productClient;

    public String getProductInfo(String productId){
        return productClient.getProduct(productId);
    }
}
  • 코드가 간결하고 가독성이 좋음
  • Eureka와 연동 가능 -> 서비스 이름으로 직접 호출
  • 로드 밸런싱 자동 지원 (Ribbon 내장)
  • 직접 HTTP 요청을 처리하지 않아도 됨(JSON 변환 자동)

RestTemplate vs Feign Client 비교 정리

항목RestTemplateFeign Client
코드 복잡성코드가 많아짐인터페이스만 작성하면 됨
Eureka 연동수동 설정 필요자동 연동 가능
로드 밸런싱Ribbon 필요자동 지원
JSON 변환수동 전환 필요자동 변환
사용 방식명시적으로HTTP요청선언형 인터페이스 방식
profile
passionate !!

0개의 댓글