한이음 프로젝트

[한이음] MSA 프로젝트(5) - Spring Cloud Gateway 사용하기

딤섬뮨 2022. 8. 17. 00:51
728x90

이번에는 MSA에서 중요한 부분인 gateway를 구현하고자 한다.
사실 gateway도 담당자가 있긴 하지만 내가 구현해보았다,

implementation 'org.springframework.cloud:spring-cloud-starter-netflix-zuul'


원래는 zuul로 구현하려 했는데 계속 다음 에러가 떠서 보니깐... 지원 안 하는 듯
아니 근데 다시 하니깐 되네 뭐람..
java - Can't import Netflix Zuul in Intellij Idea - Stack Overflow

Can't import Netflix Zuul in Intellij Idea

I am trying to follow a tutorial and build an API Gateway for my microservices. However when I write @EnableZuulProxy above the main method, IntelliJ can't find the annotation. I have cloned a GitHub

stackoverflow.com


"spring-cloud-dependencies does not have Zuul version defined" because Zuul is no longer supported. Spring Boot currently suggests you should migrate to cloud gateway from Zuul.

그래도 정 떨어져서 그냥 spring cloud gateway써야게씀 ㅋ.


마찬가지로 gateway라는 모듈도 하나 생성해준다.

1. 유레카 클라이언트 선언


1. implementation에 유레카 클라이언트 + gateway를 넣어주고

implementation("org.springframework.cloud:spring-cloud-starter-gateway")
implementation("org.springframework.boot:spring-boot-starter-actuator")
implementation 'org.springframework.cloud:spring-cloud-starter-netflix-eureka-client'

2. annotation 붙이고

@SpringBootApplication
@EnableEurekaClient
public class BblGatewayApplication {

  public static void main(String[] args) {
    SpringApplication.run(BblGatewayApplication.class, args);
  }

}

그 후 application.yml을 다음과 같이 설정해준다.

spring:
  application:
    name: bbl-gateway

eureka:
  instance:
    prefer-ip-address: true
  client:
    register-with-eureka: true
    fetch-registry: true
    serviceUrl:
      defaultZone: http://localhost:8761/eureka/
  
  
server.port : 8080



여기까지는 지난번 글을 참조하면 쉽게 따라올 수 있다.

gateway가 등록된 것을 볼 수 있다.


2. Gateway 설정


1. gateway application.yml을 설정해준다.

eureka:
  instance:
    prefer-ip-address: true
  client:
    register-with-eureka: true
    fetch-registry: true
    serviceUrl:
      defaultZone: http://localhost:8761/eureka/


server.port: 8080

spring:
  application:
    name: bbl-gateway

  cloud:
    gateway:
      routes:
        - id: bbl-career
          uri: http://localhost:8011 # 포워딩할 주소, http://localhost:8000/user 로 들어오면 http://localhost:8011 로 포워딩
          predicates:
            - Path=/Bblcareer/** # 해당 gateway 서버의 /Bblcareer/**로 들어오는 요은 bbl-career로 인식하겠다는 조건
      

  main:
    web-application-type: reactive


각 서비스 모듈(bbl-career)의 이름을 명시해주고, 그 포트(8011)에 포워딩시켜주면 된다.

그 이후 유레카 서버 - 서비스 서버(bbl-career) - 게이트웨이 서버 순으로 켜준 다음에 api를 던져보면 된다.

기존에 서비스 서버 8011 port에 직접 localhots:8011/careers 이렇게 던졌다면
여기서는 gateway 포트에 predicates에 명시한 대로 요청을 보내면 된다.

ex ) gateway port가 8080이고 predicates.paths = /Bblcareer/**라면 주소는 localhost:8080/Bblcareer/careers

처음에 404 에러가 계속 떠서 삽질을 하다가 빛의 블로그를 발견했다.

이유는 다음과 같았다.

Bblcareer라는 서비스에서는 /careers로만 라우팅이 되는데
gateway를 통하면서 Bblcareer/careers로 요청이 들어와서 라우팅이 안 되는 것이다.
고로 다음 코드를 추가해서 경로를 수정해서 서비스에 요청해준다.

    filters:
            - RewritePath=/Bblcareer/?(?<segment>.*), /$\{segment}


완성된 appication.yml은 다음과 같다.

eureka:
  instance:
    prefer-ip-address: true
  client:
    register-with-eureka: true
    fetch-registry: true
    serviceUrl:
      defaultZone: http://localhost:8761/eureka/


server.port: 8080

spring:
  application:
    name: bbl-gateway

  cloud:
    gateway:
      routes:
        - id: bbl-career
          uri: http://localhost:8011 # 포워딩할 주소, http://localhost:8000/user 로 들어오면 http://localhost:64412 로 포워딩
          predicates:
            - Path=/Bblcareer/** # 해당 gateway 서버의 /user/**로 들어오는 요은 user-service로 인식하겠다는 조건
          filters:
            - RewritePath=/Bblcareer/?(?<segment>.*), /$\{segment}

  main:
    web-application-type: reactive


실제로 다음 gateway 포트를 사용한 주소에 요청을 하여 200 response를 얻었다.

728x90