简介
Spring Cloud Gateway 网关是SpringCloud官方提供的;
使用流程
- 导入依赖
<!--spring-cloud-starter-gateway 网关-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
- 配置application.yaml文件,配置路由
路由:网关的基本构建组成,它由ID,目标URI,谓词集合和过滤器集合定义,如果集合谓词为true,则匹配路由,否则不匹配;过滤可以在发送给下游请求之前或之后修改请求和响应;
application.yaml示例:
spring:
application:
#服务名字
name: spring-cloud-gateway
cloud:
#配置网关
gateway:
discovery:
locator:
enabled: true #启用DiscoveryClient网关集成,可以实现服务的发现
#配置网关路由转发规则
routes:
#- id: route0
#ri: http://localhost:8083
#predicates: #谓词:判断,是不是?对不对?是否匹配?
#- Path=/test, /index, /echo, /api #路径谓词:匹配这些路径请求
- id: route1 #路由id
uri: lb://29-nacos-discovery-consumer
predicates: #谓词:判断,是不是?对不对?是否匹配?
- Path=/**
#- After=2020-08-15T22:35:25.335+08:00[Asia/Shanghai]
#- Before=2020-09-15T17:35:25.335+08:00[Asia/Shanghai]
#- Between=2020-08-13T17:35:25.335+08:00[Asia/Shanghai], 2020-08-14T17:35:25.335+08:00[Asia/Shanghai]
#- Cookie=token, 123456
#- Header=X-Request-Id, \d+
#- Query=token
#- Token=123456
#- AccessTime=下午6:00, 上午6:00
filters:#过滤器
- AddRequestHeader=X-Request-red, blue
- AddRequestParameter=color, red
- RequestLog=prefix, gateway #我们自定义的filter
- id: route2
uri: lb://29-nacos-discovery-consumer #lb:为负载均衡
predicates:
- Path=/test*/** # /test01/abc/123
- id: route3
uri: lb://29-nacos-discovery-provider
predicates:
- Path=/service/**
#- After=2020-10-15T17:35:25.335+08:00[Asia/Shanghai]
#- Before=2020-09-15T17:35:25.335+08:00[Asia/Shanghai]
#- Between=2020-08-13T17:35:25.335+08:00[Asia/Shanghai], 2020-08-15T17:35:25.335+08:00[Asia/Shanghai]
#- Cookie=token, ch.p
#- Header=X-Request-Id, \d+
#- Method=GET,POST
filters:
- AddRequestHeader=X-Request-Id, 12345
- 启动服务
路由谓词
- The After Route Predicate Factory(指定时间之后)
- The Before Route Predicate Factory(指定时间之前)
- The Between Route Predicate Factory(指定时间在这个中间)
- The Cookie Route Predicate Factory(请求头需要带的Cookie)
- The Header Route Predicate Factory(请求头需要对应的值)
- The Host Route Predicate Factory(匹配host)
- The Method Route Predicate Factory(匹配get,post不同的请求方式)
- The Path Route Predicate Factory(根据Path路由)
- The Query Route Predicate Factory(查询参数路由,需要配置关键词)
- The RemoteAddr Route Predicate Factory(请求的远程IP路由)
- The Weight Route Predicate Factory(权重谓词可以定义不同路由的路由权重)
谓词中的指定时间,时间格式可以通过如下方式获取:
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofLocalizedTime(FormatStyle.SHORT);
String nowTime = dateTimeFormatter.format(ZonedDateTime.now());
System.out.println(nowTime);
自定义谓词
自定义路由谓词需要继承 AbstractRoutePredicateFactory 工厂类,并且需要重写AbstractRoutePredicateFactory 工厂类的 apply() 方法和shortcutFieldOrder方法。在 apply() 方法中可以通过 serverWebExchange.getRequest() 拿到 ServerHttpRequest 对象,可以获取到请求的参数、请求方式、请求头等信息。apply() 方法的参数是自定义的配置类,在使用的时候配置参数,在 apply 方法中直接获取使用。命名需要以 RoutePredicateFactory 结尾,比如TestPredicateRoutePredicateFactory,那么在使用的时候TestPredicate 就是这个路由谓词工厂的名称.
路由过滤器
路由过滤器允许以某种方式修改传入的HTTP请求或传出的HTTP响应,Spring Cloud Gateway包括许多内置的GatewayFilter工厂;一共有31个过滤器
- The AddRequestHeader GatewayFilter Factory
- The AddRequestParameter GatewayFilter Factory
- The AddResponseHeader GatewayFilter Factory
- The DedupeResponseHeader GatewayFilter Factory
- The Hystrix GatewayFilter Factory
- Spring Cloud CircuitBreaker GatewayFilter Factory
- The FallbackHeaders GatewayFilter Factory
- The MapRequestHeader GatewayFilter Factory
- The PrefixPath GatewayFilter Factory
- The PreserveHostHeader GatewayFilter Factory
- The RequestRateLimiter GatewayFilter Factory
- The RedirectTo GatewayFilter Factory
- The RemoveRequestHeader GatewayFilter Factory
- RemoveResponseHeader GatewayFilter Factory
- The RemoveRequestParameter GatewayFilter Factory
- The RewritePath GatewayFilter Factory
- RewriteLocationResponseHeader GatewayFilter Factory
- The RewriteResponseHeader GatewayFilter Factory
- The SaveSession GatewayFilter Factory
- The SecureHeaders GatewayFilter Factory
- The SetPath GatewayFilter Factory
- The SetRequestHeader GatewayFilter Factory
- The SetResponseHeader GatewayFilter Factory
- The SetStatus GatewayFilter Factory
- The StripPrefix GatewayFilter Factory
- The Retry GatewayFilter Factory
- The RequestSize GatewayFilter Factory
- The SetRequestHost GatewayFilter Factory
- Modify a Request Body GatewayFilter Factory
- Modify a Response Body GatewayFilter Factory
- Default Filters
Spring Cloud Gateway自定义路由过滤器
网关过滤器的顶层接口是GatewayFilterFactory
通常情况下可以继承AbstractGatewayFilterFactory实现自定义网关过滤器;
或者继承AbstractNameValueGatewayFilterFactory,该方式配置方式更简单,然后覆盖里面的一个方法,具体参考一下我们的样例代码,实际上理解流程思路即可,真正需要做的时候,查一下就可以;
Spring Cloud Gateway全局过滤器
上面的过滤器工厂是执行在指定路由之上,可以称为路由过滤器(或者局部过滤器),而全局过滤器是作用于所有的路由上,对所有的路由进行过滤;全局过滤器的顶层接口是GlobalFilter ,和GatewayFilter 有一样的接口定义,只不过GlobalFilter 会作用于所有路由;全局过滤器有执行顺序问题,通过getOrder()方法的返回值决定执行顺序,数值越小越靠前执行;
Spring cloud gateway默认内置了很多全局过滤器,比如:
- Combined Global Filter and GatewayFilter Ordering
- Forward Routing Filter
- The LoadBalancerClient Filter
- The ReactiveLoadBalancerClientFilter
- The Netty Routing Filter
- The Netty Write Response Filter
- The RouteToRequestUrl Filter
- The Websocket Routing Filter
- The Gateway Metrics Filter
- Marking An Exchange As Routed
Spring Cloud Gateway集成ribbon负载均衡
spring cloud gateway已经整合好了ribbon,已经可以实现负载均衡,我们不需要做任何工作,网关对后端微服务的转发就已经具有负载均衡功能;
Spring Cloud Gateway集成Sentinel
网关集成Sentinel是为了流控熔断降级,具体集成整合步骤如下:
- 添加依赖
<!-- sentinel-spring-cloud-gateway-adapter -->
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-spring-cloud-gateway-adapter</artifactId>
<version>1.7.2</version>
</dependency>
- 添加sentinel控制台配置;
#sentinel dashboard管理后台
spring:
cloud:
sentinel:
eager: true
transport:
dashboard: 192.168.172.128:8080
- 写代码,在spring容器中配置一个Sentinel的全局过滤器
@Bean
@Order(-1)
public GlobalFilter sentinelGatewayFilter() {
return new SentinelGatewayFilter();
}
- 测试
Spring Cloud Gateway解决跨域问题
/**
* 配置网关跨域cors请求支持
*/
@Configuration
public class CorsConfig {
@Bean
public CorsWebFilter corsFilter() {
CorsConfiguration config = new CorsConfiguration();
config.addAllowedMethod("*");
config.addAllowedOrigin("*");
config.addAllowedHeader("*");
UrlBasedCorsConfigurationSource source = new
UrlBasedCorsConfigurationSource(new PathPatternParser());
source.registerCorsConfiguration("/**", config);
return new CorsWebFilter(source);
}
}