[Spring Boot] Spring Cloud Gateway (1)- 프로젝트 생성

cdwde·2023년 4월 23일
0

MSA 찍먹 여정

목록 보기
4/5

이번에는 API Gateway가 무엇인지, 사용하기 위해서는 어떻게 해야하는지, 간단하게 Spring Cloud Gateway를 사용한 프로젝트를 생성해보겠다.

✅ API Gateway Service

api gateway service는 사용자가 설정한 라우팅 설정에 따라서 각각의 endpoint로 클라이언트 대신 요청해주고, 해당 응답을 받으면 클라이언트에게 전달해주는 일종의 proxy 역할을 해준다.

API Gateway를 사용하면 다음과 같은게 가능하다.

  • 인증 및 권한 부여에 대한 단일 작업 가능
  • 서비스 검색 통합
  • 응답 캐싱
  • 부하 분산
  • 로깅, 추적, 상관 관계
  • circuit breaker로 사용

Spring cloud에서 MSA간의 통신은 RestTemplate or Feign Client 방법이 있다.

  • RestTemplate
    Spring에서 지원하는 객체로 간편하게 Rest 방식 API를 호출할 수 있는 Spring 내장 클래스이다.
    Spring 3.0부터 지원되었지만 5.0부터는 deprecated되었고 WebClient라는 새로운 HTTP 클라이언트를 도입해 요걸 지향한다고 한다.
RestTemplate restTemplate = new RestTemplate();
restTemplate.getForObject("http://localhost:8080/), User.class, 200);
  • Feign Client
    restTemplate보다 훨씬 간편하게 API 호출 가능.
    마이크로 서비스 이름 가지고 호출이 가능하다.
@FeignClient("stores")
public interface StoreClient {
  @RequestMapping(method=RequestMethod.GET, value="/stores")
  List<Store> getStores();
}

근데 문제는 LB를 어디에 구축해야 하는가이다.

Netflix Ribbon

요 문제를 해결하기 위해서 사용할 수 있는 것이 Ribbon이다. Ribbon클라이언트 사이드 로드 밸런서로 서비스 이름으로 호출이 가능하고 헬스 체크도 가능하다.
하지만 비동기화방식이 제대로 되지 않기 때문에 요즘에는 잘 사용되지 않는다고 한다.

Netflix Zuul

API Gateway이자 Http Reverse Proxy이다. 하지만 얘도 Maintenance 상태라고 한다...

요기 들어가면 어떤게 Maintenace인지 확인할 수 있다.
https://spring.io/blog/2018/12/12/spring-cloud-greenwich-rc1-available-now#spring-cloud-netflix-projects-entering-maintenance-mode

Spring Cloud Gateway

우리가 사용할 Gateway이다! 아래에서 자세하게 알아보자.

✅ Spring Cloud Gateway

Spring Cloud Gateway는 Tomcat이 아닌 Netty를 사용한다. API GATEWAY는 모든 요청이 통과하는 곳이기 때문에 성능적인 측면이 매우 중요하며 기존의 1THREAD / 1REQUEST 방식인 SPRING MVC를 사용할 경우 성능적인 이슈가 발생할 수 있다.

Netty는 비동기 WAS이고 1THREAD / MANY REQUESTS 방식이기 때문에 기존 방식보다 더 많은 요청을 처리할 수 있다고 한다.

3가지 구성 요소

Spring Cloud Gateway는 크게 3가지 구성요소가 존재한다.

Route

고유 ID, 목적지 URI, Predicate, Filter로 구성된 요소로, GATEWAY로 요청된 URI의 조건이 참일 경우 매핑된 해당 경로로 매칭을 시켜준다.

Predicate

주어진 요청이 주어진 조건을 충족하는지 테스트하는 구성요소이다.

각 요청 경로에 대해 충족하게 되는 경우 하나 이상의 조건자를 정의할 수 있다. 만약 Predicate에 매칭되지 않는다면 HTTP 404 Not Found를 응답한다.

Filter

Gateway 기준으로 들어오는 요청 및 나가는 응답에 대해 수정을 가능하게 해주는 구성요소이다.

Spring cloud gateway를 사용해보자.
먼저 각각의 서비스를 생성해준다.

적용해보기

첫 번째 Service 생성

  • 컨트롤러 생성
@RestController
@RequestMapping("/")
public class FirstServiceController {
  @GetMapping("/welcome")
  public String welcome() {
  	return "welcome to the first service";
  }
}
  • application 클래스에 @EnableDiscoveryClient를 추가해 유레카 서버에 등록됨을 명시해준다.
@SpringBootApplication
@EnableDiscoveryClient
public class XXXApplication {
  ...
}
  • application.yml
server:
  port: 8080

spring:
  application:
    name: my-first-service

eureka:
  instance:
    instance-id: ${spring.cloud.client.hostname}:${spring.application.instance_id:${random.value}}
  client:
    service-url:
      defaultZone: http://127.0.0.1:8761/eureka

두 번째 Service 생성

  • 컨트롤러 생성
@RestController
@RequestMapping("/")
public class SecondServiceController {
  @GetMapping("/welcome")
  public String welcome() {
  	return "welcome to the second service";
  }
}
  • application.yml
server:
  port: 8081 

spring:
  application:
    name: my-second-service

eureka:
  instance:
    instance-id: ${spring.cloud.client.hostname}:${spring.application.instance_id:${random.value}}
  client:
    service-url:
      defaultZone: http://127.0.0.1:8761/eureka

API Gateway 연결

새로운 프로젝트를 생성한다. 필요한 dependency는 DevTools, Eureka Discovery Client, Gateway이다.

  • application.yml
server:
  port: 8000

eureka:
  client:
    register-with-eureka: false
    fetch-registry: false
    service-url:
      defautlZone: http://localhost:8761/eureka

spring:
  application:
    name: apigateway-service
  cloud:
    gateway:
      routes:
        - id: first-service
          uri: http://localhost:8081/
          predicates:
            - Path=/first-service/**
        - id: second-service
          uri: http://localhost:8082/
          predicates:
            - Path=/second-service/**

이제 first-service, second-service, gateway-service를 모두 실행시킨 후 확인해보자.

단순하게 생각했을 때 http://localhost:8000/first-service/welcome를 들어가면 8080 포트로 바뀐 http://localhost:8081/welcome이 나와야하는데 정작 뜨는건 404 페이지이다.

문제

현재는 위처럼 가는게 아닌, 사용자가 요청한 first-service도 같이 붙고 있기 때문에
http://localhost:8000/first-service/welcome -> http://localhost:8081/first-service/welcome 으로 변경되어 404가 떴던 것이다.

해당 문제는 Filter를 사용해서 해결할 수 있다.
이 부분은 다음 글에 정리하겠다!🔥

참고
SPRING CLOUD GATEWAY를 이용한 API GATEWAY 구축기
Spring Cloud로 개발하는 마이크로서비스 애플리케이션(MSA)

0개의 댓글