Spring Boot MSA 정의
1. 마이크로서비스 아키텍처(MSA, Microservices Architecture)
정의: MSA는 애플리케이션을 여러 개의 독립적이고 자율적인 작은 서비스들로 분리하여 개발하고 운영하는 아키텍처 스타일입니다. 각 서비스는 특정 비즈니스 기능을 담당하며, 서로 독립적으로 배포, 확장 및 유지보수가 가능합니다.
2. 스프링 부트(Spring Boot)
정의: 스프링 부트는 스프링 프레임워크의 하위 프로젝트로, 복잡한 설정 없이 간단하게 스프링 기반 애플리케이션을 개발할 수 있게 해주는 프레임워크입니다. 자동 설정, 내장 서버, 독립 실행형 애플리케이션을 쉽게 만들 수 있는 기능들을 제공합니다.
3. 스프링 부트 MSA의 주요 특징
서비스 분리: 각 마이크로서비스는 독립적으로 개발 및 배포가 가능하며, 각 서비스는 자체적인 데이터베이스를 가질 수 있습니다.
독립적 확장성: 특정 서비스에 대한 트래픽이 증가하면 해당 서비스만 별도로 확장할 수 있습니다.
자율성: 각 서비스는 독립적인 기술 스택을 선택할 수 있으며, 다른 서비스의 영향을 받지 않고 업데이트가 가능합니다.
경량화: 스프링 부트는 내장 서버와 최소한의 설정으로 경량화된 마이크로서비스를 쉽게 만들 수 있습니다.
4. 스프링 부트 MSA의 주요 구성 요소
Spring Cloud: 스프링 부트와 함께 사용되는 라이브러리 세트로, 마이크로서비스의 클라우드 네이티브 개발을 지원합니다. 서비스 등록 및 발견, 구성 서버, 서킷 브레이커, 게이트웨이 등의 기능을 제공합니다.
Eureka: 서비스 디스커버리 서버로, 각 마이크로서비스가 자신의 위치를 등록하고, 다른 서비스가 이를 찾아서 호출할 수 있도록 도와줍니다.
Zuul / Spring Cloud Gateway: API 게이트웨이로, 외부 요청을 각 마이크로서비스로 라우팅하거나 필터링합니다.
Config Server: 중앙 집중식 구성 관리 서버로, 각 마이크로서비스의 설정 정보를 한 곳에서 관리할 수 있도록 도와줍니다.
Feign: 선언적 REST 클라이언트로, 마이크로서비스 간의 통신을 간단하게 처리할 수 있습니다.
5. 장점과 단점
장점
유연성: 각 서비스가 독립적으로 개발 및 배포될 수 있어, 더 빠른 개발 주기를 지원합니다.
확장성: 서비스 단위로 확장할 수 있어, 특정 기능에 대한 확장이 용이합니다.
복원력: 한 서비스의 장애가 전체 시스템에 영향을 미치지 않도록 설계할 수 있습니다.
단점
복잡성: 여러 서비스 간의 통신, 데이터 일관성, 배포 파이프라인 관리 등 복잡성이 증가할 수 있습니다.
분산 관리: 분산된 로그, 모니터링, 트랜잭션 관리 등의 이슈가 발생할 수 있습니다.
설명
분산 시스템으로 시스템을 구성하고 운영하는데 있어서 Spring Cloud 가 MSA를 구성하는데 필요합니다.
위의 그림을 보면, MSA를 구축하기 위해서는 API 게이트웨이가 요청을 받고 각각 서비스에 맞게 분산하여 정확한 위치로 전달해줍니다. 이와 같이 프로세스를 구축하기 위해서는 호출할 서비스를 찾는 Service Discovery가 필요하며 API 게이트웨이는 Service Discovery을 연결하여 필요한 요청에 정확하게 호출 할 수 있게 해줄수 있습니다.
Spring Cloud Netflix Eureka를 활용하여 MSA 를 구성해보고자 합니다.
실습
1.1) Eureka Server 생성하기
Intelli J, eclipse 등 사용하는 툴에서 스프링 부트를 선택하여 패키지와 jdk 등 설정을 상황에 맡게 설정
저의 경우 JDK 17과 스프링 부트 3.3.3 을 사용하엿습니다.
의존성 추가 : Eureka Server , API 게이트웨이
1.2) 설정
1.2.1) application.yml
spring:
application:
name: EurekaServer
server:
port: 8761
eureka:
client:
register-with-eureka: false
fetch-registry: false
eureka.client.register-with-eureka: 현재 애플리케이션을 Eureka 서버에 등록하지 않도록 설정합니다. 이 속성을 false로 설정하면 이 애플리케이션은 Eureka 서버에 자신을 등록하지 않습니다.
eureka.client.fetch-registry: 현재 애플리케이션은 Eureka 서버로부터 등록 정보를 가져오지 않도록 설정합니다. 이 속성을 false로 설정하면 이 애플리케이션은 Eureka 서버로부터 등록된 서비스 목록을 받아오지 않습니다.
1.2.2) Annotation
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
@SpringBootApplication
@EnableEurekaServer
public class EurekaServerApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaServerApplication.class, args);
}
}
@EnableEurekaServer 애노테이션을 추가하여 Eureka 서버로서 동작하게 합니다.
1.3) 실행
서버를 가동하고 http://localhost:8761 접속시 위와 같은 화면이 나타납니다.
2.1) API 게이트웨이 생성하기
의존성 추가 : Eureka Discovery Client, GateWay
2.2) 설정
2.2.1 ) application.yml
server:
port: 9000
eureka:
client:
register-with-eureka: true
fetch-registry: true
service-url:
defaultZone: http://localhost:8761/eureka
spring:
application:
name: api-gateWay
cloud:
routes:
- id: user-service
uri: lb://USER-SERVICE
predicates:
- Path=/api/**
- id: menu-service
uri: lb://MENU-SERVICE
predicates:
- Path=/menu/**
server.port : API Gateway 서버의 포트를 9000으로 등록합니다. 클라이어트는 이 포트를 통해 API Gateway에 요청할 수 있습니다.
eureka.client.register-with-eureka : 현재 애플리케이션을 Eureka 서버에 등록하도록 설정합니다.
eureka.client.fetch-register : Eureka 서버로부터 등록된 서비스 목록을 가져오도록 설정 합니다. API Gateway는 Eureka서버로부터 등록된 서비스들의 목록을 얻을 수 있습니다. 30초마다 Eureka Client 가 유레카 레지스트리 변경 사항 여부 재확인합니다.
spring.application.name : 애플리케이션 이름을 apigateway-service로 지정합니다. 이 이름은 Eureka 서버에 등록될 때 사용됩니다.
spring.cloud.gateway.routes : 이 설정은 현재 애플리케이션이 API Gateway일 경우 설정하는 부분입니다.
id : 라우트의 고유 식별자로 사용됩니다.
uri : 해당 라우트로 들어온 요청을 USER-SERVICE라는 Eureka에 등록된 서비스로 라우팅합니다.
predicates : 해당 라우트를 적용할 조건을 지정합니다.
정리하자면, /users/** 경로로 api gatway 애플리케이션에 요청할 경우, Eureka에서 USER-SERVICE를 찾은 다음 해당 애플리케이션으로 라우팅 됩니다. 로드 밸런서(lb)가 사용되며, 만약 USER-SERVICE라는 이름의 애플리케이션이 2개 이상 등록된 경우, 라운드 로빈 방식으로 동작하여 요청이 각각의 서비스에 균등하게 분배됩니다.
2.3)실행
API_GATEWAY 라는 이름으로 Eureka 서버에 등록 되었습니다.
3.1) Eureka Client 생성하기
의존성으로 Eureka Discovery Client, Spring Web 은 필수입니다. Eureka client로 사용하며 실제로 웹으로 띄워놓기 위해 필요하며 나머지는 프로젝트 구성을 위해서 선택한 의존성들입니다.
3.2) 설정
3.2.1 ) application.yml
spring:
application:
name: user-service
server:
port: 9002
servlet:
session:
timeout: 60m
persistent: true
eureka:
client:
register-with-eureka: true
fetch-registry: true
service-url:
defaultZone: http://localhost:8761/eureka
server.port : API Gateway 서버의 포트를 9000으로 등록합니다. 클라이어트는 이 포트를 통해 API Gateway에 요청할 수 있습니다.
eureka.client.register-with-eureka : 현재 애플리케이션을 Eureka 서버에 등록하도록 설정합니다.
eureka.client.fetch-register : Eureka 서버로부터 등록된 서비스 목록을 가져오도록 설정 합니다. API Gateway는 Eureka서버로부터 등록된 서비스들의 목록을 얻을 수 있습니다. 30초마다 Eureka Client 가 유레카 레지스트리 변경 사항 여부 재확인합니다.
spring.application.name : 애플리케이션 이름을 user-service로 지정합니다. 이 이름은 Eureka 서버에 등록될 때 사용됩니다.
3.2.2) Annotation
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
@SpringBootApplication
@EnableDiscoveryClient
public class UserServiceApplication {
public static void main(String[] args) {
SpringApplication.run(UserServiceApplication.class, args);
}
}
@EnableDiscoveryClient 애노테이션을 추가하여 서비스 디스커버리 클라이언트로 사용
최신 Spring Cloud에서는 해당 애노테이션을 명시하지 않아도 된다. 보여주기 위한 용도로 사용할 수 있겠다. 실제로 해당 애노테이션을 지워도 Eureka Server에 등록된다.
3.3) 실행
저는 두개의 서비스를 생성하였고 user-service, menu-service 두개의 service가 정상적으로 올라가 있습니다.
4.1) 테스트
user-service 는 /api로 mapping, menu-service 는 /menu로 mapping이 되어 있습니다.
9000 포트로 /api/board?p_num 으로 보냈고 9002 포트의 user-service가 정상 호출되었습니다.
9000 포트 / menu/products 요청하였고 9003포트의 menu-service가 정상 호출 되었습니다.
'WEB > Spring' 카테고리의 다른 글
Spring Boot JWT(JSON Web Token) 설정하기 (1) | 2024.09.05 |
---|---|
Spring Boot AOP 적용 방법(Log, Transaction) (4) | 2024.09.03 |
스프링 IOC컨테이너 - DI, DL (0) | 2024.03.23 |
스프링에서 Service ServiceImpl 사용하는 이유 (0) | 2024.03.23 |
스프링 전역 예외처리 (0) | 2024.03.23 |