springcloud getway 网关之过滤器filter

1. Filter的使用

filter是Gateway的三大核心之一,路由过滤器可用于修改进入HTTP请求和返回的HTTP响应,路由过滤器只能指定路由进行使用。Gateway内置了多种路由过滤器,他们都由GatewayFilter工程

2. Filter的作用

当我们有很多个服务时,比如下图中的user-service、goods-service、sales-service等服务,客户端请求各个服务的Api时,每个服务都需要做相同的事情,比如鉴权、限流、日志输出等。
在这里插入图片描述
对于这样重复的工作,有没有办法做的更好,答案是肯定的。在微服务的上一层加一个全局的权限控制、限流、日志输出的Api Gatewat服务,然后再将请求转发到具体的业务服务层。这个Api Gateway服务就是起到一个服务边界的作用,外接的请求访问系统,必须先通过网关层。
在这里插入图片描述

3. Filter的生命周期

Spring Cloud Gateway同zuul类似,生命周期只有pre和post。在路由处理之前,需要经过“pre”类型的过滤器处理,处理返回响应之后,可以由“post”类型的过滤器处理。在“pre”类型的过滤器可以做参数校验、权限校验、流量监控、日志输出、协议转换等,在“post”类型的过滤器中可以做响应内容、响应头的修改,日志的输出,流量监控等。

比如上图中的user-service,收到业务服务的响应之后,再经过“post”类型的filter处理,最后返回响应到客户端。
在这里插入图片描述
与zuul不同的是,filter除了分为“pre”和“post”两种方式的filter外,在Spring Cloud Gateway中,filter从作用范围可分为另外两种,一种是针对于单个路由的gateway filter,它在配置文件中的写法同predict类似;另外一种是针对于所有路由的global gateway filer。现在从作用范围划分的维度来讲解这两种filter。

4.Gateway的Filter种类

Spring Cloud Gateway的Filter种类分为GatewayFilter(单一的)和GlobalFilter(全局的)
Spring Cloud Gateway根据作用范围划分为GatewayFilter和GlobalFilter,二者区别如下:

  • GatewayFilter : 需要通过spring.cloud.routes.filters 配置在具体路由下,只作用在当前路由上或通过spring.cloud.default-filters配置在全局,作用在所有路由上。
  • GlobalFilter : 全局过滤器,不需要在配置文件中配置,作用在所有的路由上,最终通过GatewayFilterAdapter包装成GatewayFilterChain可识别的过滤器,它为请求业务以及路由的URI转换为真实业务服务的请求地址的核心过滤器,不需要配置,系统初始化时加载,并作用在每个路由上。

5 GatewayFilter介绍

GatewayFilter工厂同上一篇介绍的Predicate工厂类似,都是在配置文件application.yml中配置,遵循了约定大于配置的思想,只需要在配置文件配置GatewayFilter Factory的名称,而不需要写全部的类名,比如AddRequestHeaderGatewayFilterFactory只需要在配置文件中写AddRequestHeader,而不是全部类名。在配置文件中配置的GatewayFilter Factory最终都会相应的过滤器工厂类处理。

Spring Cloud Gateway 内置的过滤器工厂一览表如下:

在这里插入图片描述
每一个过滤器工厂在官方文档都给出了详细的使用案例,现在的版本有30种,点击查看官网,如果不清楚的还可以在org.springframework.cloud.gateway.filter.factory看每一个过滤器工厂的源码。

6 GatewayFilter Factories 局部网关过滤工厂

路由(Route)过滤器(Filter)允许以某种方式修改传入的 HTTP 请求或传出的 HTTP 响应。路由过滤器的范围是一个特定的路由。Spring Cloud Gateway 包括许多内置的 GatewayFilter 工厂。SpringCloudGateway包括许多内置网关过滤工厂。

6.0 内置的过滤器工厂汇总

这里简单将Spring Cloud Gateway内置的所有过滤器工厂整理成了一张表格。如下:

过滤器工厂作用参数
AddRequestHeader为原始请求添加HeaderHeader的名称及值
AddRequestParameter为原始请求添加请求参数参数名称及值
AddResponseHeader为原始响应添加HeaderHeader的名称及值
DedupeResponseHeader剔除响应头中重复的值需要去重的Header名称及去重策略
Hystrix为路由引入Hystrix的断路器保护HystrixCommand的名称
FallbackHeaders为fallbackUri的请求头中添加具体的异常信息Header的名称
PrefixPath为原始请求路径添加前缀前缀路径
PreserveHostHeader为请求添加一个preserveHostHeader=true的属性,路由过滤器会检查该属性以决定是否要发送原始的Host
RequestRateLimiter用于对请求限流,限流算法为令牌桶keyResolver、rateLimiter、statusCode、denyEmptyKey、emptyKeyStatus
RedirectTo将原始请求重定向到指定的URLhttp状态码及重定向的url
RemoveHopByHopHeadersFilter为原始请求删除IETF组织规定的一系列Header默认就会启用,可以通过配置指定仅删除哪些Header
RemoveRequestHeader为原始请求删除某个HeaderHeader名称
RemoveResponseHeader为原始响应删除某个HeaderHeader名称
RewritePath重写原始的请求路径原始路径正则表达式以及重写后路径的正则表达式
RewriteResponseHeader重写原始响应中的某个HeaderHeader名称,值的正则表达式,重写后的值
SaveSession在转发请求之前,强制执行WebSession::save操作
secureHeaders为原始响应添加一系列起安全作用的响应头无,支持修改这些安全响应头的值
SetPath修改原始的请求路径修改后的路径
SetResponseHeader修改原始响应中某个Header的值Header名称,
SetStatus修改原始响应的状态码HTTP 状态码,可以是数字,也可以是字符串
StripPrefix用于截断原始请求的路径使用数字表示要截断的路径的数量
Retry针对不同的响应进行重试retries、statuses、methods、series
RequestSize设置允许接收最大请求包的大小。如果请求包大小超过设置的值,则返回 413 Payload Too Large 请求包大小,单位为字节,默认值为5M
ModifyRequestBody在转发请求之前修改原始请求体内容修改后的请求体内容
ModifyResponseBody修改原始响应体的内容修改后的响应体内容
Default为所有路由添加过滤器过滤器工厂名称及值
**Tips:**每个过滤器工厂都对应一个实现类,并且这些类的名称必须以GatewayFilterFactory结尾,这是Spring Cloud Gateway的一个约定,例如AddRequestHeader对应的实现类为AddRequestHeaderGatewayFilterFactory。

参考 原文链接:

6.1. 为原始请求添加header 网关过滤器工厂 (The AddRequestHeader)

这个AddRequestHeader GatewayFilter 工厂,采用一个名称和值的参数,下面例子配置了一个AddRequest GatewayFilter。

spring:cloud:gateway:routes:- id: add_request_header_routeuri: https://example.orgfilters:- AddRequestHeader=X-Request-red, blue

这个清单将 X-Request-red:blue的 header添加到所有匹配请求,的下游请求的header信息中。
AddRequestHeader是知道用于匹配路径或者主机的URL变量。URI变量可以在值中使用并在运行时扩展。
以下示例配置使用变量的AddRequestHeader GatewayFilter。

spring:cloud:gateway:routes:- id: add_request_header_routeuri: https://example.orgpredicates:- Path=/red/{segment}filters:- AddRequestHeader=X-Request-Red, Blue-{segment}

6.2.AddRequestHeadersIfNotPresent

AddRequestHeadersIfNotPresent GatewayFilter 工厂接受一个由冒号分隔的 name 和 value 键值对的集合。下面的例子配置了一个 AddRequestHeadersIfNotPresent GatewayFilter。

spring:cloud:gateway:routes:- id: add_request_headers_routeuri: https://example.orgfilters:- AddRequestHeadersIfNotPresent=X-Request-Color-1:blue,X-Request-Color-2:green

这个列表为所有匹配的请求在下游请求的header信息中添加了两个header信息 X-Request-Color-1:blue 和 X-Request-Color-2:green。这类似于 AddRequestHeader 的工作方式,但与 AddRequestHeader 不同的是,它只在header 信息不存在的情况下才会这样做。否则,客户端请求中的原始值将被发送。

此外,要设置一个多值header,可以多次使用header的名称,如 AddRequestHeadersIfNotPresent=X-Request-Color-1:blue,X-Request-Color-1:green。

AddRequestHeadersIfNotPresent 也支持URI变量,用于匹配路径或主机。URI变量可以在值中使用,并在运行时被扩展。下面的例子配置了一个使用变量的 AddRequestHeadersIfNotPresent GatewayFilter。

spring:cloud:gateway:routes:- id: add_request_header_routeuri: https://example.orgpredicates:- Path=/red/{segment}filters:- AddRequestHeadersIfNotPresent=X-Request-Red:Blue-{segment}

6.3. 为原始请求添加请求参数( AddRequestParameter)

AddRequestParameter GatewayFilter Factory需要一个 name 和 value 参数。下面的例子配置了一个 AddRequestParameter GatewayFilter。

spring:cloud:gateway:routes:- id: add_request_parameter_routeuri: https://example.orgfilters:- AddRequestParameter=red, blue

这将为所有匹配的请求在下游请求的查询字符串中添加 red=blue。

AddRequestParameter 知道用于匹配路径或主机的URI变量。URI变量可以在值中使用,并在运行时被扩展。下面的例子配置了一个 AddRequestParameter GatewayFilter,它使用了一个变量。

spring:cloud:gateway:routes:- id: add_request_parameter_routeuri: https://example.orgpredicates:- Host: {segment}.myhost.orgfilters:- AddRequestParameter=foo, bar-{segment}

6.4. 为原始响应添加header(AddResponseHeader)

AddResponseHeader GatewayFilter 工厂需要一个 name 和 value 参数。下面的例子配置了一个 AddResponseHeader GatewayFilter。

spring:cloud:gateway:routes:- id: add_response_header_routeuri: https://example.orgfilters:- AddResponseHeader=X-Response-Red, Blue

这将把 X-Response-Red:Blue header添加到所有匹配请求的下游响应的header中。

AddResponseHeader 知道用于匹配路径或主机的URI变量。URI变量可以在值中使用,并在运行时被扩展。下面的例子配置了一个 AddResponseHeader GatewayFilter,它使用了一个变量。

