010-spring cloud gateway - 필터 - 사용자 정의 부분, 전역 필터, 차이

7069 단어
1. 부분 필터 사용자 정의
사용자 정의 필터는 GatewayFilterOrdered가 필요합니다.그중GatewayFilter에서 이 방법은 당신의 사용자 정의 논리를 실현하는 데 쓰인다
Mono filter(ServerWebExchange exchange, GatewayFilterChain chain);

예: 서비스 응답 시간 통계
1.1 Filer 만들기
public class ElapsedFilter implements GatewayFilter, Ordered {

    private static final Log log = LogFactory.getLog(GatewayFilter.class);
    private static final String ELAPSED_TIME_BEGIN = "elapsedTimeBegin";

    @Override
    public Mono filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        exchange.getAttributes().put(ELAPSED_TIME_BEGIN, System.currentTimeMillis());
        return chain.filter(exchange).then(
                Mono.fromRunnable(() -> {
                    Long startTime = exchange.getAttribute(ELAPSED_TIME_BEGIN);
                    if (startTime != null) {
                        log.info(exchange.getRequest().getURI().getRawPath() + ": " + (System.currentTimeMillis() - startTime) + "ms");
                    }
                })
        );
    }

    @Override
    public int getOrder() {
        return Ordered.LOWEST_PRECEDENCE;
    }
}

요청이 도착했을 때 ServerWebExchange에 속성elapsedTimeBegin을 넣었습니다. 속성 값은 밀리초급 시간 스탬프입니다.그리고 요청 실행이 끝난 후에 우리가 넣었던 시간 스탬프를 꺼냅니다. 현재 시간과의 차이는 요청에 소모되는 시간입니다.이것은 업무와 무관한 로그이기 때문에 OrderedInteger.MAX_VALUE로 설정하여 우선순위를 낮춘다.chain.filter(exchange) 이전에는'pre'부분, 그 다음에는 then 안에는'post'부분이 있었다.
1.2 구성
Filter를 만든 다음 Filter Chain에 추가합니다.
@Bean
public RouteLocator customerRouteLocator(RouteLocatorBuilder builder) {
    // @formatter:off
    return builder.routes()
            .route(r -> r.path("/fluent/customer/**")
                         .filters(f -> f.stripPrefix(2)
                                        .filter(new ElapsedFilter())
                                        .addResponseHeader("X-Response-Default-Foo", "Default-Bar"))
                         .uri("lb://CONSUMER")
                         .order(0)
                         .id("fluent_customer_service")
            )
            .build();
    // @formatter:on
}

참고: 실제 Spring Cloud를 사용하는 경우 Sleuth+Zipkin을 사용하여 시간 소모 분석을 수행해야 합니다.
2. 전역 필터
여러 개의 루트가 하나씩 설정되어야 하며, 아래와 같이 전역적으로 유효할 수 없습니다. (Fluent Java API에서default Filters를 설정할 수 있는 방법을 찾지 못했습니다.)
@Bean
public ElapsedFilter elapsedFilter(){
    return new ElapsedFilter();
}

사용자 정의 필터에는 GlobalFilter 및 Ordered가 필요합니다.
예: token 검증
2.1 Filter 만들기
public class TokenFilter implements GlobalFilter, Ordered {

    @Override
    public Mono filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        String token = exchange.getRequest().getQueryParams().getFirst("token");
        if (token == null || token.isEmpty()) {
            exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
            return exchange.getResponse().setComplete();
        }
        return chain.filter(exchange);
    }

    @Override
    public int getOrder() {
        return -100;
    }
}

2.2 Spring Config에서 이 Bean 구성
@Bean
public TokenFilter tokenFilter(){
    return new TokenFilter();
}

3. Gateway Filter와 Global Filter의 차이
3.1、GatewayFilter
높은 측면에서 볼 때 글로벌 필터는 모든 루트에 적용되고 Gateway 필터는 또는 에 적용된다.
Gateway Filter는 웹Filter에서 Copy로 온 것으로 Filter 필터에 해당하며 방문한 URL에 대해 횡단 처리를 할 수 있으며 시간 초과, 안전 등 장면을 응용할 수 있다.
Gateway Filter와 Global Filter 두 인터페이스에서 정의한 방법은 모두 Mono Filter(ServerWeb Exchange exchange, Gateway Filter Chain chain)이다. 유일한 차이점은 Gateway Filter가 Shortcut Configurable를 계승했고 Global Filter는 어떠한 계승도 하지 않았다는 것이다.
예제 1: Gateway Filter와 RouteLocator 바인딩 사용
3.2、GlobalFilter
Spring Cloud gateway는 Global Filter의 인터페이스를 정의하여 Global Filter를 사용자 정의합니다.GlobalFilter는 모든 라우팅에 적용되는 전체 Filter입니다.
Gateway에서 실행하도록 효력을 발생시키는 방법은 두 가지가 있는데 하나는 직접 @Component 주석을 붙이는 것이고 다른 하나는 Spring Config에서 이 Bean을 설정할 수 있다. 다음과 같다.
 
전재 대상:https://www.cnblogs.com/bjlhx/p/9786681.html

좋은 웹페이지 즐겨찾기