서비스를 구축하다 보면 한 서비스가 고장 났을 때 다른 서비스는 영향을 받지 않기 위해 MSA를 구축해야 한다.
시나리오
회원가입 즉시 웰컴 쿠폰을 발행해줘야 한다.
1. 회원가입을 요청한다.
2. 스프링 클라우드 게이트웨이에 접속한다.
3. 게이트웨이를 거쳐 유레카로 보낸다.
4. 유레카에서 해당 요청을 해당 서비스에 전달하고 로직을 처리한다.
프로젝트 모듈의 구성은 다음과 같다.
- coupon
- customer
- eureka-server
- gateway
※ 이 포스팅은 유레카와 게이트웨이를 구축 및 설정하는 부분만 작성합니다. 자세한 코드는 상단의 깃허브 코드를 참조하세요.
Dependency
기본적으로 유레카 MSA를 구축하기 위해 필요한 디펜던시는 다음과 같다.
유레카
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
게이트웨이
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
서비스 모듈
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
application.yml 설정
유레카
spring:
application:
name: eureka-server
server:
port: 8761
eureka:
client:
fetch-registry: true
register-with-eureka: false
게이트웨이
server:
port: 8000
eureka:
client:
register-with-eureka: true
fetch-registry: true
service-url:
defaultZone: http://localhost:8761/eureka
spring:
application:
name: gateway
cloud:
gateway:
routes:
- id: customer
uri: lb://CUSTOMER
predicates:
- Path=/customer/**
- id: coupon
uri: lb://COUPON
predicates:
- Path=/coupon/**
스프링 클라우드 게이트웨이가 요청 URL을 확인하고 해당 서비스로 전달한다. 이 과정에서 라우팅과 로드 밸런싱을 지원하는 역할을 한다.
(참고로 predicates에서 path 적용한 부분이 해당 url일 경우 라우트 해준다.)
쿠폰 서비스
server:
port: 8081
spring:
application:
name: coupon
eureka:
client:
service-url:
defaultZone: http://localhost:8761/eureka/
fetch-registry: true
register-with-eureka: true
커스터머 서비스
server:
port: 8080
spring:
application:
name: customer
eureka:
client:
service-url:
defaultZone: http://localhost:8761/eureka/
fetch-registry: true
register-with-eureka: true
애노테이션 및 매핑 설정
유레카 메인
@SpringBootApplication
@EnableEurekaServer
public class EurekaServerApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaServerApplication.class, args);
}
}
메인 쪽에
@EnableEurekaServer 를 붙여준다.
게이트웨이
게이트웨이 쪽은 나중에 로깅이나 헤더 요청의 토큰이 유효하지 않으면 처리해 주는 등 역할을 할 수 있지만 이 코드에서는 따로 진행하지 않기 때문에 yml 설정만 하면 된다.
쿠폰(메인)
@SpringBootApplication
@EnableDiscoveryClient
public class CouponApplication {
public static void main(String[] args) {
SpringApplication.run(CouponApplication.class, args);
}
}
메인에서 @EnableDiscoveryClient 를 붙여준다.
쿠폰(컨트롤러)
@RestController
@AllArgsConstructor
@RequestMapping("coupon/api/v1/coupon")
@Slf4j
public class CouponController {
...
}
컨트롤러 부분에서 @RequestMapping 쪽을 보면 url에 coupon이라고 붙은 것을 볼 수 있다.
그 이유는 게이트웨이 yml을 참조해 보면 predicates에서 path를 /coupon/**이라고 해두었기 때문이다.
커스터머(메인)
이쪽 부분도 쿠폰과 동일하다.
@SpringBootApplication
@EnableDiscoveryClient
public class CustomerApplication {
public static void main(String[] args) {
SpringApplication.run(CustomerApplication.class, args);
}
}
애노테이션 동일하게 붙여주고
커스터머(컨트롤러)
@Slf4j
@RestController
@RequestMapping("customer/api/v1/customers")
@AllArgsConstructor
public class CustomerController {
...
}
여기서도 매핑에 customer라고 붙여준 것을 볼 수 있다.
이렇게 하면 간단하게 MSA 구조를 만들어 보았고 이제 쿠폰 쪽 서버를 두 개를 띄워서 처리를 해볼 것이다.
잘 작동된다면 로드 밸런싱이 되면서 처리가 잘 되어야 한다.
요청을 아래와 같이 보내볼 것이다.
POST http://localhost:8000/customer/api/v1/customers
Content-Type: application/json
{
"username": "hyuk",
"email": "hyuk@ooo.com"
}
주소는 쿠폰 포트를 보는 것이 아닌 게이트웨이를 바라보는 것이다.
실행 결과
유레카 서버에 접속
http://localhost:8761/
회원가입 요청 (쿠폰이 바로 발급되어야 함)
응답 값으로 발행이 된 것을 알 수 있다.
(모든 흐름이 잘 되었음)
쿠폰 서버 1 로그
쿠폰 서버 2 로그
쿠폰 서버 1에서는 총 5개의 요청 중 2개를 처리하였고
쿠폰 서버 2에서는 3개를 처리하였다.
이렇게 유레카와 게이트웨이를 사용해서 간단하게 MSA 구조를 구현해 보았다.
'JAVA > Cloud' 카테고리의 다른 글
[OpenFeign] PathVariable annotation was empty on param 1, RequestParam.value() was empty on parameter 2. 오류 해결 (0) | 2023.09.12 |
---|---|
[Spring/Cloud] Spring Cloud Gateway에 JWT 검증 필터 사용하기 (0) | 2023.08.11 |