Hello, Freakin world!

[Zuul] 경로 라우팅하기 본문

Spring Cloud/Gateway

[Zuul] 경로 라우팅하기

johnna_endure 2021. 3. 11. 16:36

이번 글에서는 주울로 들어오는 url을 라우팅하는 방법에 대해 살펴보겠습니다.


1. 서비스 디스커버리를 이용한 자동 경로 매핑

 

유레카가 연결돼있다면 기본적으로 동작하는 방식입니다. 아무런 설정이 없다면 이 방식으로 동작합니다.

이 방식은 유레카에 등록된 서비스 ID(applciation.name)을 이용해 url을 자동 매핑합니다.

 

직접 확인해볼까요?

 

application.yml

server:
  port: 9000
# eureka
eureka:
  instance:
    prefer-ip-address: true
  client:
    register-with-eureka: true
    fetch-registry: true
    service-url:
      defaultZone: http://localhost:8761/eureka

# actuator
management:
  endpoint:
    routes:
      enabled: true
    filters:
      enabled: true
  endpoints:
    web:
      exposure:
        include: routes, filters

# zuul
zuul:
  prefix: /api

보통 게이트웨이 URL은 접두사를 포함하므로 "/api"라는 접두사를 추가했습니다.

 

스프링 액추에이터에서 제공하는 /routes 엔드 포인트를 이용해 경로들을 확인해보겠습니다.

 

수정사항 : api/** ->  /api/**

예를 들어, 클라이언트가 보낸 http://localhost:9000/api/member-serivce/members/1http://member-serivce/members/1에 매핑됩니다.


2. 서비스 디스커버리를 이용한 수동 매핑

 

이제 자동 생성되는 URL 대신, 서비스 ID와는 다른 이름으로 매핑해보겠습니다.

URL에 하이픈(-)을 써넣는게 귀찮으니 하이픈을 제거한 이름을 이용합시다.

 

application.yml

...

# zuul
zuul:
  prefix: /api
  ignored-services: '*'
  routes:
    member-service: /memberservice/**

ignored-services 프로퍼티에 자동 생성에서 제외할 서비스를 지정할 수 있습니다.

정규표현식처럼 와일드카드를 사용할 수 있으며 '*'를 사용하면 모든 서비스에 자동 매핑을 적용하지 않습니다.

("mem*"를 사용하면 member-service만 무시됩니다.)


아래에 routes 프로퍼티를 이용해 직접 매핑할 수 있습니다.

routes:
  서비스_ID: 매핑할_URL 

위와 같은 형식으로 매핑이 가능합니다.

 

아래와 같이 매핑됩니다.

http://localhost:9000/api/memberserver/members/1 => http://member-service/members/1


또 다른 방식으로,

routes:
  임의의 이름: 매핑할_URL
  serviceId: 서비스_ID
  
#example
routes:
  ms: /memberservice/**
  serviceId: member-service 

임의의 이름 routes 바로 밑에 값으로 주고, 서비스 ID를 따로 명시하는 방법도 있습니다.

 

/routes를 이용해 경로를 확인해보겠습니다.

 

수정사항 : api/** ->  /api/**

하이픈을 제거한 경로가 유레카가 제공하는 member-service(서비스 ID)에 매핑된 걸 확인할 수 있습니다.


3. 서비스 디스커버리를 사용하지 않는 URL 매핑

유레카를 사용하지 않는 서비스도 주울을 이용해 매핑이 가능합니다.

 

# zuul
zuul:
  prefix: /api
  ignored-services: "*"
  routes:
    member-service:
      path: /memberservice/**
    hello:
      path: /helloservice/**
      url: http://localhost:9090

서버가 하나인 경우 위처럼 url 프로퍼티에 주소를 명시하면 됩니다.

이렇게 등록한 서비스에는 리본, 히스트릭스를 적용할 수 없습니다.

 

일단 라우팅이 동작하는지 확인해보겠습니다.

 

hello 서버는 9090번 포트에서 접근이 가능하고 GET /hello 엔드포인트를 제공합니다. 응답 바디에 "hello"라는 문자열을 포함합니다.

 

제대로 동작하네요!


아래부터는 스프링 공식 문서글을 정리한 글입니다. 실제로 실행해본 건 아니니 참고만 해주세요.

 

히스트릭스 연동하기

위와 같이 사용하면 리본과 히스트릭스를 사용할 수 없다고 했습니다.

 

히스트릭스는 yml 파일에서 서비스 ID를 지정하고 ID에 대해 설정들을 추가해서 다음과 같이 사용할 수 있습니다.

#example
zuul:
  routes:
    echo:
      path: /myusers/**
      serviceId: myusers-service
      stripPrefix: true

hystrix:
  command:
    myusers-service:
      execution:
        isolation:
          thread:
            timeoutInMilliseconds: ...

리본 연동하기

 

여러 개의 서버를 등록하고 리본을 이용해 로드 밸런싱까지 하고 싶다면 두 가지 방법이 있습니다.

 

1. yml 파일에 정의하는 방법

zuul:
  routes:
    echo:
      path: /myusers/**
      serviceId: myusers-service
      stripPrefix: true

myusers-service:
  ribbon:
    NIWSServerListClassName: com.netflix.loadbalancer.ConfigurationBasedServerList
    listOfServers: https://example1.com,http://example2.com
    ConnectTimeout: 1000
    ReadTimeout: 3000
    MaxTotalHttpConnections: 500
    MaxConnectionsPerHost: 100

이 방법은 아래 방법보다 비교적 간단합니다.

서비스 ID 값을 지정하고 리본에 필요한 프로퍼티를 추가해줍니다.

 

listOfServes 프로퍼티에 여러 서버의 주소를 등록할 수 있습니다.


 

2. 리본과 유레카의 연결을 끊고 직접 로드밸런싱 코드를 작성하는 방법

 

이 방법은 상당히 복잡하고 불편합니다.

직접 로드밸런싱 코드를 작성해야하므로 알아야 될 것들이 많습니다. 그래서 패스하겠습니다...

 

jvm 기반 프로젝트가 아니라면 스프링 클라우드 사이드를 이용하면 프로젝트를 감싸 유레카에 등록할 수 있다니 참고하세요.

 

유레카없이 리본을 직접 사용하려면 아래 글을 참고하시면 됩니다.

cloud.spring.io/spring-cloud-netflix/multi/multi_spring-cloud-ribbon.html#spring-cloud-ribbon-without-eureka

 

6. Client Side Load Balancer: Ribbon

Ribbon is a client-side load balancer that gives you a lot of control over the behavior of HTTP and TCP clients. Feign already uses Ribbon, so, if you use @FeignClient, this section also applies. A central concept in Ribbon is that of the named client. Eac

cloud.spring.io

 

Comments