Spring Cloud Gateway(译)(Part 4)

16. Troubleshooting

本部分介绍使用Spring Cloud Gateway时可能出现的常见问题.

16.1. Log Levels

下面的 loggers 可能在DEBUG and TRACE级别包含有价值的故障排除信息:

  • org.springframework.cloud.gateway
  • org.springframework.http.server.reactive
  • org.springframework.web.reactive
  • org.springframework.boot.autoconfigure.web
  • reactor.netty
  • redisratelimiter

16.2. Wiretap

Reactor Netty HttpClient and HttpServer可以启用监听. 与与 reactor.netty 日志级别设置为DEBUG or TRACE结合使用时, 它将启用信息记录, 例如通过网络发送/接收 的 headers 和 bodies . 要启用监听, 请分别为HttpServerHttpClient设置 spring.cloud.gateway.httpserver.wiretap=truespring.cloud.gateway.httpclient.wiretap=true.

17. Developer Guide

这些是编写网关的某些自定义组件的基本指南.

17.1. Writing Custom Route Predicate Factories

如果想要编写一个Route Predicate,需要实现RoutePredicateFactory借口。 或者继承AbstractRoutePredicateFactory的抽象类。

MyRoutePredicateFactory.java

public class MyRoutePredicateFactory extends AbstractRoutePredicateFactory<HeaderRoutePredicateFactory.Config> {

    public MyRoutePredicateFactory() {
        super(Config.class);
    }

    @Override
    public Predicate<ServerWebExchange> apply(Config config) {
        // grab configuration from Config object
        return exchange -> {
            //grab the request
            ServerHttpRequest request = exchange.getRequest();
            //take information from the request to see if it
            //matches configuration.
            return matches(config, request);
        };
    }

    public static class Config {
        //Put the configuration properties for your filter here
    }

}

17.2. Writing Custom GatewayFilter Factories

若要自定义 GatewayFilter, 你必须实现 GatewayFilterFactory接口. 或者继承 AbstractGatewayFilterFactory抽象类. 如下所示:

Example 73. PreGatewayFilterFactory.java

public class PreGatewayFilterFactory extends AbstractGatewayFilterFactory<PreGatewayFilterFactory.Config> {

    public PreGatewayFilterFactory() {
        super(Config.class);
    }

    @Override
    public GatewayFilter apply(Config config) {
        // grab configuration from Config object
        return (exchange, chain) -> {
            //If you want to build a "pre" filter you need to manipulate the
            //request before calling chain.filter
            ServerHttpRequest.Builder builder = exchange.getRequest().mutate();
            //use builder to manipulate the request
            return chain.filter(exchange.mutate().request(request).build());
        };
    }

    public static class Config {
        //Put the configuration properties for your filter here
    }

}

PostGatewayFilterFactory.java

public class PostGatewayFilterFactory extends AbstractGatewayFilterFactory<PostGatewayFilterFactory.Config> {

    public PostGatewayFilterFactory() {
        super(Config.class);
    }

    @Override
    public GatewayFilter apply(Config config) {
        // grab configuration from Config object
        return (exchange, chain) -> {
            return chain.filter(exchange).then(Mono.fromRunnable(() -> {
                ServerHttpResponse response = exchange.getResponse();
                //Manipulate the response in some way
            }));
        };
    }

    public static class Config {
        //Put the configuration properties for your filter here
    }

}

17.3. Writing Custom Global Filters

若要自定义 global filter, 你必须实现 GlobalFilter 接口. 这会将filter应用于所有请求.

以下示例说明如何分别设置全局前置和后置过滤器:

@Bean
public GlobalFilter customGlobalFilter() {
    return (exchange, chain) -> exchange.getPrincipal()
        .map(Principal::getName)
        .defaultIfEmpty("Default User")
        .map(userName -> {
          //adds header to proxied request
          exchange.getRequest().mutate().header("CUSTOM-REQUEST-HEADER", userName).build();
          return exchange;
        })
        .flatMap(chain::filter);
}