spring:cloud:gateway:routes:- id: add_response_header_routeuri: https://example.orgpredicates:- Host: {segment}.myhost.orgfilters:- AddResponseHeader=foo, bar-{segment}

6.5. 网关熔断器 (CircuitBreaker)

Spring Cloud CircuitBreaker GatewayFilter 工厂使用Spring Cloud CircuitBreaker API 将 Gateway 路由包裹在一个熔断器中。Spring Cloud CircuitBreaker 支持多个可与 Spring Cloud Gateway 一起使用的库。Spring Cloud 支持 Resilience4J 开箱即用。

要启用 Spring Cloud CircuitBreaker 过滤器,你需要添加 spring-cloud-starter-circuitbreaker-reactor-resilience4j 依赖。下面的例子配置了一个 Spring Cloud CircuitBreaker GatewayFilter。

spring:cloud:gateway:routes:- id: circuitbreaker_routeuri: https://example.orgfilters:- CircuitBreaker=myCircuitBreaker

要配置熔断器,请参阅你所使用的底层熔断器实现的配置。

Resilience4J 文档
Spring Cloud CircuitBreaker 过滤器还可以接受一个可选的 fallbackUri 参数。目前,只支持 forward: 模式的URI。如果fallback被调用,请求将被转发到URI所匹配的控制器。下面的例子配置了这样一个fallback。

spring:cloud:gateway:routes:- id: circuitbreaker_routeuri: lb://backing-service:8088predicates:- Path=/consumingServiceEndpointfilters:- name: CircuitBreakerargs:name: myCircuitBreakerfallbackUri: forward:/inCaseOfFailureUseThis- RewritePath=/consumingServiceEndpoint, /backingServiceEndpoint

也可以通过Java来实现相同的配置,如下。

