[关闭]
@tenlee 2018-12-28T10:44:02.000000Z 字数 2732 阅读 1799

Zuul迁移到Spring-Cloud-Gateway

Spring SpringCloud Gateway


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

迁移Route

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

  1. spring.cloud.gateway.routes[0].id=demo-1
  2. spring.cloud.gateway.routes[0].uri=http://g.cn
  3. spring.cloud.gateway.routes[0].predicates[0]=Path=/demo/**
  4. spring.cloud.gateway.routes[0].filters[0]=StripPrefix=1
  5. 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,其源码如下:

  1. @Override
  2. public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
  3. Route route = exchange.getAttribute(GATEWAY_ROUTE_ATTR);
  4. if (route == null) {
  5. return chain.filter(exchange);
  6. }
  7. log.trace("RouteToRequestUrlFilter start");
  8. URI uri = exchange.getRequest().getURI();
  9. boolean encoded = containsEncodedParts(uri);
  10. URI routeUri = route.getUri();
  11. if (hasAnotherScheme(routeUri)) {
  12. // this is a special url, save scheme to special attribute
  13. // replace routeUri with schemeSpecificPart
  14. exchange.getAttributes().put(GATEWAY_SCHEME_PREFIX_ATTR, routeUri.getScheme());
  15. routeUri = URI.create(routeUri.getSchemeSpecificPart());
  16. }
  17. URI mergedUrl = UriComponentsBuilder.fromUri(uri)
  18. // .uri(routeUri)
  19. .scheme(routeUri.getScheme())
  20. .host(routeUri.getHost())
  21. .port(routeUri.getPort())
  22. .build(encoded)
  23. .toUri();
  24. exchange.getAttributes().put(GATEWAY_REQUEST_URL_ATTR, mergedUrl);
  25. return chain.filter(exchange);
  26. }

迁移Filter

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

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

实现。

  1. ServerHttpRequest.Builder builder = exchange.getRequest().mutate()
  2. .header(Constants.HEADER_REQUEST_URI, exchange.getRequest().getURI().getPath());
  3. ServerWebExchange newExchange = exchange.mutate().request(builder.build()).build();
  4. return chain.filter(newExchange);
  1. JsonObject result = new JsonObject();
  2. return Mono.defer(() -> {
  3. setResponseStatus(exchange, HttpStatus.UNAUTHORIZED);
  4. final ServerHttpResponse response = exchange.getResponse();
  5. byte[] bytes = new byte[0];
  6. try {
  7. bytes = objectMapper.writeValueAsBytes(result);
  8. } catch (JsonProcessingException e) {
  9. e.printStackTrace();
  10. }
  11. DataBuffer buffer = exchange.getResponse().bufferFactory().wrap(bytes);
  12. response.getHeaders().set("Content-Type", "application/json");
  13. return response.writeWith(Flux.just(buffer));
  14. });
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注