@Bean
public GlobalFilter customGlobalPostFilter() {
    return (exchange, chain) -> chain.filter(exchange)
        .then(Mono.just(exchange))
        .map(serverWebExchange -> {
          //adds header to response
          serverWebExchange.getResponse().getHeaders().set("CUSTOM-RESPONSE-HEADER",
              HttpStatus.OK.equals(serverWebExchange.getResponse().getStatusCode()) ? "It worked": "It did not work");
          return serverWebExchange;
        })
        .then();
}

18. Building a Simple Gateway by Using Spring MVC or Webflux

以下描述了替代样式的网关. 先前的文档均不适用于以下内容.

Spring Cloud Gateway 提供了一个名为ProxyExchange的实用程序对象. 你可以在常规的 Spring web handler 中使用它作为方法参数. 它通过镜像HTTP动词的方法支持基本的下游HTTP交换. 使用MVC, 它还支持通过forward()方法转发到本地处理程序. 要使用 ProxyExchange, 请在类路径中包含正确的模块 ( spring-cloud-gateway-mvcspring-cloud-gateway-webflux).

以下MVC示例代理了对/test到远程服务器下游的请求:

@RestController
@SpringBootApplication
public class GatewaySampleApplication {

    @Value("${remote.home}")
    private URI home;

    @GetMapping("/test")
    public ResponseEntity<?> proxy(ProxyExchange<byte[]> proxy) throws Exception {
        return proxy.uri(home.toString() + "/image/png").get();
    }

}

以下示例使用Webflux执行相同的操作:

@RestController
@SpringBootApplication
public class GatewaySampleApplication {

    @Value("${remote.home}")
    private URI home;

    @GetMapping("/test")
    public Mono<ResponseEntity<?>> proxy(ProxyExchange<byte[]> proxy) throws Exception {
        return proxy.uri(home.toString() + "/image/png").get();
    }

}

ProxyExchange 上的便捷方法使处理程序方法能够发现并增强传入请求的URI路径. 例如, 你可能希望提取路径的尾部元素以将它们传递到下游:

@GetMapping("/proxy/path/**")
public ResponseEntity<?> proxyPath(ProxyExchange<byte[]> proxy) throws Exception {
  String path = proxy.path("/proxy/path/");
  return proxy.uri(home.toString() + "/foos/" + path).get();
}

网关处理程序方法可以使用Spring MVC和Webflux的所有功能. 所以, 你可以注入request headers和query parameters, 例如, 你可以使用mapping annotation中的声明来约束传入的请求. 请参见Spring MVC中的@RequestMapping in Spring MVC 文档.

你可以使用ProxyExchangeheader()方法将 headers 添加到下游响应中.

你还可以通过将mapper 添加到get()方法(和其他方法)来操作 response headers (以及response中的其他元素) . The mapper 是一种Function类型,它接收传入的 ResponseEntity 并将其转换为传出的.

对不传递到下游的 “sensitive” headers (默认情况下为, cookieauthorization) 以及 “proxy” (x-forwarded-*) headers提供良好的支持.

19. Configuration properties

可以在application.properties , application.yml 文件内或作为命令行开关指定各种属性. 本附录提供了常见的 Spring Cloud Gateway 属性列表以及对使用它们的基础类的引用.

属性可以来自类路径上的其他jar文件,因此这不是全部的属性列表。 另外,你也可以定义自己的属性。

