1. 개요


2. 설치

Spring Boot 애플리케이션이다.

https://start.spring.io/ 사이트에서 애플리케이션을 하나 생성한다. 이 때 Dependency에 Zuul을 추가한다.

초간단 Zuul부터 만들어보자.


3. 어노테이션 추가

메인 메소드에 @EnableZuulProxy을 추가한다.

코드가 이런 모양이 된다.

package io.sarc.test.zuultest;
 
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.zuul.EnableZuulProxy;
 
@SpringBootApplication
@EnableZuulProxy
public class ZuulTestApplication {
  public static void main(String[] args) {
    SpringApplication.run(ZuulTestApplication.class, args);
  }
}

4. application.yml

src/main/resources 아래에 있다. 이 파일에 각종 설정이 들어있다고 보면 된다.

spring:
  application:
    name: zuul-test

server:
  port: 9080

ribbon:
  eureka:
    enabled: false

zuul:
  sensitive-headers:
  host:
    connect-timeout-millis: 600000
    socket-timeout-millis: 600000
  routes:
    top-api:
      path: /top
      url: https://aaa.domain.com
      stripPrefix: false
    end-api:
      path: /end
      url: http://bbb.domain.com
      stripPrefix: false

해석하자.

  • 포트는 9080이다.
  • /top 으로 접속하면 (예: http://localhost:9080/top) ▶ https://aaa.domain.com/top 으로 간다.
  • /end 으로 접속하면 (예: http://localhost:9080/end) ▶ http://bbb.domain.com/end 으로 간다.

위에서 /top, /end가 유지되는 것은 stripPrefix가 false이기 때문이다. stripPrefix를 true로 설정하면 뒤로 넘어갈 때 path의 prefix는 떼고 간다.


5. stripPrefix

계속 stripPrefix에 대해 알아본다. 삵 사이트를 예를 들어보자.

5.1. true

    sarcio-api:
      path: /sarcio/**
      url: https://sarc.io
      stripPrefix: true
  • http://localhost:9080/sarcio 로 접속하면  https://sarc.io 으로 간다.
  • http://localhost:9080/sarcio/index.php/cloud/1747-zuul 으로 접속하면 ▶ https://sarc.io/index.php/cloud/1747-zuul 로 간다.

5.2. false

    sarcio-api:
      path: /sarcio/**
      url: https://sarc.io
      stripPrefix: false
  • http://localhost:9080/sarcio 로 접속하면  https://sarc.io/sarcio 로 간다.
  • http://localhost:9080/sarcio/index.php/cloud/1747-zuul 으로 접속하면 ▶ https://sarc.io/sarcio/index.php/cloud/1747-zuul 로 간다.

6. 실제 테스트

실제 테스트가 가능한 설정이다.

spring:
  application:
    name: zuul-test

server:
  port: 9080

ribbon:
  eureka:
    enabled: false

zuul:
  sensitive-headers:
  host:
    connect-timeout-millis: 600000
    socket-timeout-millis: 600000
  routes:
    posts-api:
      path: /posts/**
      url: http://jsonplaceholder.typicode.com/posts
      stripPrefix: true
    comments-api:
      path: /comments/**
      url: http://jsonplaceholder.typicode.com/comments
      stripPrefix: true

예를 들면 http://localhost:9080/posts/1 이다.


7. Filter

7.1. PreFIlter

 xml:lang="java">package io.sarc.test.zuultest;

import javax.servlet.http.HttpServletRequest;

import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import com.netflix.zuul.exception.ZuulException;

public class PreFilter extends ZuulFilter {
    @Override
    public String filterType() {
        return "pre";
    }

    @Override
    public int filterOrder() {
        return 0;
    }

    @Override
    public boolean shouldFilter() {
        return true;
    }

    @Override
    public Object run() throws ZuulException {
        RequestContext ctx = RequestContext.getCurrentContext();
        HttpServletRequest request = ctx.getRequest();
        System.out.println(String.format("%s request to %s", request.getMethod(), request.getRequestURL().toString()));
        return null;
    }
}

7.2. PostFilter

package io.sarc.test.zuultest;
 
import javax.servlet.http.HttpServletResponse;
 
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import com.netflix.zuul.exception.ZuulException;
 
public class PostFilter extends ZuulFilter {
    @Override
    public boolean shouldFilter() {
        return true;
    }
 
    @Override
    public String filterType() {
        return "post";
    }
 
    @Override
    public int filterOrder() {
        return 2;
    }
 
    @Override
    public Object run() throws ZuulException {
        RequestContext ctx = RequestContext.getCurrentContext();
        HttpServletResponse response = ctx.getResponse();
        int statusCode = response.getStatus();
        System.out.println("statusCode="+statusCode);
        return null;
    }
} 

7.3. 메인 메소드

package io.sarc.test.zuultest;
 
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.zuul.EnableZuulProxy;
import org.springframework.context.annotation.Bean;
 
@SpringBootApplication
@EnableZuulProxy
public class ZuulTestApplication {
  public static void main(String[] args) {
    SpringApplication.run(ZuulTestApplication.class, args);
  }
 
  @Bean
  public PreFilter preFilter() {
    return new PreFilter();
  }
 
  @Bean
  public PostFilter postFilter() {
    return new PostFilter();
  }
}

이렇게 하면 로그에 추가 정보가 찍힌다.

GET request to http://localhost:9080/posts/1
statusCode=200