SpringBoot에서의 MSA는 크게 3가지로 분류된다.
- 서비스 등록 센터 - Eureka Server
- API 라우팅 - API Gateway
- 서비스 인스턴스 - Eureka Cilent
그리고 Spring 환경에선 위의 3가지를 사용해 MSA를 편리하게 구축하고자 Spring Cloud 를 사용한다.
서비스 등록 센터 - Eureka Sever
Eureka Client 에 등록된 각 서비스(Member, Order, Product …)를 관리하는 서버이다.
build.gradle
implementation 'org.springframework.cloud:spring-cloud-starter-netflix-eureka-server'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
application.yml
server:
port: 8761
spring:
application:
name: eureka-server
eureka:
client:
register-with-eureka: false
fetch-registry: false
- server.port : Eureka Server의 포트를 정하는데 사용
- spring.application.name : 이 애플리케이션 이름을 정함
- eureka.client
- register-with-eureka : 해당 애플리케이션을 서비스로 등록할지 여부를 판단함
- fetch-registry : Eureka Client가 Eureka Server로부터 서비스 등록 정보를 가져올지 여부를 설정
Main
@EnableEurekaServer
@SpringBootApplication
public class EurekaServerApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaServerApplication.class, args);
}
}
- @EnableEurekaServer : 이 프로젝트를 Eureka Server 로 등록함
API 라우팅 - API GateWay
사용자에게 요청이 오면, 해당 요청을 처리하기 위한 서비스를 Eureka Server 에서 찾고, 찾았으면 해당 서비스에게 요청을 전달한다.
build.gradle
implementation 'org.springframework.cloud:spring-cloud-starter-gateway-mvc'
implementation 'org.springframework.cloud:spring-cloud-starter-netflix-eureka-client'
application.yml
server:
port: 9000
eureka:
client:
register-with-eureka: true
fetch-registry: true
service-url:
defaultZone: <http://localhost:8761/eureka>
spring:
application:
name: apigateway-service
cloud:
gateway:
mvc:
routes:
- id: product-service
uri: lb://PRODUCT-SERVICE
predicates:
- Path=/products/**
- id: order-service
uri: lb://ORDER-SERVICE
predicates:
- Path=/orders/**
- eureka.client
- service-url.defaultZone : Eureka Server의 URL을 입력함
- spring.cloud.gateway.mvc.routes : 해당 프로젝트가 API Gateway일 경우 세부 설정을 위해 사용함
- id : 여러 개의 라우트가 존재할 수 있으므로, 각 라우트의 고유 식별자로 사용됨
- uri : 해당 라우트로 요청이 들어올 경우, Eureka Server에 등록된 uri에 요청을 전달함
- predicates : 사용자가 요청한 URL 타입을 설정함
서비스 인스턴스 - Eureka Client
사용자의 요청을 처리하는 비즈니스 로직이 담긴 서버를 담당한다.
→ MemberService, ProductService, OrderService …
build.gradle
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.cloud:spring-cloud-starter-netflix-eureka-client'
implementation 'org.springframework.kafka:spring-kafka'
application.yml
server:
port: 8081
eureka:
client:
register-with-eureka: true
fetch-registry: true
service-url:
defaultZone: <http://127.0.0.1:8761/eureka>
spring:
application:
name: order-service
kafka:
consumer:
bootstrap-servers: localhost:9092
group-id: dev
auto-offset-reset: earliest
key-deserializer: org.apache.kafka.common.serialization.StringDeserializer
value-deserializer: org.apache.kafka.common.serialization.StringDeserializer
producer:
bootstrap-servers: localhost:9092
key-serializer: org.apache.kafka.common.serialization.StringSerializer
value-serializer: org.apache.kafka.common.serialization.StringSerializer
- spring.kafka
- consumer : 메시지를 받는 사람
- bootstrap-servers : Kafka 브로커 서버의 주소로, Consumer가 이 서버와 연결하여 메시지를 구독하게 됨
- group-id : Kafka Consumer가 속한 소비자 그룹의 ID
- auto-offset-reset : Kafka Consumer가 처음으로 읽기 시작할 위치를 정의
- earliest: 가장 오래된 메시지부터 읽기 시작
- latest: 가장 최근 메시지부터 읽기 시작
- key-deserializer : Consumer가 메시지의 키를 어떻게 역직렬화할지 정의
- value-deserializer : Consumer가 메시지의 값을 어떻게 역직렬화할지 정의
- producer : 메시지를 보낸 사람
- bootstrap-servers : Kafka 브로커 서버의 주소로, Producer가 이 서버와 연결하여 메시지를 전송하게 됨
- key-deserializer : Producer가 메시지의 키를 어떻게 직렬화할지 정의
- value-deserializer : Producer가 메시지의 값을 어떻게 직렬화할지 정의
- consumer : 메시지를 받는 사람
참고로 여기선 모든 메시지의 값을 문자열 형태로 역직렬화한다.
- org.apache.kafka.common.serialization.StringSerializer
- org.apache.kafka.common.serialization.StringDeserializer
Main
@EnableDiscoveryClient
@SpringBootApplication
public class OrderApplication {
public static void main(String[] args) {
SpringApplication.run(OrderApplication.class, args);
}
}
- @EnableDiscoveryClient : 이 프로젝트를 디스커버리 클라이언트(Eureka Client)로 등록함
OrderController
@RestController
@RequiredArgsConstructor
@RequestMapping("/orders")
public class OrderController {
@GetMapping
public String test() {
return "Order Controller";
}
}
- 테스트용 컨트롤러
테스트
Eureka Server, Eureka Client, API Gateway를 모두 실행하고 API Gateway의 포트인 9000 포트로 요청을 보낸다.
http://localhost:9000/orders
결과는 API Gateway로 요청을 보냈지만, OrderService 까지 요청이 전달된 걸 보니, API Gateway가 잘 동작한다는 것을 알 수 있다.
이제 사용자와 서비스간의 통신은 잘 이루어진다. 그럼 이젠 각 서비스간의 통신을 구현해야 한다.
보통 서비스간의 통신에는 RabbitMQ나 Kafka를 사용한다.
'Spring > MSA' 카테고리의 다른 글
[MSA] Spring Boot + Kafka를 사용한 채팅 (3) (Feat : Prometheus + Grafana) (0) | 2025.02.12 |
---|---|
[MSA] Spring Boot + Kafka를 사용한 채팅 (2) (1) | 2024.10.21 |
[MSA] Spring Boot + Kafka를 사용한 채팅 (1) (3) | 2024.10.05 |
[MSA] Spring Boot + MSA (2) (Feat : Kafka) (0) | 2024.09.25 |