美文网首页Spring全家桶
Zuul迁移到Spring-Cloud-Gateway

Zuul迁移到Spring-Cloud-Gateway

作者: tenlee | 来源:发表于2018-12-28 18:45 被阅读0次

    Spring SpringCloud Gateway


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

    迁移Route

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

    • Zuul写法
    zuul.routes.demo-1.path=/demo/**
    zuul.routes.demo-1.url=http://g.cn/real_context_path
    
    • Spring Cloud Gateway写法
    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.

    • RequestContext.getCurrentContext().set(...)通过exchange.getAttributes().put(...)实现
    • 获取Route, RequestContext.getCurrentContext().getRouteHost()通过exchange.getAttribute(GATEWAY_ROUTE_ATTR)实现。
    • Zuul 的 Post Filter通过
    exchange.then(Mono.fromRunnable(() -> {
                ServerHttpResponse response = exchange.getResponse();
                LOGGER.info(response.getStatusCode());
            }));
    

    实现。

    • 修改Request
     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);
    
    • 修改Response
    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));
            });
    

    相关文章

      网友评论

        本文标题:Zuul迁移到Spring-Cloud-Gateway

        本文链接:https://www.haomeiwen.com/subject/nrmelqtx.html