Project/MSA 프로젝트

[프로젝트][MSA] API Gateway 작성으로 모듈 별 연결하기

쉬지마 이굥진 2024. 6. 25. 03:00

우선 지금 진행하고 있는 api gateway와 각 도메인들을 모듈별로 구분해놓고, 각 모듈은 각기 다른 포트 번호를 가지고 있는 구조이다. 오늘은 api gateway 모듈에서 게이트웨이 설정으로 각 모듈 별 api 주소를 전부 8080 포트에서 뿌려주도록 변경해 볼 예정이다.

 

의존성 추가

일단 스프링 클라우드 사용을 위한 의존성 추가를 해주자!

ext {
    set('springCloudVersion', "2023.0.0")
}

dependencies {
    testImplementation 'org.springframework.boot:spring-boot-starter-test'

    // 스프링 클라우드
    implementation 'org.springframework.cloud:spring-cloud-starter-gateway'
    implementation group: 'io.netty', name: 'netty-all', version: '4.1.107.Final'
}

dependencyManagement {
    imports {
        mavenBom "org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}"
    }
}

 

Netty를 사용하기 위해 netty-all 의존성을 추가해줬다. Netty는 Spring Cloud Gateway에서 비동기 통신을 위한 네트워크 프레임워크로 사용된다. dependencyManagement 섹션에서 Spring Cloud BOM(Bill Of Materials)을 가져와 의존성 관리를 일관되게 해 줬다.

Spring Cloud Gateway란?
▪️ Spring Cloud Gateway는 Spring 프로젝트의 일부로, MSA 환경에서 API Gateway의 역할을 수행하는 경량의 프레임워크다.
▪️ 주요 기능으로는 요청 라우팅, 필터링, 부하 분산, 보안 등이 있고, 이를 통해 클라이언트 요청을 적절한 마이크로서비스로 전달하며, 다양한 정책을 적용해서 요청을 처리할 수 있다.

 

 

Config 파일 작성

api gateway 모듈의 build.gradle에 의존성을 추가 해 줬다면, 그 다음으론 Config 파일을 작성해 주면 된다.

(application.yml 이나 application.properties 파일에서도 작성할 수 있는데, 필자는 java 코드로 작성 해주었다.)

▪️Java 설정 방식은 코드로 모든 설정을 관리하기 때문에, 설정 파일보다 더 많은 유연성을 제공하며, 복잡한 로직을 처리하기에도 적합하다.
▪️ 또한, 팀 내에서 코드 리뷰를 통해 설정 변경을 관리할 수 있어 유지보수에도 유리하다고 생각했다.
@Configuration
public class FilterConfig {

    @Bean
    public RouteLocator gatewayRoute(RouteLocatorBuilder routeLocatorBuilder) {
        return routeLocatorBuilder.routes()
                .route(r -> r.path("/api/v1/users/**")
                        .uri("http://localhost:8081"))
                .route(r -> r.path("/api/v1/lectures/**")
                        .uri("http://localhost:8082"))
                .route(r -> r.path("/api/v1/coupons/**")
                        .uri("http://localhost:8083"))
                .route(r -> r.path("/api/v1/payments/**")
                        .uri("http://localhost:8084"))
                .build();
    }
}
  • RouteLocatorBuilder : 라우트를 빌드하는 데 사용
  • .route() : 각 경로에 대한 라우팅 규칙을 정의
    • r.path("/api/v1/users/**").uri("<http://localhost:8081>"): /api/v1/users/** 경로로 들어오는 요청을 http://localhost:8081으로 라우팅
    • 마찬가지로 다른 경로에 대해 각각 다른 서비스로 라우팅하는 규칙을 정의

이렇게 설정해주면 각 경로에 대해 특정 마이크로서비스로 요청을 전달할 수 있게 된다!! 그럼 쿠폰 관련 api 테스트를 할 때도 8083 포트가 아닌 8080 포트로 보내주면 되는 것 ㅎ

 

++ (24.06.28) 추가 사항

추가로 .. 쿠폰 모듈에서 변경 사항이 있어 다른 api 엔드포인트를 만들어 준 후 postman으로 기능 테스트를 했는데, 404 Not Found 에러가 떠서 매우 당황을 했다. dto 설정을 잘못했나..? 데이터 타입이 틀렸나..? 하고 보고있는데 알고보니 Api Gateway 필터 설정 문제였다 ㅎ

 

- 포스트맨에서 뱉어내는 에러 반환값

{
    "timestamp": "2024-06-27T16:43:09.329+00:00",
    "path": "/api/v1/coupon-issued/issue",
    "status": 404,
    "error": "Not Found",
    "requestId": "b502c0ed-2"
}

 

- 코드 수정

@Configuration
public class FilterConfig {

    @Bean
    public RouteLocator gatewayRoute(RouteLocatorBuilder routeLocatorBuilder) {
        return routeLocatorBuilder.routes()
                .route(r -> r.path("/api/v1/users/**")
                        .uri("http://localhost:8081"))
                .route(r -> r.path("/api/v1/coupons/**")
                        .uri("http://localhost:8083"))
                // 추가 부분 ////////////////////////
                .route(r -> r.path("/api/v1/coupon-issued/**")
                        .uri("http://localhost:8083"))
                /////////////////////////////////////////
                .route(r -> r.path("/api/v1/payments/**")
                        .uri("http://localhost:8084"))
                ...
                .build();
    }
}

<추후 리팩토링>

 

[리팩토링] MSA 구조에서의 인증/인가 처리

[프로젝트][MSA] API Gateway 작성으로 모듈 별 연결하기우선 지금 진행하고 있는 api gateway와 각 도메인들을 모듈별로 구분해놓고, 각 모듈은 각기 다른 포트 번호를 가지고 있는 구조이다. 오늘은 api

developer-jinnie.tistory.com