@Bean
public RouteLocator routes(RouteLocatorBuilder builder) {return builder.routes().route("circuitbreaker_route", r -> r.path("/consumingServiceEndpoint").filters(f -> f.circuitBreaker(c -> c.name("myCircuitBreaker").fallbackUri("forward:/inCaseOfFailureUseThis")).rewritePath("/consumingServiceEndpoint", "/backingServiceEndpoint")).uri("lb://backing-service:8088").build();
}

当熔断器 fallback 被调用时,这个例子转发到 /inCaseofFailureUseThis URI。请注意,这个例子还演示了(可选)Spring Cloud LoadBalancer 的负载均衡(由目标URI上的 lb 前缀定义)。

CircuitBreaker 还支持 fallbackUri 中的URI变量。这允许更复杂的路由选项,比如使用 PathPattern 表达式 转发原始主机或URL路径的部分。

在下面的例子中,调用 consumingServiceEndpoint/users/1 将被重定向到 inCaseOfFailureUseThis/users/1。

spring:cloud:gateway:routes:- id: circuitbreaker_routeuri: lb://backing-service:8088predicates:- Path=/consumingServiceEndpoint/{*segments}filters:- name: CircuitBreakerargs:name: myCircuitBreakerfallbackUri: forward:/inCaseOfFailureUseThis/{segments}

一般情况下是使用 fallbackUri 来定义网关应用程序中的内部controller或handler。然而,你也可以将请求重新路由到外部应用程序的controller或handler,如下所示。

spring:cloud:gateway:routes:- id: ingredientsuri: lb://ingredientspredicates:- Path=//ingredients/**filters:- name: CircuitBreakerargs:name: fetchIngredientsfallbackUri: forward:/fallback- id: ingredients-fallbackuri: http://localhost:9994predicates:- Path=/fallback

在这个例子中,网关应用程序中没有 fallback 端点或处理程序。然而,在另一个应用程序中有一个,在 localhost:9994 下注册。

在请求被转发到 fallback 的情况下,Spring Cloud CircuitBreaker Gateway 过滤器也提供了造成这种情况的 Throwable。它作为 ServerWebExchangeUtils.CIRCUITBREAKER_EXECUTION_EXCEPTION_ATTR 属性被添加到 ServerWebExchange 中,在网关应用中处理 fallback 时可以使用。

对于外部 controller/handler 的情况,可以添加带有异常细节的header。你可以在FallbackHeaders GatewayFilter Factory 部分找到更多关于这样做的信息。

6.5.1. 熔断指定的状态码

在某些情况下,你可能想根据它所包裹的路由返回的状态码来熔断。断路器配置对象需要一个状态码列表,如果返回这些代码将导致断路器熔断。当设置你想让断路器熔断的状态代码时,你可以使用一个带有状态码值的 int 或 HttpStatus 枚举的字符串表示。

Example 27. application.yml

spring:cloud:gateway:routes:- id: circuitbreaker_routeuri: lb://backing-service:8088predicates:- Path=/consumingServiceEndpointfilters:- name: CircuitBreakerargs:name: myCircuitBreakerfallbackUri: forward:/inCaseOfFailureUseThisstatusCodes:- 500- "NOT_FOUND"

Example 28. Application.java

@Bean
public RouteLocator routes(RouteLocatorBuilder builder) {return builder.routes().route("circuitbreaker_route", r -> r.path("/consumingServiceEndpoint").filters(f -> f.circuitBreaker(c -> c.name("myCircuitBreaker").fallbackUri("forward:/inCaseOfFailureUseThis").addStatusCode("INTERNAL_SERVER_ERROR")).rewritePath("/consumingServiceEndpoint", "/backingServiceEndpoint")).uri("lb://backing-service:8088").build();
}

6.6.CacheRequestBody

有些情况下,有必要读取请求体。由于请求体只能被读取一次,我们需要缓存请求体。你可以使用 CacheRequestBody 过滤器来缓存请求体,然后再把它发送到下游,从 exchange 属性中获取请求体。
下面显示了如何缓存请求体 GatewayFilter:

@Bean
public RouteLocator routes(RouteLocatorBuilder builder) {return builder.routes().route("cache_request_body_route", r -> r.path("/downstream/**").filters(f -> f.prefixPath("/httpbin").cacheRequestBody(String.class).uri(uri)).build();
}
spring:cloud:gateway:routes:- id: cache_request_body_routeuri: lb://downstreampredicates:- Path=/downstream/**filters:- name: CacheRequestBodyargs:bodyClass: java.lang.String

CacheRequestBody 提取请求体并将其转换为一个 body 类(比如前面例子中定义的 java.lang.String)。然后,CacheRequestBody 把它放在 ServerWebExchange.getAttributes() 提供的属性中,其KEY值在 ServerWebExchangeUtils.CACHED_REQUEST_BODY_ATTR 中定义。

这个过滤器只对HTTP(包括HTTPS)请求起作用。

6.7. 剔除响应头中重复的值。(DedupeResponseHeader)

DedupeResponseHeader GatewayFilter 工厂接受一个 name 参数和一个可选的 strategy 参数。name 可以包含一个以空格分隔的header名称列表。下面的例子配置了一个 DedupeResponseHeader GatewayFilter。

spring:cloud:gateway:routes:- id: dedupe_response_header_routeuri: https://example.orgfilters:- DedupeResponseHeader=Access-Control-Allow-Credentials Access-Control-Allow-Origin

在网关CORS逻辑和下游逻辑都添加了 Access-Control-Allow-Credentials 和 Access-Control-Allow-Origin 响应头的情况下,这将删除重复的值。

DedupeResponseHeader 过滤器还接受一个可选的 strategy 参数。接受的值是 RETAIN_FIRST(默认)、RETAIN_LAST 和 RETAIN_UNIQUE。

6.8 腐乳降级请求header 中添加值(FallbackHeaders)

通过 FallbackHeaders 工厂,你可以在转发到外部应用程序中的 fallbackUri 的请求的header中添加Spring Cloud CircuitBreaker的执行异常细节,如以下场景。

spring:cloud:gateway:routes:- id: ingredientsuri: lb://ingredientspredicates:- Path=//ingredients/**filters:- name: CircuitBreakerargs:name: fetchIngredientsfallbackUri: forward:/fallback- id: ingredients-fallbackuri: http://localhost:9994predicates:- Path=/fallbackfilters:- name: FallbackHeadersargs:executionExceptionTypeHeaderName: Test-Header

在这个例子中,在运行断路器时发生执行异常后,请求被转发到运行在 localhost:9994 的应用程序中的 fallback 端点或 handler。带有异常类型、消息和(如果有)根本原因的异常类型和消息的 header 被 FallbackHeaders 过滤器添加到该请求中。

你可以通过设置以下参数的值(显示为默认值)来覆盖配置中header的名称。

  • executionExceptionTypeHeaderName (“Execution-Exception-Type”)
  • executionExceptionMessageHeaderName (“Execution-Exception-Message”)
  • rootCauseExceptionTypeHeaderName (“Root-Cause-Exception-Type”)
  • rootCauseExceptionMessageHeaderName (“Root-Cause-Exception-Message”)
    关于断路器和网关的更多信息,请参见 Spring Cloud CircuitBreaker Factory 部分 。

6.9.JsonToGrpc

JSONToGRPCFilter GatewayFilter Factory 将一个JSON payload 转换为gRPC请求。

该过滤器需要以下参数。

  • protoDescriptor: Proto描述文件。
    这个文件可以用 protoc 生成,并指定 --descriptor_set_out 标志。
protoc --proto_path=src/main/resources/proto/ \
--descriptor_set_out=src/main/resources/proto/hello.pb  \
src/main/resources/proto/hello.proto
  • protoFile: Proto定义文件。
  • service: 处理请求的服务的全名称。
  • method: 处理该请求的服务中的方法名称。

支持 streaming。

@Bean
public RouteLocator routes(RouteLocatorBuilder builder) {return builder.routes().route("json-grpc", r -> r.path("/json/hello").filters(f -> {String protoDescriptor = "file:src/main/proto/hello.pb";String protoFile = "file:src/main/proto/hello.proto";String service = "HelloService";String method = "hello";return f.jsonToGRPC(protoDescriptor, protoFile, service, method);}).uri(uri))
spring:cloud:gateway:routes:- id: json-grpcuri: https://localhost:6565/testhellopredicates:- Path=/json/**filters:- name: JsonToGrpcargs:protoDescriptor: file:proto/hello.pbprotoFile: file:proto/hello.protoservice: com.example.grpcserver.hello.HelloServicemethod: hello

当通过网关向 /json/hello 发出请求时,该请求通过使用 hello.proto 中提供的定义进行转换,发送到 com.example.grpcserver.hello.HelloService/hello,返回的响应被转换为JSON。

默认情况下,它通过使用默认的 TrustManagerFactory 创建一个 NettyChannel。然而,你可以通过创建一个 GrpcSslConfigurer 类型的bean来定制这个 TrustManager。

@Configuration
public class GRPCLocalConfiguration {@Beanpublic GRPCSSLContext sslContext() {TrustManager trustManager = trustAllCerts();return new GRPCSSLContext(trustManager);}
}

6.10.LocalResponseCache

这个过滤器允许缓存响应体和header,遵循以下规则。

  • 它只能缓存无请求体的GET请求。
  • 它只对以下状态代码之一的响应进行缓存。HTTP 200(OK),HTTP 206(部分内容),或HTTP 301(永久移动)。
  • 如果 Cache-Control header不允许,响应数据就不会被缓存(请求中存在 no-store 或响应中存在 no-store 或 private)。
  • 如果响应已经被缓存,并且在 Cache-Control 头中用 no-cache 值执行一个新的请求,它将返回一个304(未修改)的无body的响应。
    这个过滤器(配置每个路由的本地响应缓存)只有在启用了本地响应全局缓存的情况下才可用。 它接受第一个参数,用于覆盖缓存条目过期的时间(用 s 表示秒,用 m 表示分钟,用 h 表示小时),第二个参数用于设置该路由驱逐条目的最大缓存大小(KB、MB或GB)。

下面的列表显示了如何添加本地响应缓存 GatewayFilter。

@Bean
public RouteLocator routes(RouteLocatorBuilder builder) {return builder.routes().route("rewrite_response_upper", r -> r.host("*.rewriteresponseupper.org").filters(f -> f.prefixPath("/httpbin").localResponseCache(Duration.ofMinutes(30), "500MB")).uri(uri)).build();
}

或者,这样:

application.yml

spring:cloud:gateway:routes:- id: resourceuri: http://localhost:9000predicates:- Path=/resourcefilters:- LocalResponseCache=30m,500MB

这个过滤器还自动计算 HTTP Cache-Control header中的 max-age 值。只有在原始响应中存在 max-age
的情况下,才会用 timeToLive 配置参数中设置的秒数重写该值。在连续的调用中,这个值会以响应过期前的剩余秒数重新计算。

6.11 添加请求head 参数值并从已有header中取值( MapRequestHeader)

MapRequestHeader GatewayFilter 工厂接受 fromHeader 和 toHeader 参数。它创建一个新的命名header(toHeader),并从传入的http请求的现有命名头(fromHeader)中提取值。如果输入的header不存在,过滤器没有任何影响。如果新的命名header信息已经存在,它的值就会被增加新的值。下面的例子配置了一个 MapRequestHeader。

spring:cloud:gateway:routes:- id: map_request_header_routeuri: https://example.orgfilters:- MapRequestHeader=Blue, X-Request-Red

这将在下游请求中添加 X-Request-Red: 头,并从传入的HTTP请求的 Blue 头中更新数值。

6.12. 修改请求body体(ModifyRequestBody)

你可以使用 ModifyRequestBody 过滤器,在网关向下游发送请求体之前对其进行修改。

这个过滤器只能通过使用Java DSL来配置。

下面显示了如何使用 GatewayFilter 修改请求体:

@Bean
public RouteLocator routes(RouteLocatorBuilder builder) {return builder.routes().route("rewrite_request_obj", r -> r.host("*.rewriterequestobj.org").filters(f -> f.prefixPath("/httpbin").modifyRequestBody(String.class, Hello.class, MediaType.APPLICATION_JSON_VALUE,(exchange, s) -> return Mono.just(new Hello(s.toUpperCase())))).uri(uri)).build();
}static class Hello {String message;public Hello() { }public Hello(String message) {this.message = message;}public String getMessage() {return message;}public void setMessage(String message) {this.message = message;}
}

如果请求没有正文,RewriteFilter 将被传递为 null。应该返回 Mono.empty() 来指定请求中缺少的主体。

6.13. 修改返回响应体(ModifyResponseBody)

你可以使用 ModifyResponseBody 过滤器来修改响应体,然后再把它送回给客户端。

这个过滤器只能通过使用Java DSL来配置。

下面显示了如何使用 GatewayFilter 修改响应体 。

@Bean
public RouteLocator routes(RouteLocatorBuilder builder) {return builder.routes().route("rewrite_response_upper", r -> r.host("*.rewriteresponseupper.org").filters(f -> f.prefixPath("/httpbin").modifyResponseBody(String.class, String.class,(exchange, s) -> Mono.just(s.toUpperCase()))).uri(uri)).build();
}

如果响应没有正文,RewriteFilter 将被传递为 null。应该返回 Mono.empty() 来指定响应中缺少的主体。

6.14. 匹配请求路径(PrefixPath)

PrefixPath GatewayFilter 工厂需要一个 prefix 参数。下面的例子配置了一个 PrefixPath GatewayFilter。

spring:cloud:gateway:routes:- id: prefixpath_routeuri: https://example.orgfilters:- PrefixPath=/mypath

这就把 /mypath 作为所有匹配请求的路径的前缀。因此,一个到 /hello 的请求会被发送到 /mypath/hello。

6.15.保持客户端host不变(PreserveHostHeader)

它表示在Spring Cloud Gateway转发请求的时候,保持客户端的Host信息不变,然后将它传递到下游服务器中;

PreserveHostHeader GatewayFilter 工厂没有参数。这个过滤器设置一个请求属性(request attribute),路由过滤器(routing filter)会检查该属性,以确定是否应该发送原始的主机头,而不是由HTTP客户端确定的主机头。下面的例子配置了一个 PreserveHostHeader GatewayFilter。

spring:cloud:gateway:routes:- id: preserve_host_routeuri: https://example.orgfilters:- PreserveHostHeader

6.16. 重定向(RedirectTo)

RedirectTo GatewayFilter 工厂需要两个参数,status 和 url。status 参数应该是一个300系列的重定向 HTTP 状态码,如301。url 参数应该是一个有效的URL。这就是 Location header 的值。对于相对重定向,你应该使用 uri: no://op 作为路由定义的uri。下面的列表配置了一个 RedirectTo GatewayFilter。

spring:cloud:gateway:routes:- id: prefixpath_routeuri: https://example.orgfilters:- RedirectTo=302, https://acme.org

这将发送一个带有 Location:https://acme.org header的302状态码的响应,以执行重定向。

6.17. 移除请求响应中属性字段(RemoveJsonAttributesResponseBody)

RemoveJsonAttributesResponseBody GatewayFilter 工厂接收了一个要搜索的属性名称(attribute name)集合,列表中的最后一个参数可以是一个布尔值,用来删除根级的属性(如果该参数未定义,那就是默认值 false)或递归(true)。它提供了一个方便的方法,通过删除属性来应用于JSON body内容的转换。

下面的例子配置了一个 RemoveJsonAttributesResponseBody GatewayFilter。

spring:cloud:gateway:routes:- id: removejsonattributes_routeuri: https://example.orgfilters:- RemoveJsonAttributesResponseBody=id,color

这从根层的JSON body中删除了属性 “id” 和 “color”。
下面的例子配置了一个 RemoveJsonAttributesResponseBody GatewayFilter,它使用了可选的最后参数。

spring:cloud:gateway:routes:- id: removejsonattributes_recursively_routeuri: https://example.orgpredicates:- Path=/red/{segment}filters:- RemoveJsonAttributesResponseBody=id,color,true

这将从任何级别的JSON body中移除属性 “id” 和 “color”。

下面的例子配置了一个 RemoveJsonAttributesResponseBody GatewayFilter,它使用了可选的最后参数。

spring:cloud:gateway:routes:- id: removejsonattributes_recursively_routeuri: https://example.orgpredicates:- Path=/red/{segment}filters:- RemoveJsonAttributesResponseBody=id,color,true

这将从任何级别的JSON body中移除属性 “id” 和 “color”。

6.18.移除header 参数过滤器 (RemoveRequestHeader)

RemoveRequestHeader GatewayFilter 工厂需要一个 name 参数。它是要被删除的header的名称。下面配置了一个 RemoveRequestHeader GatewayFilter。

spring:cloud:gateway:routes:- id: removerequestheader_routeuri: https://example.orgfilters:- RemoveRequestHeader=X-Request-Foo

这在向下游发送之前删除了 X-Request-Foo 标头。

6.19. 移除Parameter参数过滤器 (RemoveRequestParameter)

RemoveRequestParameter GatewayFilter 工厂需要一个 name 参数。它是要删除的查询参数的名称。下面的例子配置了一个 RemoveRequestParameter GatewayFilter。

spring:cloud:gateway:routes:- id: removerequestparameter_routeuri: https://example.orgfilters:- RemoveRequestParameter=red

这将在向下游发送之前删除 red 参数。

6.20. 删除响应头 (RemoveResponseHeader)

RemoveResponseHeader GatewayFilter 工厂需要一个 name 参数。它是要被移除的 header 的名称。下面的列表配置了一个 RemoveResponseHeader GatewayFilter。

spring:cloud:gateway:routes:- id: removeresponseheader_routeuri: https://example.orgfilters:- RemoveResponseHeader=X-Response-Foo

这将在响应返回到网关客户端之前从响应中删除 X-Response-Foo 头。

要删除任何类型的敏感标头,你应该为任何你可能想这样做的路由配置这个过滤器。此外,你可以通过使用 spring.cloud.gateway.default-filters 配置一次此过滤器,并将其应用于所有路由。

6.21.RequestHeaderSize

RequestHeaderSize GatewayFilter 工厂接受 maxSize 和 errorHeaderName 参数。maxSize 参数是请求头(包括key和value)所允许的最大数据大小。errorHeaderName 参数设置包含错误信息的响应头的名称,默认为 “errorMessage”。下面的列表配置了一个 RequestHeaderSize GatewayFilter。

spring:cloud:gateway:routes:- id: requestheadersize_routeuri: https://example.orgfilters:- RequestHeaderSize=1000B

如果任何请求头的大小超过1000字节,这将发送一个 431状态码的响应。

6.22. 请求限流过滤器 (RequestRateLimiter)

RequestRateLimiter GatewayFilter 工厂使用 RateLimiter 实现来确定是否允许当前请求继续进行。如果不允许,就会返回 HTTP 429 - Too Many Requests(默认)的状态。

这个过滤器需要一个可选的 keyResolver 参数和特定于速率限制器的参数(在本节后面描述)。

keyResolver 是一个实现了 KeyResolver 接口的Bean。在配置中,使用SpEL来引用Bean的名字。#{@myKeyResolver} 是一个SpEL表达式,它引用了一个名为 myKeyResolver 的bean。下面的列表显示了 KeyResolver 的接口。

Example 42. KeyResolver.java

public interface KeyResolver {Mono<String> resolve(ServerWebExchange exchange);
}

KeyResolver 接口让可插拔的策略导出限制请求的key。在未来的里程碑版本中,会有一些 KeyResolver 的实现。

KeyResolver 的默认实现是 PrincipalNameKeyResolver,它从 ServerWebExchange 中检索 Principal 并调用 Principal.getName()。

默认情况下,如果 KeyResolver 没有找到一个 key,请求会被拒绝。你可以通过设置 spring.cloud.gateway.filter.request-rate-limiter.deny-empty-key(true 或 false)和 spring.cloud.gateway.filter.request-rate-limiter.empty-key-status-code 属性来调整这种行为。

RequestRateLimiter 不能用 “快捷方式” 来配置。下面的例子是无效的。Example 43. application.properties# 无效的快捷方式配置
spring.cloud.gateway.routes[0].filters[0]=RequestRateLimiter=2, 2, #{@userkeyresolver}

6.22.1. 基于redis 的请求限流过滤器 (RedisRateLimiter)

Redis的实现是基于 Stripe 的工作。它需要使用 spring-boot-starter-data-redis-reactive Spring Boot Starter。

使用的算法是 令牌桶算法。

redis-rate-limiter.replenishRate 属性定义了每秒钟允许多少个请求(不算放弃的请求)。这是令牌桶被填充的速度。

redis-rate-limiter.burstCapacity 属性是一个用户在一秒钟内允许的最大请求数(不算放弃的请求)。这是令牌桶可以容纳的令牌数量。将此值设置为零会阻止所有请求。

redis-rate-limiter.requestedTokens 属性是指一个请求要花费多少令牌。这是为每个请求从桶中提取的令牌数量,默认为 1。

一个稳定的速率是通过在 replenishRate 和 burstCapacity 中设置相同的值来实现的。可以通过设置高于补给率的 burstCapacity 来允许临时的突发。在这种情况下,速率限制器需要在突发之间允许一些时间(根据 replenishRate),因为连续两次突发会导致请求被放弃(HTTP 429 - Too Many Requests)。下面的列表配置了一个 redis-rate-limiter。

低于 1个请求/s 的速率限制是通过将 replenishRate 设置为想要的请求数, requestTokens 设置为秒数,burstCapacity 设置为 replenishRate 和 requestTokens 的乘积来完成的。例如,设置 replenishRate=1,requestedTokens=60,burstCapacity=60,结果是1个请求/分钟的限制。

Example 44. application.yml

spring:cloud:gateway:routes:- id: requestratelimiter_routeuri: https://example.orgfilters:- name: RequestRateLimiterargs:redis-rate-limiter.replenishRate: 10redis-rate-limiter.burstCapacity: 20redis-rate-limiter.requestedTokens: 1

下面的例子在Java中配置了一个 KeyResolver。

Example 45. Config.java

@Bean
KeyResolver userKeyResolver() {return exchange -> Mono.just(exchange.getRequest().getQueryParams().getFirst("user"));
}

这定义了每个用户的请求率限制为10。爆发20次是允许的,但是,在下一秒,只有10个请求可用。KeyResolver 是一个简单的,获得 user 请求参数。

不建议在生产中使用这个方法

你也可以把速率限制器定义为一个实现 RateLimiter 接口的bean。在配置中,你可以用SpEL来引用bean的名字。#{@myRateLimiter} 是一个SpEL表达式,它引用了一个名为 myRateLimiter 的 bean。下面的清单定义了一个速率限制器,它使用了前面清单中定义的 KeyResolver。
Example 46. application.yml

spring:cloud:gateway:routes:- id: requestratelimiter_routeuri: https://example.orgfilters:- name: RequestRateLimiterargs:rate-limiter: "#{@myRateLimiter}"key-resolver: "#{@userKeyResolver}"

6.23. 修改Location响应标头的值 (RewriteLocationResponseHeader)

RewriteLocationResponseHeader GatewayFilter 工厂修改 Location 响应头的值,通常是为了去掉后台的特定细节。它需要 stripVersionMode、locationHeaderName、hostValue 和 protocolsRegex 参数。下面的清单配置了一个 RewriteLocationResponseHeader GatewayFilter。

pring:cloud:gateway:routes:- id: rewritelocationresponseheader_routeuri: http://example.orgfilters:- RewriteLocationResponseHeader=AS_IN_REQUEST, Location, ,

例如,对于一个 POST http://api.example.com/some/object/name 的请求, Location 响应头值 http://object-service.prod.example.net/v2/some/object/id 被改写为 http://api.example.com/some/object/id。

stripVersionMode 参数有以下可能的值。NEVER_STRIP、AS_IN_REQUEST(默认)和 ALWAYS_STRIP。

  • NEVER_STRIP: 即使最初的请求路径不包含version,version也不会被剥离。
  • AS_IN_REQUEST: 只有当原始请求路径不包含version时,才会剥离version。
  • ALWAYS_STRIP: version 总是被剥离,即使原始请求路径包含version 。

hostValue 参数,如果提供的话,将用于替换响应的 Location 头的 host:port 部分。如果没有提供,则使用 Host 请求头的值。

protocolsRegex 参数必须是一个有效的 regex String,协议名称将与之匹配。如果没有匹配,过滤器不做任何事情。默认是 http|https|ftp|ftps。

Location响应标头 详情

Location字段用于重定向浏览器到另一个URL,通常在HTTP响应的3xx状态码中使用。浏览器会自动根据Location字段的值重定向到指定的URL。这个字段可以用于以下情况:

  1. 当资源被移动到一个新的位置时,比如资源已经被重命名或者被分解到不同的URL中时,可以使用Location字段将浏览器重定向到新的URL上。

  2. 当需要跟踪用户重定向时,Location字段可以携带用户信息或会话信息,帮助重定向后的资源验证用户的身份。
    使用Location字段时,需要指定重定向的URL,并在响应中设置Location字段。
    在这里插入图片描述

6.24. 重写原始的请求路径 (RewritePath)

RewritePath GatewayFilter 工厂接收一个路径 regexp 参数和一个 replacement 参数。这是用Java正则表达式来重写请求路径的一种灵活方式。下面的列表配置了一个 RewritePath GatewayFilter。

spring:cloud:gateway:routes:- id: rewritepath_routeuri: https://example.orgpredicates:- Path=/red/**filters:- RewritePath=/red/?(?<segment>.*), /$\{segment}

对于请求路径为 /red/blue 的情况,在进行下游请求之前将路径设置为 /blue。注意,由于YAML的规范,$ 应该被替换成 $\。

6.25. 重写原始响应中的某个Header (RewriteResponseHeader)

RewriteResponseHeader GatewayFilter 工厂接受 name、regexp 和 replacement 参数。它使用Java正则表达式,以一种灵活的方式重写响应头的值。下面的例子配置了一个 RewriteResponseHeader GatewayFilter。

spring:cloud:gateway:routes:- id: rewriteresponseheader_routeuri: https://example.orgfilters:- RewriteResponseHeader=X-Response-Red, , password=[^&]+, password=***

对于一个 /42?user=ford&password=omg!what&flag=true 的header值,在发出下游请求后,它被设置为 /42?user=ford&password=***&flag=true。因为YAML规范,你必须用 $\ 来表示 $。

6.26. 在转发请求之前,强制执行WebSession::save操作 (SaveSession)

SaveSession GatewayFilter 工厂在转发下游调用之前强制进行 WebSession::save 操作。这在使用类似 Spring Session 的懒数据存储时特别有用,因为你需要确保在进行转发调用之前已经保存了Session状态。下面的例子配置了一个 SaveSession GatewayFilter。

spring:cloud:gateway:routes:- id: save_sessionuri: https://example.orgpredicates:- Path=/foo/**filters:- SaveSession

如果你将 Spring Security 与 Spring Session 集成,并希望确保安全细节(security detail)已被转发到远程进程,这一点至关重要。

6.27.为原始响应添加一系列起安全作用的响应头 (SecureHeaders)

根据 这篇博客的建议,SecureHeaders GatewayFilter 工厂在响应中添加了一些头信息。

以下header信息(显示为其默认值)被添加。

  • X-Xss-Protection:1 (mode=block)

  • Strict-Transport-Security (max-age=631138519)

  • X-Frame-Options (DENY)

  • X-Content-Type-Options (nosniff)

  • Referrer-Policy (no-referrer)

  • 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)’

  • X-Download-Options (noopen)

  • X-Permitted-Cross-Domain-Policies (none)
    要改变默认值,请在 spring.cloud.gateway.filter.secure-headers 命名空间中设置相应的属性。以下是可用的属性。

  • xss-protection-header

  • strict-transport-security

  • frame-options

  • content-type-options

  • referrer-policy

  • content-security-policy

  • download-options

  • permitted-cross-domain-policies
    要禁用默认值,请用逗号分隔的值设置 spring.cloud.gateway.filter.secure-headers.disable 属性,如下。

spring.cloud.gateway.filter.secure-headers.disable=x-frame-options,strict-transport-security

需要使用 secure header 的小写全名来禁用它。

6.28. 替换请求路径(SetPath)

SetPath GatewayFilter 工厂接受一个路径模板参数。它提供了一种简单的方法,通过允许模板化的路径段来操作请求路径。这使用了 Spring Framework 的URI模板。允许多个匹配段。下面的例子配置了一个 SetPath GatewayFilter。

spring:cloud:gateway:routes:- id: setpath_routeuri: https://example.orgpredicates:- Path=/red/{segment}filters:- SetPath=/{segment}

对于请求路径为 /red/blue 的情况,在进行下行请求之前,将路径设置为 /blue。

6.29. 替换请求header头值(SetRequestHeader)

SetRequestHeader GatewayFilter 工厂接受 name 和 value 参数。下面的列表配置了一个 SetRequestHeader GatewayFilter。

spring:cloud:gateway:routes:- id: setrequestheader_routeuri: https://example.orgfilters:- SetRequestHeader=X-Request-Red, Blue

这 GatewayFilter 会替换(而不是添加)所有给定名称的 header 信息。 因此,如果下游服务器以 X-Request-Red:1234 响应,它将被替换为 X-Request-Red:Blue,这就是下游服务会收到的。

SetRequestHeader 知道用于匹配路径或主机的URI变量。URI变量可以在值中使用,并在运行时被扩展。下面的例子配置了一个 SetRequestHeader GatewayFilter,它使用了一个变量。

spring:cloud:gateway:routes:- id: setrequestheader_routeuri: https://example.orgpredicates:- Host: {segment}.myhost.orgfilters:- SetRequestHeader=foo, bar-{segment}

6.30. 替换响应header头(SetResponseHeader)

SetResponseHeader GatewayFilter 工厂接受 name 和 value 参数。下面的列表配置了一个 SetResponseHeader GatewayFilter。

spring:cloud:gateway:routes:- id: setresponseheader_routeuri: https://example.orgfilters:- SetResponseHeader=X-Response-Red, Blue

这个 GatewayFilter 会替换(而不是添加)所有带有给定名称的头信息。 因此,如果下游服务器以 X-Response-Red:1234 响应,它将被替换为 X-Response-Red:Blue,这就是网关客户端将收到的内容。

SetResponseHeader 知道用于匹配路径或主机的URI变量。URI变量可以在值中使用,并将在运行时被扩展。下面的例子配置了一个 SetResponseHeader GatewayFilter,它使用了一个变量。

spring:cloud:gateway:routes:- id: setresponseheader_routeuri: https://example.orgpredicates:- Host: {segment}.myhost.orgfilters:- SetResponseHeader=foo, bar-{segment}

6.31. 设置响应状态值(SetStatus)

SetStatus GatewayFilter 工厂只接受一个参数,即 status。它必须是一个有效的Spring HttpStatus。它可以是 404 的int值或枚举的字符串表示: NOT_FOUND。下面的列表配置了一个 SetStatus GatewayFilter。

spring:cloud:gateway:routes:- id: setstatusstring_routeuri: https://example.orgfilters:- SetStatus=UNAUTHORIZED- id: setstatusint_routeuri: https://example.orgfilters:- SetStatus=401

在这两种情况下,响应的HTTP状态被设置为401。

你可以配置 SetStatus GatewayFilter,使其在响应中的头中返回代理请求的原始HTTP状态代码。如果配置了以下属性,该头会被添加到响应中。

spring:cloud:gateway:set-status:original-status-header-name: original-http-status

6.32. 用于截断原始请求的路径 (StripPrefix)

StripPrefix GatewayFilter 工厂需要一个参数,即 parts。parts 参数表示在向下游发送请求之前要从路径中剥离的部分的数量。下面的列表配置了一个 StripPrefix GatewayFilter。

spring:cloud:gateway:routes:- id: nameRooturi: https://nameservicepredicates:- Path=/name/**filters:- StripPrefix=2

当通过网关向 /name/blue/red 发出请求时,向 nameservice 发出的请求看起来像 nameservice/red。

6.33. 请求重试(Retry)

Retry GatewayFilter 工厂支持以下参数。

  • retries: 应该尝试的重试次数。
  • statuses: 应该重试的HTTP状态代码,用 org.springframework.http.HttpStatus 表示。
  • methods: 应该重试的HTTP方法,用 org.springframework.http.HttpMethod 来表示。
  • series: 要重试的状态代码系列,用 org.springframework.http.HttpStatus.Series 表示。
  • exceptions: 抛出的异常的列表,应该重试。
  • backoff: 为重试配置的指数式backoff。重试是在 backoff 间隔 firstBackoff * (factor ^ n) 之后进行的,其中 n 是迭代次数。如果配置了 maxBackoff,应用的最大 backoff 时间被限制在 maxBackoff。如果 basedOnPreviousValue 为 true,则通过使用 prevBackoff * factor 来计算backoff。

如果启用,为 Retry filter 配置的默认值如下。

  • retries: 三次
  • series: 5XX系列
  • methods: GET 请求
  • exceptions: IOException 和 TimeoutException
  • backoff: disabled
    下面配置了一个 Retry GatewayFilter。
spring:cloud:gateway:routes:- id: retry_testuri: http://localhost:8080/flakeypredicates:- Host=*.retry.comfilters:- name: Retryargs:retries: 3statuses: BAD_GATEWAYmethods: GET,POSTbackoff:firstBackoff: 10msmaxBackoff: 50msfactor: 2basedOnPreviousValue: false

当使用带有 forward: 前缀的URL的 retry filter 时,应仔细编写目标端点,以便在出现错误时,它不会做任何可能导致响应被发送到客户端并提交的事情。例如,如果目标端点是一个 @Controller,目标controller方法不应该返回带有错误状态码的 ResponseEntity。相反,它应该抛出一个 Exception 或发出一个错误信号(例如,通过 Mono.error(ex) 返回值),retry filter 可以被配置为通过重试来处理。

当对任何带有body的HTTP方法使用 retry filter 时,body将被缓存,网关将变得内存受限。body被缓存在 ServerWebExchangeUtils.CACHED_REQUEST_BODY_ATTR 定义的请求属性(request attribute)中。该对象的类型是 org.springframework.core.io.buffer.DataBuffer。

一个简化的 “快捷” 方式可以用一个 status 和 method 来添加。以下两个例子是等同的。

spring:cloud:gateway:routes:- id: retry_routeuri: https://example.orgfilters:- name: Retryargs:retries: 3statuses: INTERNAL_SERVER_ERRORmethods: GETbackoff:firstBackoff: 10msmaxBackoff: 50msfactor: 2basedOnPreviousValue: false- id: retryshortcut_routeuri: https://example.orgfilters:- Retry=3,INTERNAL_SERVER_ERROR,GET,10ms,50ms,2,false

6.34. 设置允许接收最大请求包的大小。如果请求包大小超过设置的值,则返回 413 Payload Too Large (RequestSize)

当请求的大小超过允许的限制时,RequestSize GatewayFilter 工厂可以限制请求到达下游服务。该过滤器需要一个 maxSize 参数。maxSize 是一个 DataSize 类型,所以值可以定义为一个数字,后面有一个可选的 DataUnit 后缀,如 ‘KB’ 或’MB’。默认是 ‘B’,表示字节。它是以字节为单位定义的请求的可允许的大小限制。下面的列表配置了一个 RequestSize GatewayFilter。

spring:cloud:gateway:routes:- id: request_size_routeuri: http://localhost:8080/uploadpredicates:- Path=/uploadfilters:- name: RequestSizeargs:maxSize: 5000000

RequestSize GatewayFilter 工厂将响应状态设置为 413 Payload Too Large,当请求由于大小而被拒绝时,会有一个额外的头 errorMessage。下面的例子显示了这样一个 errorMessage。

errorMessage : Request size is larger than permissible limit. Request size is 6.0 MB where permissible limit is 5.0 MB

如果在路由定义中没有提供filter参数,默认请求大小被设置为5MB。

6.35.SetRequestHostHeader

在某些情况下,host 头可能需要被重写。在这种情况下,SetRequestHostHeader GatewayFilter 工厂可以将现有的 host header 替换成指定的值。该过滤器需要一个 host 参数。下面的列表配置了一个 SetRequestHostHeader GatewayFilter。

spring:cloud:gateway:routes:- id: set_request_host_header_routeuri: http://localhost:8080/headerspredicates:- Path=/headersfilters:- name: SetRequestHostHeaderargs:host: example.org

SetRequestHostHeader GatewayFilter 工厂将 host 头的值替换为 http://example.org。

6.36.TokenRelay

Token Relay是指OAuth2消费者作为客户端,将传入的令牌转发给传出的资源请求。消费者可以是一个纯粹的客户端(如SSO应用程序)或一个资源服务器。

Spring Cloud Gateway 可以将 OAuth2 访问令牌转发到它所代理的服务的下游。为了在网关中添加这一功能,你需要像这样添加 TokenRelayGatewayFilterFactory。

@Bean
public RouteLocator customRouteLocator(RouteLocatorBuilder builder) {return builder.routes().route("resource", r -> r.path("/resource").filters(f -> f.tokenRelay()).uri("http://localhost:9000")).build();
}

或者,这样。

spring:cloud:gateway:routes:- id: resourceuri: http://localhost:9000predicates:- Path=/resourcefilters:- TokenRelay=

它将(除了登录用户和抓取令牌之外)把认证令牌传递给下游的服务(在这里是 /resource)。

要为 Spring Cloud Gateway 启用这个功能,需要添加以下依赖

org.springframework.boot:spring-boot-starter-oauth2-client

它是如何工作的? {githubmaster}/src/main/java/org/springframework/cloud/gateway/security/TokenRelayGatewayFilterFactory.java[filter]从当前认证的用户中提取一个访问令牌,并将其放在下游请求的请求头中。

完整的工作样本见 该项目。

只有当适当的 spring.security.oauth2.client.* 属性被设置时,
TokenRelayGatewayFilterFactory Bean才会被创建,这将触发
ReactiveClientRegistrationRepository Bean的创建。

TokenRelayGatewayFilterFactory 使用的 ReactiveOAuth2AuthorizedClientService 的默认实现使用了一个内存数据存储。如果你需要一个更强大的解决方案,你将需要提供你自己的实现 ReactiveOAuth2AuthorizedClientService。

6.37. 为所有路由添加过滤器( default Filter)

要添加一个filter并将其应用于所有路由,可以使用 spring.cloud.gateway.default-filters。这个属性需要一个filter的列表。下面的列表定义了一组默认filter。

pring:cloud:gateway:default-filters:- AddResponseHeader=X-Response-Default-Red, Default-Blue- PrefixPath=/httpbin

7.Gloabal Filters 全局过滤器

GlobalFilter接口具有与GatewayFilter相同的签名,只不过, GlobalFilter 会作用于所有路由。

。这些 是有条件的应用于所有路由的特殊过滤器。

This interface and its usage are subject to change in future milestone releases.

7.1 组合式全局过滤器和网关过滤器排序(Combined Global Filter and GatewayFilter Ordering )

当请求与路由匹配时,过滤web处理程序会将GlobalFilter的所有实例和GatewayFilter的所有路由特定实例添加到过滤器链中。这个组合过滤器链由org.springframework.core.Ordered接口排序,您可以通过实现getOrder()方法来设置该接口,值越小,越先执行。

由于Spring Cloud Gateway区分了过滤器逻辑执行的“pre” 和 “post” 阶段(请参阅其工作原理),优先级最高的过滤器是“pre”阶段的第一个,“post”的最后一个。

以下列表配置过滤器链:

@Bean
public GlobalFilter customFilter() {return new CustomGlobalFilter();
}public class CustomGlobalFilter implements GlobalFilter, Ordered {@Overridepublic Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {log.info("custom global filter");return chain.filter(exchange);}@Overridepublic int getOrder() {return -1;}  #值越小,越先执行
}

7.2 转发路由过滤器(Forward Routing Filter)

ForwardRoutingFilter在交换属性ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR中查找URI。如果URL具有转发方案(例如forward:///localendpoint),它使用SpringDispatcherHandler来处理请求。请求URL的路径部分被转发URL中的路径覆盖。未修改的原始URL将附加到ServerWebExchangeUtils.GATEWAY_original_REQUEST_URL_ATTR属性的列表中。

有转发属性,forward。就用spring的DispatcherHandler 处理。 请求 URL 的路径部分被转发 URL
中的路径覆盖
原始url记录在ServerWebExchangeUtils.GATEWAY_ORIGINAL_REQUEST_URL_ATTR

7.3 netty路由过滤器(The Netty Routing Filter ) 网络路由过滤器

如果位于 ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR 交换属性中的 URL 具有 http 或 https 方案,则 Netty 路由过滤器运行。它使用 Netty HttpClient 发出下游代理请求。响应放在 ServerWebExchangeUtils.CLIENT_RESPONSE_ATTR 交换属性中,以供以后的过滤器使用。 (还有一个实验性的 WebClientHttpRoutingFilter 执行相同的功能但不需要 Netty。)

7.4 写响应过滤器( The Netty Write Response Filter Netty Netty)

如果 ServerWebExchangeUtils.CLIENT_RESPONSE_ATTR 交换属性中有 Netty HttpClientResponse,则 NettyWriteResponseFilter 运行。它在所有其他过滤器完成后运行,并将代理响应写回网关客户端响应。 (还有一个实验性的 WebClientWriteResponseFilter 执行相同的功能但不需要 Netty。)

7.5 路由请求地址过滤器(The RouteToRequestUrl Filter )

如果exchange中的ServerWebExchangeUtils.GATEWAY_ROUTE_ATTR 属性中有一个 Route 对象,则运行 RouteToRequestUrlFilter 。它根据请求URI创建一个新URI,但会使用该 Route 对象的URI属性进行更新。新URI放到exchange的 ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR 属性中。
如果URI具有scheme前缀,例如 lb:ws://serviceid ,该 lb scheme将从URI中剥离,并放到 ServerWebExchangeUtils.GATEWAY_SCHEME_PREFIX_ATTR 中,方便后面的过滤器使用。

7.6 (Websocket 路由过滤器) The Websocekt Routing Filter

如果exchange中的 ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR 属性的值的scheme是 ws或者 wss ,则运行Websocket Routing Filter。它底层使用Spring Web Socket将Websocket请求转发到下游。
可为URI添加 lb 前缀实现负载均衡,例如 lb:ws://serviceid 。

如果你使用 SockJS 作为普通 HTTP 的后备,你应该配置一个普通的 HTTP 路由以及 websocket 路由。

spring:cloud:gateway:routes:# SockJS route- id: websocket_sockjs_routeuri: http://localhost:3001predicates:- Path=/websocket/info/**# Normal Websocket route- id: websocket_routeuri: ws://localhost:3001predicates:- Path=/websocket/**

7.7 (网关指标过滤器) The Gateway Metrics Filter 网关指标过滤器

要启用网关指标,请将 spring-boot-starter-actuator 添加为项目依赖项。然后,默认情况下,只要属性 spring.cloud.gateway.metrics.enabled 未设置为 false,网关指标过滤器就会运行。此过滤器添加一个名为 spring.cloud.gateway.requests 的计时器指标,带有以下标签:

  • routeId: 路由Id
  • routeUri: 路由地址
  • outcome: 结果,按 HttpStatus.Series 分类。
  • status: 返回给客户端的请求的 HTTP 状态。
  • httpStatusCode: 返回给客户端的请求的 HTTP 状态。
  • httpMethod: 用于请求的 HTTP 方法

此外,通过属性 spring.cloud.gateway.metrics.tags.path.enabled(默认设置为 false),您可以使用标签激活额外的指标:

  • path:请求的路径。

然后可以从 /actuator/metrics/spring.cloud.gateway.requests 中抓取这些指标,并且可以轻松地与 Prometheus 集成以创建 Grafana 仪表板。要启用 prometheus 端点,请将 micrometer-registry-prometheus 添加为项目依赖项

7.8 (将交换标记为已路由) Marking An Exchange As Routed

在网关路由到 ServerWebExchange 后,它通过将 gatewayAlreadyRouted 添加到交换属性来将该交换标记为“已路由”。一旦请求被标记为已路由,其他路由过滤器将不会再次路由该请求,实质上是跳过过滤器。您可以使用一些便捷的方法将交换标记为已路由或检查交换是否已被路由。

跳过过滤器

  • ServerWebExchangeUtils.isAlreadyRouted 接受一个 ServerWebExchange 对象并检查它是否已被“路由”。
  • ServerWebExchangeUtils.setAlreadyRouted采用ServerWebExchange 对象,标记他为已被“路由”。

7.9 反应式负载均衡器客户端过滤器(LoadBalancerClient Filter)

LoadBalancerClientFilter 会查看exchange的属性 ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR 的值(一个URI),如果该值的scheme是 lb,比如:lb://myservice ,它将会使用Spring Cloud的LoadBalancerClient 来将 myservice 解析成实际的host和port,并替换掉 ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR 的内容。原始地址会追加到 ServerWebExchangeUtils.GATEWAY_ORIGINAL_REQUEST_URL_ATTR 中。该过滤器还会查看 ServerWebExchangeUtils.GATEWAY_SCHEME_PREFIX_ATTR 属性,如果发现该属性的值是 lb ,也会执行相同逻辑。

spring:cloud:gateway:routes:- id: myRouteuri: lb://servicepredicates:- Path=/service/**

默认情况下,如果无法在 LoadBalancer 找到指定服务的实例,那么会返回503(对应如上的例子,找不到service实例,就返回503);可使用 spring.cloud.gateway.loadbalancer.use404=true 让其返回404。
LoadBalancer 返回的 ServiceInstance 的 isSecure 的值,会覆盖请求的scheme。举个例子,如果请求打到Gateway上使用的是 HTTPS ,但 ServiceInstance 的 isSecure 是false,那么下游收到的则是HTTP请求,反之亦然。然而,如果该路由指定了 GATEWAY_SCHEME_PREFIX_ATTR 属性,那么前缀将会被剥离,并且路由URL中的scheme会覆盖 ServiceInstance 的配置

TIPS 这段文档太学术了,讲解了LoadBalancerClientFilter 的实现原理,对使用者来说,意义不大;对使用者来说,其实只要知道这个Filter是用来整合Ribbon的就OK了。 建议:如对原理感兴趣的,建议直接研究源码,源码比官方文档好理解。

7.10 本地响应缓存过滤器

如果LocalResponseCache的关联属性已启用(spring.cloud.gateway.filter.localresponse-cache.enabled),则LocalResponceCache将运行,并使用咖啡因为满足以下条件的所有响应激活本地缓存:

  • 请求是一个脱胎换骨的GET。
  • 响应具有以下状态代码之一:HTTP 200(正常)、HTTP 206(部分内容)或HTTP 301(永久移动)。
  • HTTP Cache-Control标头允许缓存(这意味着它没有以下任何值:请求中没有存储,响应中没有存储或私有)。

它接受两个配置参数:

  • spring.cloud.gateway.filter.local-response-cache.size:设置缓存的最大大小以清除此路由的条目(以KB、MB和GB为单位)。
  • spring.cloud.gateway.filter.local-response-cache.timeToLive:设置缓存项的过期时间(以秒表示,以分钟表示,以小时表示)。

如果未配置这些参数,但启用了全局筛选器,则默认情况下,它会为缓存的响应配置5分钟的生存时间。

此筛选器还实现了HTTP Cache-Control中max-age 值的自动计算。如果原始响应中存在max-age,则使用timeToLive配置参数中设置的秒数重写该值。在随后的调用中,该值将根据响应到期前剩余的秒数重新计算。

https://blog.csdn.net/qq_33472553/article/details/125801298

8. http表头过滤器( HttpHeadersFilter)

HttpHeadersFilters 在将请求发送到下游之前应用于请求,例如在 NettyRoutingFilter 中。

HttpHeadersFilters(HTTP头部过滤器)是在网关路由请求到下游服务之前对请求的头部信息进行处理和转换的组件。这些过滤器允许开发人员对请求头部进行修改、添加或删除操作,以满足特定的需求和业务场景。

HttpHeadersFilters 提供了一种灵活且可定制的方式来处理请求头部。通过定义和配置不同的过滤器,可以实现对请求头部的各种操作。以下是 HttpHeadersFilters 的一些常见功能和用途:

  • 添加头部信息:可以通过过滤器在请求中添加额外的头部信息,比如身份验证凭据、安全令牌、跟踪标识等。这些信息可以帮助下游服务进行身份验证、授权或跟踪请求的处理流程。
  • 修改头部信息:有时候需要对请求头部的某些字段进行修改,比如更改请求的源地址、修改内容类型、设置缓存控制等。通过过滤器可以实现对指定头部字段的修改操作,确保请求被下游服务正确地处理。
  • 删除头部信息:某些情况下,可能需要从请求中删除特定的头部字段。例如,删除敏感信息、移除无关的头部字段或遵循某些协议规范。HttpHeadersFilters 提供了删除指定头部字段的功能,以确保请求的头部信息符合预期。
  • 头部信息的转换:有时候需要对请求头部进行格式转换,以适应下

8.1. Forwared Headers Filter 转发表头过滤器

Forwarded Headers Filter 创建一个 Forwarded 头来发送给下游服务。它将当前请求的 Host 标头、方案和端口添加到任何现有的 Forwarded 标头。

8.2. 从转发的请求中删除标头。被删除的头的默认列表来自IETF (RemoveHopByHop Headers Filter)

RemoveHopByHop 标头过滤器从转发的请求中删除标头。删除的默认标头列表来自 IETF。

默认删除的标题是:

  • Connection
  • Keep-Alive
  • Proxy-Authenticate
  • Proxy-Authorization
  • TE
  • Trailer
  • Transfer-Encoding
  • Upgrade

要更改此设置,请将 spring.cloud.gateway.filter.remove-hop-by-hop.headers 属性设置为要删除的标头名称列表。

8.3.XForwarded Headers FilterXForwarded 标头过滤器

XForwarded 标头过滤器创建各种 X-Forwarded-* 标头以发送到下游服务。它使用当前请求的 Host 标头、方案、端口和路径来创建各种标头。 可以通过以下布尔属性控制单个标题的创建(默认为 true):

  • spring.cloud.gateway.x-forwarded.for-enabled

  • spring.cloud.gateway.x-forwarded.host-enabled

  • spring.cloud.gateway.x-forwarded.port-enabled

  • spring.cloud.gateway.x-forwarded.proto-enabled

  • spring.cloud.gateway.x-forwarded.prefix-enabled
    附加多个标题可以由以下布尔属性控制(默认为 true):

  • spring.cloud.gateway.x-forwarded.for-append

  • spring.cloud.gateway.x-forwarded.host-append

  • spring.cloud.gateway.x-forwarded.port-append

  • spring.cloud.gateway.x-forwarded.proto-append

  • spring.cloud.gateway.x-forwarded.prefix-append

9.TLS 和 SSL 配置

网关可以通过遵循通常的 Spring 服务器配置来监听 HTTPS 上的请求。以下示例显示了如何执行此操作:

server:ssl:enabled: truekey-alias: scgkey-store-password: scg1234key-store: classpath:scg-keystore.p12key-store-type: PKCS12

您可以将网关路由路由到 HTTP 和 HTTPS 后端。如果您要路由到 HTTPS 后端,则可以使用以下配置将网关配置为信任所有下游证书:

spring:cloud:gateway:httpclient:ssl:useInsecureTrustManager: true

使用不安全的信任管理器不适合生产。对于生产部署,您可以使用一组已知证书配置网关,它可以使用以下配置信任这些证书:

spring:cloud:gateway:httpclient:ssl:trustedX509Certificates:- cert1.pem- cert2.pem

如果 Spring Cloud Gateway 没有配置受信任的证书,则使用默认的信任存储(您可以通过设置 javax.net.ssl.trustStore 系统属性来覆盖它)。

9.1. TLS Handshake TLS握手

网关维护一个客户端池,用于路由到后端。通过 HTTPS 进行通信时,客户端会启动 TLS 握手。许多超时与此握手相关。您可以配置这些超时,可以按如下方式配置(显示默认值):

spring:cloud:gateway:httpclient:ssl:handshake-timeout-millis: 10000close-notify-flush-timeout-millis: 3000close-notify-read-timeout-millis: 0

10.Configuration 配置

Spring Cloud Gateway 的配置由 RouteDefinitionLocator 实例的集合驱动。以下清单显示了 RouteDefinitionLocator 接口的定义:

Example 66. RouteDefinitionLocator.java

public interface RouteDefinitionLocator {Flux<RouteDefinition> getRouteDefinitions();
}

默认情况下,PropertiesRouteDefinitionLocator 使用 Spring Boot 的 @ConfigurationProperties 机制加载属性。 早期的配置示例都使用使用位置参数而不是命名参数的快捷表示法。下面两个例子是等价的:

spring:cloud:gateway:routes:- id: setstatus_routeuri: https://example.orgfilters:- name: SetStatusargs:status: 401- id: setstatusshortcut_routeuri: https://example.orgfilters:- SetStatus=401

对于网关的某些用途,属性就足够了,但某些生产用例受益于从外部源(例如数据库)加载配置。未来的里程碑版本将具有基于 Spring Data Repositories 的 RouteDefinitionLocator 实现,例如 Redis、MongoDB 和 Cassandra。

10.1.RouteDefinition Metrics 路由定义指标

要启用 RouteDefinition 指标,请将 spring-boot-starter-actuator 添加为项目依赖项。然后,默认情况下,只要属性 spring.cloud.gateway.metrics.enabled 设置为 true,这些指标就可用。将添加一个名为 spring.cloud.gateway.routes.count 的仪表度量,其值是 RouteDefinition 的数量。该指标可从 /actuator/metrics/spring.cloud.gateway.routes.count 获得。

11.Route Metadata Configuration

您可以使用元数据为每个路由配置附加参数,如下所示:

spring:cloud:gateway:routes:- id: route_with_metadatauri: https://example.orgmetadata:optionName: "OptionValue"compositeObject:name: "value"iAmNumber: 1

您可以从交换中获取所有元数据属性,如下所示:

Route route = exchange.getAttribute(GATEWAY_ROUTE_ATTR);
// get all metadata properties
route.getMetadata();
// get a single metadata property
route.getMetadata(someKey);

12. Http超时配置 (Http timeouts configuration )

可以为所有路由配置 Http 超时(响应和连接),并被每个特定路由覆盖。(overridden for 被覆盖)

12.1. Global timeouts 全局超时配置

要配置全局 http 超时:

  • connect-timeout: 必须以毫秒为单位指定连接超时。
  • response-timeout:响应超时必须指定为 java.time.Duration

global http timeouts example

spring:cloud:gateway:httpclient:connect-timeout: 1000response-timeout: 5s

12.2. Per-route timeouts 单个路由超时配置

要配置每条路由超时:
connect-timeout 必须以毫秒为单位指定连接超时。
response-timeout 必须以毫秒为单位指定连接超时。

用yaml配置 per-route http timeouts configuration via configuration

 - id: per_route_timeoutsuri: https://example.orgpredicates:- name: Pathargs:pattern: /delay/{timeout}metadata:response-timeout: 200connect-timeout: 200

用java配置 per-route timeouts configuration using Java DSL

import static org.springframework.cloud.gateway.support.RouteMetadataUtils.CONNECT_TIMEOUT_ATTR;
import static org.springframework.cloud.gateway.support.RouteMetadataUtils.RESPONSE_TIMEOUT_ATTR;@Beanpublic RouteLocator customRouteLocator(RouteLocatorBuilder routeBuilder){return routeBuilder.routes().route("test1", r -> {return r.host("*.somehost.org").and().path("/somepath").filters(f -> f.addRequestHeader("header1", "header-value-1")).uri("http://someuri").metadata(RESPONSE_TIMEOUT_ATTR, 200).metadata(CONNECT_TIMEOUT_ATTR, 200);}).build();}

具有负值的每条路由响应超时将禁用全局响应超时值。
问题:不是负值,就不会禁用吗?
A per-route response-timeout with a negative value will disable the global response-timeout value.

 - id: per_route_timeoutsuri: https://example.orgpredicates:- name: Pathargs:pattern: /delay/{timeout}metadata:response-timeout: -1

12.3 Fluent Java Routes API 流畅的 Java 路由 API

为了允许在 Java 中进行简单配置,RouteLocatorBuilder bean 包含一个流畅的 API。下面的清单显示了它是如何工作的:
Example 69. GatewaySampleApplication.java

// static imports from GatewayFilters and RoutePredicates
@Bean
public RouteLocator customRouteLocator(RouteLocatorBuilder builder, ThrottleGatewayFilterFactory throttle) {return builder.routes().route(r -> r.host("**.abc.org").and().path("/image/png").filters(f ->f.addResponseHeader("X-TestHeader", "foobar")).uri("http://httpbin.org:80")).route(r -> r.path("/image/webp").filters(f ->f.addResponseHeader("X-AnotherHeader", "baz")).uri("http://httpbin.org:80").metadata("key", "value")).route(r -> r.order(-1).host("**.throttle.org").and().path("/get").filters(f -> f.filter(throttle.apply(1,1,10,TimeUnit.SECONDS))).uri("http://httpbin.org:80").metadata("key", "value")).build();
}

这种风格还允许更多的自定义谓词断言。 RouteDefinitionLocator bean 定义的谓词使用逻辑与进行组合。通过使用 fluent Java API,您可以在 Predicate 类上使用 and()、or() 和 negate() 运算符。

12.4. The DiscoveryClient Route Definition DiscoveryClient 路由定义定位器

您可以将网关配置为基于向 DiscoveryClient 兼容的服务注册表注册的服务创建路由。 要启用此功能,请设置 spring.cloud.gateway.discovery.locator.enabled=true 并确保 DiscoveryClient 实现(例如 Netflix Eureka、Consul 或 Zookeeper)在类路径上并已启用。

12.4.1. Configuring Predicates and Filters For DiscoveryClient Routes 为 DiscoveryClient 路由配置谓词和过滤器

默认情况下,网关为使用 DiscoveryClient 创建的路由定义单个谓词和过滤器。 默认谓词是使用模式 /serviceId/** 定义的路径谓词,其中 serviceId 是来自 DiscoveryClient 的服务的 ID。 默认过滤器是使用正则表达式 /serviceId/?(?.*) 和替换 /${remaining} 的重写路径过滤器。这会在请求被发送到下游之前从路径中去除服务 ID。 如果要自定义 DiscoveryClient 路由使用的谓词或过滤器,请设置 spring.cloud.gateway.discovery.locator.predicates[x] 和 spring.cloud.gateway.discovery.locator.filters[y]。这样做时,如果要保留该功能,则需要确保包含前面显示的默认谓词和过滤器。以下示例显示了它的样子:

Example 70. application.properties

spring.cloud.gateway.discovery.locator.predicates[0].name: Path
spring.cloud.gateway.discovery.locator.predicates[0].args[pattern]: "'/'+serviceId+'/**'"
spring.cloud.gateway.discovery.locator.predicates[1].name: Host
spring.cloud.gateway.discovery.locator.predicates[1].args[pattern]: "'**.foo.com'"
spring.cloud.gateway.discovery.locator.filters[0].name: CircuitBreaker
spring.cloud.gateway.discovery.locator.filters[0].args[name]: serviceId
spring.cloud.gateway.discovery.locator.filters[1].name: RewritePath
spring.cloud.gateway.discovery.locator.filters[1].args[regexp]: "'/' + serviceId + '/?(?<remaining>.*)'"
spring.cloud.gateway.discovery.locator.filters[1].args[replacement]: "'/${remaining}'"

13. 访问日志配置(Reactor Netty Access Logs Reactor Netty )

要启用 Reactor Netty 访问日志,请设置 -Dreactor.netty.http.server.accessLogEnabled=true。

  • 它必须是 Java 系统属性,而不是 Spring Boot 属性。
    您可以将日志记录系统配置为具有单独的访问日志文件。以下示例创建一个 Logback 配置:

Example 71. logback.xml

   <appender name="accessLog" class="ch.qos.logback.core.FileAppender"><file>access_log.log</file><encoder><pattern>%msg%n</pattern></encoder></appender><appender name="async" class="ch.qos.logback.classic.AsyncAppender"><appender-ref ref="accessLog" /></appender><logger name="reactor.netty.http.server.AccessLog" level="INFO" additivity="false"><appender-ref ref="async"/></logger>

14. CORS Configuration 跨域配置

您可以配置网关来控制 CORS 行为。 “全局”CORS 配置是 URL 模式到 Spring Framework CorsConfiguration 的映射。以下示例配置 CORS:

spring:cloud:gateway:globalcors:cors-configurations:'[/**]':allowedOrigins: "https://docs.spring.io"allowedMethods:- GET

在前面的示例中,对于所有 GET 请求路径,允许来自 docs.spring.io 的请求的 CORS 请求。 要为某些网关路由谓词未处理的请求提供相同的 CORS 配置,请将 spring.cloud.gateway.globalcors.add-to-simple-url-handler-mapping 属性设置为 true。当您尝试支持 CORS 预检请求并且您的路由谓词未评估为 true 时,这很有用,因为 HTTP 方法是选项。

16. Troubleshooting 故障排除

本节介绍使用 Spring Cloud Gateway 时可能出现的常见问题。

16.1. Log Levels

以下记录器可能在 DEBUG 和 TRACE 级别包含有价值的故障排除信息:

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/221774.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【机器学习 | 假设检验系列】假设检验系列—卡方检验(详细案例,数学公式原理推导),最常被忽视得假设检验确定不来看看?

&#x1f935;‍♂️ 个人主页: AI_magician &#x1f4e1;主页地址&#xff1a; 作者简介&#xff1a;CSDN内容合伙人&#xff0c;全栈领域优质创作者。 &#x1f468;‍&#x1f4bb;景愿&#xff1a;旨在于能和更多的热爱计算机的伙伴一起成长&#xff01;&#xff01;&…

2024 年,新程序员如何与AI共赢!!

&#x1f337;&#x1f341; 博主猫头虎 带您 Go to New World.✨&#x1f341; &#x1f984; 博客首页——猫头虎的博客&#x1f390; &#x1f433;《面试题大全专栏》 文章图文并茂&#x1f995;生动形象&#x1f996;简单易学&#xff01;欢迎大家来踩踩~&#x1f33a; &a…

如何在Facebook Business Manager进行企业认证

Facebook Business Manager&#xff0c;简称BM&#xff0c;按照字面意思理解就是Facebook官方的商务管理平台&#xff0c;是供广告主团队去使用的一个管理工具。BM可以绑定Facebook公共主页、广告账户等一系列Facebook账号。通过BM&#xff0c;企业就可以在一个后台&#xff0c…

Amazon SageMaker: 拓展机器学习边界,塑造未来创新趋势

授权说明&#xff1a;本篇文章授权活动官方亚马逊云科技文章转发、改写权&#xff0c;包括不限于在 亚马逊云科技开发者社区, 知乎&#xff0c;自媒体平台&#xff0c;第三方开发者媒体等亚马逊云科技官方渠道。 近期在 re:Invent 2023 大会上&#xff0c;亚马逊云科技发布了一…

Stable Diffusion 源码解析(1)

参考1&#xff1a;https://blog.csdn.net/Eric_1993/article/details/129393890 参考2&#xff1a;https://zhuanlan.zhihu.com/p/613337342 1.StableDiffusion基本原理1.1 UNetModel、FrozenCLIP 模型1.2 DDPM、DDIM、PLMS算法 2. Runwayml SD 源码2.1 Img2Img Pipeline2.2 DD…

蚁群优化算法ACO

蚁群优化算法模拟了自然界中蚂蚁的觅食行为&#xff0c;信息素浓度的大小表征路径的远近&#xff0c;信息素浓度越高&#xff0c;表示对应的路径距离越短。同时&#xff0c;路径上的信息素浓度会随着时间的推进而逐渐衰减。 1.过程 &#xff08;1&#xff09;初始化参数 蚁群…

Nginx+Tomcat实现负载均衡和动静分离

目录 前瞻 动静分离和负载均衡原理 实现方法 实验&#xff08;七层代理&#xff09; 部署Nginx负载均衡服务器(192.168.75.50:80) 部署第一台Tomcat应用服务器&#xff08;192.168.75.60:8080&#xff09; 多实例部署第二台Tomcat应用服务器&#xff08;192.168.75.70:80…

8080端口被占用怎么解决,并结束释放8080端口

8080端口是被用于WWW代理服务的&#xff0c;可以实现网页浏览&#xff0c;经常在访问某个网站或使用代理服务器的时候&#xff0c;Win10 8080端口被占用解决方法吧。 1、按【 Win r】 2、运行窗口&#xff0c;输入【cmd】命令&#xff0c;按【确定或回车】&#xff0c;打开命…

基于SpringBoot 校园招聘系统设计与实现(源码+文档+可视化HTML+数据库)

摘 要 基于SpringBoot 校园招聘系统是一种基于Java技术的校园招聘和可视化展示的系统。该系统通过采集和整合各类招聘网站、社交媒体等渠道的数据&#xff0c;对招聘岗位进行深入分析&#xff0c;并将分析结果以直观、易懂的可视化形式呈现。系统能够自动从多个数据源获取招聘…

电子学会C/C++编程等级考试2023年03月(五级)真题解析

C/C++等级考试(1~8级)全部真题・点这里 第1题:拼点游戏 C和S两位同学一起玩拼点游戏。有一堆白色卡牌和一堆蓝色卡牌,每张卡牌上写了一个整数点数。C随机抽取n张白色卡牌,S随机抽取n张蓝色卡牌,他们进行n回合拼点,每次两人各出一张卡牌,点数大者获得三颗巧克力,小者获…

Flutter:web项目跨域问题解决

前后端解决系列 文章目录 一、Flutter web客户端解决本地环境调试跨域问题二、Flutter web客户端解决线上环境跨域问题 一、Flutter web客户端解决本地环境调试跨域问题 就一句命令【--web-browser-flag "--disable-web-security"】&#xff0c;用来屏蔽浏览器域名请…

大模型时代-让AI自己开发自己

一、前言 AI能自己开发自己或者开发和一个很像自己的东西吗&#xff1f;显然是可以的&#xff01;因为AI模型的算法&#xff0c;基本就是学习和递归 二、大模型的算法实现例子 本例子就是通过AI模型来写 大模型的实现通常涉及到深度学习框架和大量的计算资源。具体的算法代…

Java入门学习笔记二

一、抽象类 当编写一个类时&#xff0c;我们往往会为该类定义一些方法&#xff0c;这些方法是用来描述该类的行为方式&#xff0c;那么这些方法都有具体的方法体。 分析事物时&#xff0c;发现了共性内容&#xff0c;就出现向上抽取。会有这样一种特殊情况&#xff0c;就是功…

Python实现高效摸鱼,批量识别银行卡号并自动写入Excel表格

前言 每当有新员工入职&#xff0c;人事小姐姐都要收集大量的工资卡信息&#xff0c;并且生成Excel文档&#xff0c;看到小姐姐这么辛苦&#xff0c;我就忍不住要去帮她了… 于是我用1行代码就实现了自动识别银行卡信息并且自动生成Excel文件&#xff0c;小姐姐当场就亮眼汪汪…

智能冶钢厂环境监控与设备控制系统(边缘物联网网关)

目录 1、项目背景 2、项目功能介绍 3、模块框架 3.1 架构框图 3.2 架构介绍 4、系统组成与工作原理 4.1 数据采集 4.2 指令控制 4.3 其他模块 4.3.1 网页、qt视频流 4.3.2 qt搜索进程 5、成果呈现 6、问题解决 7、项目总结 1、项目背景 这个项目的背景是钢铁行业的…

tesseract-ocr安装使用

描述&#xff1a; 在centos上安装 tesseract 并在springboot项目中使用 步骤一&#xff1a;安装 确认使用的版本tesseract和test4j版本需要匹配&#xff0c;这里选择最新版 tesseract5.3.3 &#xff0c;test4j 5.9.0 版本匹配可查看 Releases nguyenq/tess4j GitHub 或…

使用 iperf 和 iftop 测试网络带宽

博主历时三年精心创作的《大数据平台架构与原型实现&#xff1a;数据中台建设实战》一书现已由知名IT图书品牌电子工业出版社博文视点出版发行&#xff0c;点击《重磅推荐&#xff1a;建大数据平台太难了&#xff01;给我发个工程原型吧&#xff01;》了解图书详情&#xff0c;…

CSS中神奇的filter属性

CSS是Web开发中不可或缺的一部分&#xff0c;它可以帮助开发者在页面上添加各种各样的样式和效果。其中一个比较神奇的CSS属性就是filter&#xff0c;它可以让我们实现各种有趣的图形处理效果。 一、filter属性的基础 filter属性是CSS中用于对元素进行图形效果处理的属性之一…

C语言—每日选择题—Day47

第一题 1. 以下逗号表达式的值为&#xff08;&#xff09; (x 4 * 5, x * 5), x 25 A&#xff1a;25 B&#xff1a;20 C&#xff1a;100 D&#xff1a;45 答案及解析 D 本题考查的就是逗号表达式&#xff0c;逗号表达式是依次计算每个表达式&#xff0c;但是只输出最后一个表…

【算法题】开源项目热度榜单(js)

解法 const lines ["4","8 6 2 8 6","camila 66 70 46 158 80","victoria 94 76 86 189 211","athony 29 17 83 21 48","emily 53 97 1 19 218", ]; const lines2 ["5","5 6 6 1 2","…