안녕하세요. 오늘은 저번시간에 이어서 Spring Cloud Eureka에 대해서 알아보도록 하겠습니다. 저번시간에는 Eureka의 이론적인 부분에 집중했다면 이번시간에는 실제로 적용해보는 시간을 가지도록 하겠습니다. Client는 Zuul을 사용할 것입니다. Zuul에 대해서 잘 모르시는 분들은 Zuul에 대한 포스팅을 참고해주시기 바랍니다.
프로젝트 구성요소
- Service( Eureka-Client ) : 실제 로직이 실행되는 서비스
- Eureka-Server : 서비스들의 정보를 관리하는 Eureka Server
- Zuul (Eureka-Client) : 실제 서비스로 Routing하는 Edge 서비스
아키텍처
- MSA를 구성하는 서비스들은 본인의 정보(IP, Port, AppName, instanceID)들을 Eureka Server에 전달
- 해당 정보를 사용하고자 하는 Service는 Eureka Server에 정보 요청
- 해당 요청 정보를 이용하여 통신
Eureka Server
가장먼저 eureka server를 생성하는 방법을 알아보도록 하겠습니다. eureka server는 서비스들의 정보를 가지고 있는 서버입니다.
가장먼저 기본 Spring Boot 프로젝트를 생성한 후 아래의 dependency를 추가합니다. 아래의 Dependency를 추가하면 Eureka Server를 사용할 수 있게 됩니다.
implementation("org.springframework.cloud:spring-cloud-starter-netflix-eureka-server:2.1.2.RELEASE")
그리고 Java파일을 만들도록 하겠습니다. @EnableEurekaServer
Annotation을 달면 바로 Eureka Server로 사용할 수 있게 됩니다.
@EnableEurekaServer
@SpringBootApplication
public class EurekaServiceApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaServiceApplication.class, args);
}
}
아래는 Eureka의 application.yml
파일입니다. register-with-eureka는 eureka의 registry에 등록할지 여부이고, fetch-registry는 registry에 있는 정보를 가져올지 여부입니다. eureka-server는 사용하지 않으므로 false 로 기입해줍니다. 그리고 eureka의 service-url은 보인 server의 url을 적어줍니다.
eureka:
instance:
hostname: localhost
client:
register-with-eureka: false
fetch-registry: false
service-url:
defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
이렇게 어렵지않게 eureka-server를 생성해보았습니다. 이제 실제 로직이 실행되는 Service를 한번 만들어보겠습니다.
Service
service는 아래와 같은 의존성을 가짐으로써 eureka-client를 구현할 수 있습니다.
implementation("org.springframework.cloud:spring-cloud-starter-netflix-eureka-client:2.1.2.RELEASE")
아래는 실행하는 main과 test를 위해서 /ping
을 호출 할 수 있도록 controller를 만들도록 하겠습니다.
@SpringBootApplication
public class OrderApplication {
public static void main(String[] args) {
SpringApplication.run(OrderApplication.class, args);
}
}
@RestController
public class HealthCheckController {
@GetMapping("/ping")
public ResponseEntity<String> healthCheck() {
log.info("###health check");
return ResponseEntity.ok("pong");
}
}
그리고 service는 아래와 같이 설정파일을 변경해 줍니다.
server:
port: 8080
spring:
application:
name: service-1
eureka:
client:
register-with-eureka: true
fetch-registry: true
service-url:
defaultZone: http://localhost:8761/eureka/
이렇게 까지 하고 서버를 실행하면 Eureka-server에 Eureka-client인 service가 정보를 지속적으로 전달하게 됩니다. 2개의 서버를 띄운 후 http://localhost:8761에 접속 해보면 Instances currently registered with Eureka에 아래와 같이 1개의 Instance가 등록되어 출력되는 것을 확인할 수 있습니다.
Zuul
마지막으로 Eureka-Server에 등록되어 있는 정보를 가져와 실제 통신에 사용하는 Zuul에 대해서 실습해 보겠습니다. Zuul이 아닌 일반 Client를 사용하고자 하시는 분들은 Ribbon 또는 feign를 사용하시면 됩니다.
implementation "org.springframework.cloud:spring-cloud-starter-netflix-eureka-client:2.1.2.RELEASE"
Service와 동일하게 eureka-client를 의존합니다.
@EnableZuulProxy
@EnableDiscoveryClient
@SpringBootApplication
public class ZuulApplication {
public static void main(String[] args) {
SpringApplication.run(ZuulApplication.class, args);
}
}
@EnableDiscoveryClient
를 사용하면 eureka-client에서 fetch한 정보를 통신에 사용할 수 있게 됩니다.
@EnableZuulProxy
는 End-Point를 이용한 라우팅을 허용합니다. 이렇게 하면 Eureka-Server의 appId로 Routing이 이루어질 Service를 정할 수 있습니다.
실제로 라우팅되는 Service 설정은 yaml 파일로 진행합니다.
server:
port: 8100
zuul:
routes:
service-1:
path: /order/**
serviceId: service-1
eureka:
client:
register-with-eureka: true
fetch-registry: true
service-url:
defaultZone: http://localhost:8761/eureka/
yaml 파일은 위와 같이 설정해줍니다. service-1은 우리가 통신하고자 하는 service의 appName입니다. zuul.routes.service-1.path
는 zuul의 서비스의 end-point에 /order/** 으로 접근 시 service-1
의 서비스로 라우팅 된다는 의미입니다. 그러면 위의 설정을 이용하여 테스트를 진행해보도록 하겠습니다.
통합 테스트
예상되는 시나리오는 http://localhost:8100/order/ping으로 호출하면 zuul에서 service-1의 서비스인 http://localhost:8080/ping를 호출하여 응답을 가져올 것이라는 것입니다.
3개의 서버를 다 띄운 후 테스트해보도록 하겠습니다.
실제 결과는 위와 같이 우리가 예상한 대로 나옵니다. 그렇다면 Zuul에서 Debug 모드로 한번 Log를 출력해보도록 하겠습니다.
2020-02-10 12:03:19.009 [473fa7af3cefeaa0/473fa7af3cefeaa0] DEBUG - [nio-8100-exec-1] c.n.l.DynamicServerListLoadBalancer [241] : List of Servers for service-1 obtained from Discovery client: [192.168.4.91:8081]
2020-02-10 12:03:19.020 [473fa7af3cefeaa0/473fa7af3cefeaa0] DEBUG - [nio-8100-exec-1] c.n.l.DynamicServerListLoadBalancer [246] : Filtered List of Servers for service-1 obtained from Discovery client: [192.168.4.91:8081]
2020-02-10 12:03:19.021 [473fa7af3cefeaa0/473fa7af3cefeaa0] DEBUG - [nio-8100-exec-1] c.n.l.DynamicServerListLoadBalancer [179] : Setting server list for zones: {defaultzone=[192.168.4.91:8081]}
호출 시 local cache에 담겨있는 값중 기 입력했던 serviceId가 있는지 체크하며 있다면 해당 service의 ip와 port를 가져오는 것을 알 수 있었습니다.
2020-02-10 12:03:19.169 [473fa7af3cefeaa0/6ec4819ec96888b2] DEBUG - [RibbonCommand-1] c.n.loadbalancer.LoadBalancerContext [492] : service-1 using LB returned Server: 192.168.4.91:8081 for request /ping
그리고 가져온 IP, Port 정보를 이용하여 위와 같이 라우팅으로 실제 서비스를 호출합니다.
마무리
오늘은 이렇게 Eureka를 실제로 Spring 프로젝트에서 사용하는 방법에 대해서 알아보았습니다.
감사합니다.
참조
https://cloud.spring.io/spring-cloud-netflix/reference/html/
'language, framework, library > Spring Cloud' 카테고리의 다른 글
[MSA] Spring Cloud Feign - 커스터 마이징 설정편 (0) | 2020.09.30 |
---|---|
[MSA] Spring Cloud Feign - 기본 사용 및 기본 설정편 (0) | 2020.09.27 |
[MSA] Spring Cloud Eureka에 관하여 - 이론편 (1) | 2020.02.05 |
[MSA] Spring Cloud Zuul 1.x - 실습편 (0) | 2020.01.22 |
[MSA] Spring Cloud Zuul 1.x - 개념편 (0) | 2020.01.20 |
댓글