Spring全家桶

Zuul迁移到Spring-Cloud-Gateway

2018-12-28  本文已影响0人  tenlee

Spring SpringCloud Gateway


前面已经做过性能比较了,Spring-Cloud-Gateway确实比Zuul 1性能更强,并且Spring也不在支持Zuul 2 了。
以下是简单的迁移方案.

迁移Route

如果请求/demo/get,想要转发到http://g.cn/real_context_path/get.

zuul.routes.demo-1.path=/demo/**
zuul.routes.demo-1.url=http://g.cn/real_context_path
spring.cloud.gateway.routes[0].id=demo-1
spring.cloud.gateway.routes[0].uri=http://g.cn
spring.cloud.gateway.routes[0].predicates[0]=Path=/demo/**
spring.cloud.gateway.routes[0].filters[0]=StripPrefix=1
spring.cloud.gateway.routes[0].filters[1]=PrefixPath=/real_context_path

这里使用了Path Route Predicate Factory, StripPrefix GatewayFilter FactoryPrefixPath GatewayFilter Factory
注意:如果uri写成http://g.cn/real_context_path是无效的,Spring Gateway只读取其中的Scheme, Host, Port,其源码如下:

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        Route route = exchange.getAttribute(GATEWAY_ROUTE_ATTR);
        if (route == null) {
            return chain.filter(exchange);
        }
        log.trace("RouteToRequestUrlFilter start");
        URI uri = exchange.getRequest().getURI();
        boolean encoded = containsEncodedParts(uri);
        URI routeUri = route.getUri();

        if (hasAnotherScheme(routeUri)) {
            // this is a special url, save scheme to special attribute
            // replace routeUri with schemeSpecificPart
            exchange.getAttributes().put(GATEWAY_SCHEME_PREFIX_ATTR, routeUri.getScheme());
            routeUri = URI.create(routeUri.getSchemeSpecificPart());
        }

        URI mergedUrl = UriComponentsBuilder.fromUri(uri)
                // .uri(routeUri)
                .scheme(routeUri.getScheme())
                .host(routeUri.getHost())
                .port(routeUri.getPort())
                .build(encoded)
                .toUri();
        exchange.getAttributes().put(GATEWAY_REQUEST_URL_ATTR, mergedUrl);
        return chain.filter(exchange);
    }

迁移Filter

Filter的迁移也比较简单,从原来的继承ZuulFilter改为实现接口
GlobalFilter或自定义Filter, Ordered.

exchange.then(Mono.fromRunnable(() -> {
            ServerHttpResponse response = exchange.getResponse();
            LOGGER.info(response.getStatusCode());
        }));

实现。

 ServerHttpRequest.Builder builder = exchange.getRequest().mutate()
                .header(Constants.HEADER_REQUEST_URI, exchange.getRequest().getURI().getPath());

        ServerWebExchange newExchange = exchange.mutate().request(builder.build()).build();
        return chain.filter(newExchange);
JsonObject result = new JsonObject();
return Mono.defer(() -> {
            setResponseStatus(exchange, HttpStatus.UNAUTHORIZED);
            final ServerHttpResponse response = exchange.getResponse();
            byte[] bytes = new byte[0];
            try {
                bytes = objectMapper.writeValueAsBytes(result);
            } catch (JsonProcessingException e) {
                e.printStackTrace();
            }
            DataBuffer buffer = exchange.getResponse().bufferFactory().wrap(bytes);
            response.getHeaders().set("Content-Type", "application/json");
            return response.writeWith(Flux.just(buffer));
        });
上一篇下一篇

猜你喜欢

热点阅读