Gateway 常用配置 CORS 跨域配置 YML 配置方式 1 2 3 4 5 6 7 8 9 10 11 spring: cloud: gateway: globalcors: corsConfigurations: '[/**]' : allowedOriginPatterns: "*" allowed-methods: "*" allowed-headers: "*" allow-credentials: true exposedHeaders: "Content-Disposition,Content-Type,Cache-Control"
若添加上述配置后,前端页面出现 The 'Access-Control-Allow-Origin' header contains multiple values 'http://127.0.0.1:8010, http://127.0.0.1:8010', but only one is allowed.
这样的错误,则需要添加以下配置来去掉重复的 HTTP Header
1 2 3 4 5 6 7 8 9 10 11 12 13 spring: cloud: gateway: default-filters: - DedupeResponseHeader=Access-Control-Allow-Credentials Access-Control-Allow-Origin Access-Control-Allow-Headersa globalcors: corsConfigurations: '[/**]' : allowedOriginPatterns: "*" allowed-methods: "*" allowed-headers: "*" allow-credentials: true exposedHeaders: "Content-Disposition,Content-Type,Cache-Control"
Java 配置方式 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.web.cors.CorsConfiguration;import org.springframework.web.cors.reactive.CorsWebFilter;import org.springframework.web.cors.reactive.UrlBasedCorsConfigurationSource;@Configuration public class GlobalCorsConfig { @Bean public CorsWebFilter corsWebFilter () { CorsConfiguration config = new CorsConfiguration(); config.addAllowedOrigin("http://127.0.0.1:8010" ); config.addAllowedHeader("*" ); config.addAllowedMethod("*" ); config.setAllowCredentials(true ); config.addExposedHeader("Content-Disposition" ); config.addExposedHeader("Content-Type" ); config.addExposedHeader("Cache-Control" ); UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); source.registerCorsConfiguration("/**" , config); return new CorsWebFilter(source); } }
路由超时时间配置 路由超时配置可以为所有路由配置 HTTP 超时(响应和连接),并为每个特定路由覆盖 HTTP 超时。
全局路由的超时时间配置 配置全局 HTTP 超时(响应和连接),需要使用以下两个参数:
connect-timeout
:必须以毫秒为单位指定连接超时时间response-timeout
:必须指定为 java.time.Duration1 2 3 4 5 6 spring: cloud: gateway: httpclient: connect-timeout: 1000 response-timeout: 5s
每个路由的超时时间配置 可以通过路由的 metadata
以下两个参数配置每个路由的超时时间:
connect-timeout
:必须以毫秒为单位指定连接超时时间response-timeout
:必须以毫秒为单位指定响应超时时间1 2 3 4 5 6 7 8 9 - id: per_route_timeouts uri: https://example.org predicates: - name: Path args: pattern: /delay/{timeout} metadata: response-timeout: 1000 connect-timeout: 1000
使用 Java DSL 为每个路由配置超时时间 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 import static org.springframework.cloud.gateway.support.RouteMetadataUtils.CONNECT_TIMEOUT_ATTR;import static org.springframework.cloud.gateway.support.RouteMetadataUtils.RESPONSE_TIMEOUT_ATTR;@Bean public 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, 1000 ) .metadata(CONNECT_TIMEOUT_ATTR, 1000 ); }) .build(); }
常见使用问题 整合 Nacos 出现 503 错误 Spring Boot Spring Cloud Spring Cloud Alibaba 2.6.3 2021.0.1 2021.0.1.0 3.2.0 2023.0.0 2022.0.0.0
1 2 3 4 5 6 7 8 9 10 11 12 13 spring: cloud: nacos: discovery: server-addr: 192.168 .56 .103 :8848 gateway: routes: - id: tmall-product uri: lb://tmall-product predicates: - Path=/api/** filters: - RewritePath=/api(?<segment>/?.*), /tmall-product/$\{segment}
Gateway 使用 Nacos 作为服务注册中心,基于上述的配置内容,当通过 uri: http://127.0.0.1:9090
去直接调用 tmall-product
服务时,是可以正常调用的,但是使用 uri: lb://tmall-product
时就无法调用服务,Gateway 返回 503
错误码(如下图)。
造成 Gateway 负载均衡失效的原因是,从 Spring Cloud 2020 版本开始,Spring Cloud 弃用了 Ribbon,使用 Spring Cloud Loadbalancer
作为客户端的负载均衡组件;因此 Spring Cloud Alibaba 在 2020 及之后版本的 Nacos 中也移除了 Ribbon
的依赖,最终导致 Gateway 无法通过 lb://
路由到指定的服务,继而出现了 503
错误码。解决方案是引入 Spring Cloud Loadbalancer
的 Maven 坐标即可:
1 2 3 4 <dependency > <groupId > org.springframework.cloud</groupId > <artifactId > spring-cloud-loadbalancer</artifactId > </dependency >
context-path 导致服务调用失败 微服务应用配置了 context-path
,并且指定 IP 将微服务注册到 Nacos 注册中心 1 2 3 4 5 6 7 8 9 10 11 server: port: 8004 servlet: context-path: / spring: cloud: nacos: discovery: ip: 192.168 .1 .140 server-addr: ${NACOS_HOST:127.0.0.1}:${NACOS_PORT:8848}
当外部通过 Gateway 调用微服务应用的接口时,会返回以下错误信息: 1 2 3 4 5 { "code" : 1 , "msg" : "null: /192.168.1.140:8004" , "data" : null }
解决办法有两种:(1) 去掉 context-path
的配置1 2 3 4 5 6 7 8 9 server: port: 8004 spring: cloud: nacos: discovery: ip: 192.168 .1 .140 server-addr: ${NACOS_HOST:127.0.0.1}:${NACOS_PORT:8848}
(2) 将微服务注册进 Nacos 时,指定元数据(metadata
)1 2 3 4 5 6 7 8 9 10 11 12 13 14 server: port: 8004 servlet: context-path: / spring: cloud: nacos: discovery: ip: 192.168 .1 .140 server-addr: ${NACOS_HOST:127.0.0.1}:${NACOS_PORT:8848} metadata: management.context-path: ${server.servlet.context-path}
预览: