Spring Boot MSA 적용기 (With. Netflex Eureka)
TL;DR
정말 오랜만에 블로그 포스팅을하게 되었습니다.
그동안 이것저것 정리는 했지만 .. 블로그로 옮기려니 귀찮아지더라구요 .. 😢
곧 2022년이 다가오니 다시 초심을 찿고 열심히 포스팅을 해 볼 생각입니다.
화이팅~ 👊
- ( 목표 :: 주 1회 포스팅하기 .. 😤 )
MSA 란?
-
서비스에 도출되는 도메인들을 컴포넌트단위로 나누어 설계하는 구조 기법.
-
DDD(도메인 주도 개발)시 MSA를 곁들여 사용하면 시너지가 좋다.
-
장점도 많으나, 단점도 명확히 존재하기에 사용 전 MSA를 적용하는게 맞는지 고민이 필요하다. (굳이 신기술이라고 좋아라 적용한다면 나중에 후회 할지도 ..)
- 장점
- 각 컴포넌트별로 나눠져 있기에, 각 컴포넌트를 수정/추가 작업 이후 소요되는 테스트 및 빌드시간이 단축 됨.
- 여러 언어 및 기술을 사용하여 구성할 수 있기에 최적의 기술을 탑재하기 용이
- 서버 또는 신규 서비스 컴포넌트 확장 시 용이 함
- 단점
- 초기 세팅/구조 설계 시 많은 비용이 발생.
- 여러 컴포넌트 / 서버가 생기기에 그에 따른 관리포인트가 증가.
- DB 같은 Connection Pool 등 또한 각각의 컴포넌트가 따로 가지고 있기에 Transaction등을 일관성있게 유지하기 어렵다.
Netflex Eureka
-
Neflix에서 공개한 MSA 클라우드 오픈소스.
-
클라우드 환경에서 서비스를 배포/관리 하기 어려울 수 있기에, 이를 도와주는 컴포넌트중 하나가 Netflex OSS 인 Eureka 이다.
-
Discovery는 Eureka 내 존재하는 컴포넌트들에 연결 정보를 찿는것을 의미 하고, Registry는 각 컴포넌트가 연결 정보를 Eureka에 등록하는 것을 의미한다.
-
크게 Eureka Server와 Eureka Client로 나뉘며, Server 에서는 각 Eureka Client 컴포넌트들에 연결 정보를 관리하고, Client에서는 이러한 연결 정보를 Server에 알려주며, Disdcovery Server에 관리중인 연결정보를 기반으로 Routing 서비스를 제공한다. 이후 Routing 된 Client들은 각 컴포넌트 내 작성한 서비스대로 처리가 된다.
-
Zuul, Ribbon, hystrix 등을 이용한 다양한 MSA 지원 서비스를 제공
Spring Boot 내 적용
- 각 컴포넌트에 연결 정보를 관리 할 Discovery Server 컴포넌트
- Routing을 관리할 Zuul 컴포넌트
- 실제 기능을 처리할 다수의 서비스 컴포넌트
Discovery Server (Server)
[Build]
dependencies {
```
implementation group: 'org.springframework.cloud', name: 'spring-cloud-starter-netflix-eureka-server', version: '2.2.9.RELEASE'
```
}
[properties]
server:
port: 8081
spring:
application:
name: kdk-eureka-server
[ServerApplication]
@EnableEurekaServer
@SpringBootApplication
public class DefaultServerApplication {
public static void main(String[] args) {
SpringApplication.run(DefaultServerApplication.class, args);
}
}
-
먼저 Discovery Server 구성을 위한 Lib를 빌드 해주고, properties 설정을 진행 해준다
-
어플리케이션 파일 내 @EnableEurekaServer Annotation을 추가하여 Eureka Server임을 선언 해주면 Discovery 서버는 세팅이 완료 된다.
Zuul Component (Client)
[Build]
dependencies {
```
implementation group: 'org.springframework.cloud', name: 'spring-cloud-starter-netflix-eureka-client', version: '2.2.9.RELEASE'
implementation group: 'org.springframework.cloud', name: 'spring-cloud-starter-netflix-zuul', version: '2.2.9.RELEASE'
```
}
[properties]
server:
port: 8100
spring:
application:
name: kdk-eureka-zuul
zuul:
routes:
service-1:
stripPrefix: false
path: /api/**
url: http://localhost:8101
service-2:
stripPrefix: false
path: /craw/**
url: http://localhost:8102
eureka:
client:
register-with-eureka: true
fetch-registry: true
serviceUrl:
defaultZone: http://localhost:8081/eureka/
- propoerties
- name
- Application Name
- zuul.routes
- zuul을 통해 routing 될 Service Application 지정
- zuul.strinpPrefix
- prefix를 사용할지 여부
- (현재 지정한 zuul prefix가 없는 관계로 false setting)
- prefix를 사용할지 여부
- zuul.path
- router Path 지정
- (Zuul을 통해 “ /api/** “로 접근하는 호출은 모두 위 서비스를 이용)
- router Path 지정
- eureka.client.register-with-eureka
- Eureka 서버 내 등록 여부
- eureka.client.fetch-registry
- 등록 된 서비스 정보를 가져올지 여부
- eureka.client.serviceUrl.defaultZone
- Eureka Discovery Server Url (Default)
- name
[ServerApplication]
@SpringBootApplication
@EnableZuulProxy
@EnableDiscoveryClient
public class DefaultServerApplication {
public static void main(String[] args) {
SpringApplication.run(DefaultServerApplication.class, args);
}
}
- Eureka Client Lib 와 Routing을 지원할 Zuul Lib 를 빌드
- propertes 파일 내 zuul을 이용한 Routing 방식을 지정
- 어플리케이션 파일 내 @EnableZuulProxy Annotation을 추가하여 Routing Application 임을 부여
- 어플리케이션 파일 내 @EnableDiscoveryClient Annotation을 추가하여 Eureka Client 임을 부여
Service Component (Client)
[build]
dependencies {
```
implementation group: 'org.springframework.cloud', name: 'spring-cloud-starter-netflix-eureka-client', version: '2.2.9.RELEASE'
```
}
[properties]
server:
port: 8101
spring:
application:
name: kdk-eureka-zuul-service
eureka:
client:
fetch-registry: true
serviceUrl:
defaultZone: http://localhost:8081/eureka/
[ServerApplication]
@EnableDiscoveryClient
@SpringBootApplication
public class DefaultServerApplication {
public static void main(String[] args) {
SpringApplication.run(DefaultServerApplication.class, args);
}
}
[Controller]
@RestController
@RequestMapping(value = "/api", produces = MediaType.APPLICATION_JSON_VALUE)
public class TestRestCOntroller {
@RequestMapping(value = "/{value}", method = RequestMethod.GET)
public String eurekaClient(@PathVariable("value") String value) {
return value == null ? "NA" : value;
}
}
- 앞서 Zuul 컴포넌트에서 행했던 절차와 동일하게, Client를 빌드 하고 어플리케이션 명명을 지정해주면 세팅 완료
- 이후 Zuul에서 선언했던 바와 같이 현재 서비스 컴포넌트 경우 path ‘/api/**‘를 가져가기에 해당 컴포넌트 내 모든 API Url은 동일 prefix 값 을 가져간다
테스트 ..
- 위 단계까지 진행하였다면 간단한 MSA 구성 세팅은 완료.
- 테스트를 위해 Zuul Rounting 컴포넌트(port :: 8101) 로 테스트 API를 호출하여 잘 되는지 확인.
- 성공적으로 Routing이 되어 원하던 결과가 나온걸 확인할 수 있다.
마무리
- 위 포스팅으로 Netflex Eureka를 이용한 Spring Boot 기반 NSA 구조를 구성해보았습니다!😄
- 다음 포스팅에는 Python에서도 Eureka를 적용하여 테스팅 하는 방법을 소개 해볼까 합니다!
읽어주셔서 감사합니다 :)
Thanks .