Name Default Description
spring.cloud.gateway.default-filters List of filter definitions that are applied to every route.
spring.cloud.gateway.discovery.locator.enabled false Flag that enables DiscoveryClient gateway integration.
spring.cloud.gateway.discovery.locator.filters
spring.cloud.gateway.discovery.locator.include-expression true SpEL expression that will evaluate whether to include a service in gateway integration or not, defaults to: true.
spring.cloud.gateway.discovery.locator.lower-case-service-id false Option to lower case serviceId in predicates and filters, defaults to false. Useful with eureka when it automatically uppercases serviceId. so MYSERIVCE, would match /myservice/**
spring.cloud.gateway.discovery.locator.predicates
spring.cloud.gateway.discovery.locator.route-id-prefix The prefix for the routeId, defaults to discoveryClient.getClass().getSimpleName() + "_". Service Id will be appended to create the routeId.
spring.cloud.gateway.discovery.locator.url-expression 'lb://'+serviceId SpEL expression that create the uri for each route, defaults to: 'lb://'+serviceId.
spring.cloud.gateway.enabled true Enables gateway functionality.
spring.cloud.gateway.filter.remove-hop-by-hop.headers
spring.cloud.gateway.filter.remove-hop-by-hop.order
spring.cloud.gateway.filter.request-rate-limiter.deny-empty-key true Switch to deny requests if the Key Resolver returns an empty key, defaults to true.
spring.cloud.gateway.filter.request-rate-limiter.empty-key-status-code HttpStatus to return when denyEmptyKey is true, defaults to FORBIDDEN.
spring.cloud.gateway.filter.secure-headers.content-security-policy default-src 'self' https:; font-src 'self' https: data:; img-src 'self' https: data:; object-src 'none'; script-src https:; style-src 'self' https: 'unsafe-inline'
spring.cloud.gateway.filter.secure-headers.content-type-options nosniff
spring.cloud.gateway.filter.secure-headers.disable
spring.cloud.gateway.filter.secure-headers.download-options noopen
spring.cloud.gateway.filter.secure-headers.frame-options DENY
spring.cloud.gateway.filter.secure-headers.permitted-cross-domain-policies none
spring.cloud.gateway.filter.secure-headers.referrer-policy no-referrer
spring.cloud.gateway.filter.secure-headers.strict-transport-security max-age=631138519
spring.cloud.gateway.filter.secure-headers.xss-protection-header 1 ; mode=block
spring.cloud.gateway.forwarded.enabled true Enables the ForwardedHeadersFilter.
spring.cloud.gateway.globalcors.add-to-simple-url-handler-mapping false If global CORS config should be added to the URL handler.
spring.cloud.gateway.globalcors.cors-configurations
spring.cloud.gateway.httpclient.connect-timeout The connect timeout in millis, the default is 45s.
spring.cloud.gateway.httpclient.pool.acquire-timeout Only for type FIXED, the maximum time in millis to wait for aquiring.
spring.cloud.gateway.httpclient.pool.max-connections Only for type FIXED, the maximum number of connections before starting pending acquisition on existing ones.
spring.cloud.gateway.httpclient.pool.max-idle-time Time in millis after which the channel will be closed. If NULL, there is no max idle time.
spring.cloud.gateway.httpclient.pool.max-life-time Duration after which the channel will be closed. If NULL, there is no max life time.
spring.cloud.gateway.httpclient.pool.name proxy The channel pool map name, defaults to proxy.
spring.cloud.gateway.httpclient.pool.type Type of pool for HttpClient to use, defaults to ELASTIC.
spring.cloud.gateway.httpclient.proxy.host Hostname for proxy configuration of Netty HttpClient.
spring.cloud.gateway.httpclient.proxy.non-proxy-hosts-pattern Regular expression (Java) for a configured list of hosts. that should be reached directly, bypassing the proxy
spring.cloud.gateway.httpclient.proxy.password Password for proxy configuration of Netty HttpClient.
spring.cloud.gateway.httpclient.proxy.port Port for proxy configuration of Netty HttpClient.
spring.cloud.gateway.httpclient.proxy.username Username for proxy configuration of Netty HttpClient.
spring.cloud.gateway.httpclient.response-timeout The response timeout.
spring.cloud.gateway.httpclient.ssl.close-notify-flush-timeout 3000ms SSL close_notify flush timeout. Default to 3000 ms.
spring.cloud.gateway.httpclient.ssl.close-notify-flush-timeout-millis
spring.cloud.gateway.httpclient.ssl.close-notify-read-timeout SSL close_notify read timeout. Default to 0 ms.
spring.cloud.gateway.httpclient.ssl.close-notify-read-timeout-millis
spring.cloud.gateway.httpclient.ssl.default-configuration-type The default ssl configuration type. Defaults to TCP.
spring.cloud.gateway.httpclient.ssl.handshake-timeout 10000ms SSL handshake timeout. Default to 10000 ms
spring.cloud.gateway.httpclient.ssl.handshake-timeout-millis
spring.cloud.gateway.httpclient.ssl.key-password Key password, default is same as keyStorePassword.
spring.cloud.gateway.httpclient.ssl.key-store Keystore path for Netty HttpClient.
spring.cloud.gateway.httpclient.ssl.key-store-password Keystore password.
spring.cloud.gateway.httpclient.ssl.key-store-provider Keystore provider for Netty HttpClient, optional field.
spring.cloud.gateway.httpclient.ssl.key-store-type JKS Keystore type for Netty HttpClient, default is JKS.
spring.cloud.gateway.httpclient.ssl.trusted-x509-certificates Trusted certificates for verifying the remote endpoint’s certificate.
spring.cloud.gateway.httpclient.ssl.use-insecure-trust-manager false Installs the netty InsecureTrustManagerFactory. This is insecure and not suitable for production.
spring.cloud.gateway.httpclient.websocket.max-frame-payload-length Max frame payload length.
spring.cloud.gateway.httpclient.wiretap false Enables wiretap debugging for Netty HttpClient.
spring.cloud.gateway.httpserver.wiretap false Enables wiretap debugging for Netty HttpServer.
spring.cloud.gateway.loadbalancer.use404 false
spring.cloud.gateway.metrics.enabled true Enables the collection of metrics data.
spring.cloud.gateway.metrics.tags Tags map that added to metrics.
spring.cloud.gateway.redis-rate-limiter.burst-capacity-header X-RateLimit-Burst-Capacity The name of the header that returns the burst capacity configuration.
spring.cloud.gateway.redis-rate-limiter.config
spring.cloud.gateway.redis-rate-limiter.include-headers true Whether or not to include headers containing rate limiter information, defaults to true.
spring.cloud.gateway.redis-rate-limiter.remaining-header X-RateLimit-Remaining The name of the header that returns number of remaining requests during the current second.
spring.cloud.gateway.redis-rate-limiter.replenish-rate-header X-RateLimit-Replenish-Rate The name of the header that returns the replenish rate configuration.
spring.cloud.gateway.routes List of Routes.
spring.cloud.gateway.set-status.original-status-header-name The name of the header which contains http code of the proxied request.
spring.cloud.gateway.streaming-media-types
spring.cloud.gateway.x-forwarded.enabled true If the XForwardedHeadersFilter is enabled.
spring.cloud.gateway.x-forwarded.for-append true If appending X-Forwarded-For as a list is enabled.
spring.cloud.gateway.x-forwarded.for-enabled true If X-Forwarded-For is enabled.
spring.cloud.gateway.x-forwarded.host-append true If appending X-Forwarded-Host as a list is enabled.
spring.cloud.gateway.x-forwarded.host-enabled true If X-Forwarded-Host is enabled.
spring.cloud.gateway.x-forwarded.order 0 The order of the XForwardedHeadersFilter.
spring.cloud.gateway.x-forwarded.port-append true If appending X-Forwarded-Port as a list is enabled.
spring.cloud.gateway.x-forwarded.port-enabled true If X-Forwarded-Port is enabled.
spring.cloud.gateway.x-forwarded.prefix-append true If appending X-Forwarded-Prefix as a list is enabled.
spring.cloud.gateway.x-forwarded.prefix-enabled true If X-Forwarded-Prefix is enabled.
spring.cloud.gateway.x-forwarded.proto-append true If appending X-Forwarded-Proto as a list is enabled.
spring.cloud.gateway.x-forwarded.proto-enabled true If X-Forwarded-Proto is enabled.
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,657评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,662评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,143评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,732评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,837评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,036评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,126评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,868评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,315评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,641评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,773评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,470评论 4 333
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,126评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,859评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,095评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,584评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,676评论 2 351

推荐阅读更多精彩内容