공부/Spring

Spring Cloud로 개발하는 마이크로서비스 애플리케이션_API Gateway Service_1

데부한 2023. 1. 30. 01:48
반응형

 

 

Spring Cloud로 개발하는 마이크로서비스 애플리케이션(MSA)

API Gateway란?

API Gateway Service는 사용자가 설정한 Routing 설정에 따라 각 endpoint로 client를 대신해서 요청하고, 응답을 받으면 다시 client에게 전달해주는 역할을 한다.

시스템의 내부 구조는 숨기고 외부의 요청에 대해 적절한 형태로 가공해서 응답할 수 있는 장점이 있다.

API Gateway Service가 없을 시에 client에서는 microservice를 호출할 때, 클라이언트 쪽에서 endpoint를 설정하게 된다. 그런데 만약 microservice의 설정이 변경되어 endpoint가 변경되거나, 새로운 microservice가 추가되어 이에 해당하는 endpoint를 client에 추가할 때 client도 관련해서 수정 및 재배포가 이뤄저야 한다. 이러한 불편함을 없애고자 단일 진입점이 존재하는 개발이 필요하게 되었다.

출처 : https://learn.microsoft.com/ko-kr/dotnet/architecture/microservices/architect-microservice-container-applications/direct-client-to-microservice-communication-versus-the-api-gateway-pattern

 

API Gateway 기능

  • 인증 및 권한 부여
  • 서비스(마이크로서비스 등) 검색 통합
  • 응답 캐싱
  • 정책, 회로 차단기 및 QoS 다시 시도
  • 속도 제한
  • 부하 분산
  • 로깅, 추적, 상관 관계
  • 헤더, 쿼리 문자열 및 청구 변환
  • IP 허용 목록에 추가

 

Netflix Ribbon

  • Spring Cloud에서의 MSA간 통신
    • RestTemplate
      • 전통적인 사용법. 하나의 웹 어플리케이션에서 다른 어플리케이션을 사용하기 위해 사용된 API
      • 다른 어플리케이션을 호출할 때 접속하고자하는 서버의 주소, port 번호 등을 기재해야했다.
    • Feign Client
      • Spring Cloud에서 사용하는 API
      • interface를 생성하고 외부 microservice 이름만으로 다른 microservice를 호출할 수 있음
  • Ribbon : Client side Load Balancer
    • Spring Cloud에서 Load Balancer로 Ribbon 채택. Ribbon은 Netfliex에서 만든 서비스.
    • 리액트와 같이 비동기를 사용하는 기술들과의 호환이 잘 안되어 최근에는 잘 사용하지 않음
    • Spring Cloud Ribbon은 Spring Boot 2.4에서 Maintenance 상태가 되었음
      • Maintenace : 다음 버전에서 사용할지 이 기술을 빼거나 보완하려는 상태
    • 서비스 이름으로 호출
    • Health Check

 

Netflix Zuul

  • 역할
    • Routing
    • API Gateway
  • Spring Cloud Zuul은 Spring Boot 2.4에서 Maintenance 상태이다.

아래 링크로 들어가면 관련 내용들이 적혀있다.

 

Spring Cloud Greenwich.RC1 available now

<p>On behalf of the community, I am pleased to announce that the Release Candidate 1 (RC1) of the <a href="https://cloud.spring.io">Spring Cloud Greenwich</a> Release Train is available today. The release can be found in <a href="https://repo.spring.io/mil

spring.io

maintenance list

해결책까지 나와있다.

버전을 낮춰야할지; 아니면 저 해결책 방법으로 강의를 계속 진행할지 좀 고민해봐야겠다.. 만약 후자 방법으로 한다면 도움이 많이 될 거 같긴한데 시간이 따라줄지 모르겠다. 아무튼 일단 못 먹어도 고!

 

 

Netflix Zuul 구현 (Spring Cloud Gateway)

First Service, Second Service 프로젝트 생성

  • Spring Boot : 2.7.8
  • Dependencies : Lombok, Spring Web, Eureka Discovery Client

 

새로운 프로젝트를 하나 더 만들어준다.

 

FirstServiceController.java 생성

@RestController
@RequestMapping("/")
public class FirstServiceController {

    @GetMapping("/welcome")
    public String welcome() {
        return "Welcome to the First Service";
    }
}

 

application.properties → application.yml 변경 및 수정

server:
  port: 8082

spring:
  application:
     name: my-second-service
       
eureka:
  client:
    fetch-registry: false
    register-with-eureka: false

 

위 설정 사항을 second-service에서도 설정해준다. First-service에서 만들었던 컨트롤러도 복붙하자.

@RestController
@RequestMapping("/")
//@EnableEurekaClient
public class SecondServiceController {

    @GetMapping("/welcome")
    public String welcome() {
        return "Welcome to the second Service"; //내용을 좀 변경했다.
    }
}

 

두 개 프로젝트 모두 서버를 실행해보자.

 

 

Netflix Zuul 프로젝트 생성(Spring Cloud Gateway)

  • 강의에서는 Spring Boot 버전 2.3.8을 선택하여 Zuul을 사용할 수 있지만, 나는 Spring Boot 2.7.8을 선택하여 Spring Cloud Gateway를 사용했다.
  • Spring Boot : 2.7.8
  • Dependencies : Lombok, Spring Web, Spring Cloud Gateway(강의에선 Zuul)

 

GatewayServiceApplication.java

강의에서는 @EnableZuulProxy 어노테이션을 붙였는데 Gateway는.....뭘 붙여야할까...?

검색해보니 따로 @EnableZuulProxy와 비슷한 기능을하는 어노테이션을 붙여주지 않아도 되는 거 같다.

 

application.properties → application.yml 변경 및 수정

server:
  port: 8000
  
spring:
  application:
    name: my-gateway-service

강의에선 Zuul과 관련된 설정 코드를 아래와 같이 작성했다.

zuul:
  routes:
    first-service:
      path: /first-service/**
      url: http://localhost:8081
    second-service:
      path: /second-service/**
      url: http://localhost:8082

 

Spring Cloud Gateway는 아래와 같이 작성하면 된다.

spring:
    cloud:
      gateway:
        routes:
          - id: gateway_1
            uri: http://localhost:8081
            predicates:
              - Path=/first-service/**
            filters:
              - RewritePath=/first-service/(?<segment>.*), /$\{segment}
          - id: gateway_2
            uri: http://localhost:8082
            predicates:
              - Path=/second-service/**
            filters:
              - RewritePath=/second-service/(?<segment>.*), /$\{segment}

처음에는 filters에 RewritePath 속성을 안 줬더니 계속 404 에러가 발생했다. 구글링 하다가 우연히 본 속성인데, 혹시 몰라 적용해보니 정상적으로 동작했다. 해결은 됐지만 원인을 알 수가 없어서 계속 더 찾아봤는데 또 혹시나하고 first-service 프로젝트의 FirstServiceController의 @RequestMapping 경로를 ("/")에서 ("/first-service/")로 변경해주니 RewritePath 속성이 없어도 통신이 잘 되는 걸 확인할 수 있었다.

@RestController
@RequestMapping("/first-service/")
//@EnableEurekaClient
public class FirstServiceController {

    @GetMapping("/welcome")
    public String welcome() {
        return "Welcome to the First Service";
    }
}

 

 

그래도 어쨌든 강의 기준으로 작성해야하니 @RequestMapping 경로를 원복하고 RewritePath 속성을 주어서 해결했다.

 

- 출처 : 인프런 Spring Cloud로 개발하는 마이크로서비스 애플리케이션(MSA) 강의

반응형