赞
踩
Spring Cloud Gateway是Spring Cloud自己的产物,基于Spring 5 和Spring Boot 2.0 开发,Spring Cloud Gateway的出现是为了代替zuul,在Spring Cloud 高版本中没有对zuul 2.0进行集成,SpringCloud Gateway使用了高性能的Reactor模式通信框架Netty。
Spring Cloud Gateway 的目标,不仅提供统一的路由方式,并且基于 Filter 链的方式提供了网关基本的功能,例如:安全,监控/指标,和限流。
Spring Cloud Gataway有几个核心组成:
Spring Cloud Gateway的Filter和Zuul的过滤器类似,可以在请求发出前后进行一些业务上的处理 ,这里分为两种类型的Filter,分别是Gateway Filter网关filter和Global Filter全局Filter, 他们的区别在后续会讲到。
网关配置的基本组成模块,和Zuul的路由配置模块类似。一个Route模块由一个 ID,一个目标 URI,一组断言和一组过滤器定义。如果断言为真,则路由匹配,目标URI会被访问。说白了就是把url请求路由到对应的资源(服务),或者说是一个请求过来Gateway应该怎么把这个请求转发给下游的微服务,转发给谁。
这是一个 Java 8 的 Predicate,可以使用它来匹配来自 HTTP 请求的任何内容,例如 headers 或参数。断言的输入类型是一个 ServerWebExchange。简单理解就是处理HTTP请求的匹配规则,在什么样的请情况下才能命中资源继续访问。
客户端向Spring Cloud Gateway发出请求。如果网关处理程序映射确定请求与路由匹配,则将其发送到网关Web处理程序。该处理程序通过特定于请求的过滤器链来运行请求。筛选器由虚线分隔的原因是,筛选器可以在发送代理请求之前和之后运行逻辑。所有“前置”过滤器逻辑均被执行。然后发出代理请求。发出代理请求后,将运行“后”过滤器逻辑。
<!--服务注册与发现-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
@SpringBootApplication
@EnableDiscoveryClient
public class GatewayApplication {
public static void main(String[] args) {
SpringApplication.run(GatewayApplication.class, args);
}
}
server: port: 10060 eureka: client: serviceUrl: defaultZone: http://localhost:10010/eureka/ instance: instance-id: gateway-server spring: application: name: gateway-server cloud: gateway: discovery: locator: enabled: false #开放服务名访问方式 lower-case-service-id: true #服务名小写 routes: - id: user-server #指定服务名 uri: lb://user-server #去注册中心找这个服务名 predicates: #断言,匹配访问的路径 - Path=/user/** #服务访问路径 filters: - StripPrefix=1 #请求转发的时候会去掉 /user访问路径
简单解释
什么是断言工厂:官方解释–Spring Cloud Gateway将路由作为Spring WebFlux HandlerMapping基础架构的一部分进行匹配。Spring Cloud Gateway包括许多内置的路由断言工厂。所有这些断言都与HTTP请求的不同属性匹配。您可以将多个路由断言工厂与逻辑and语句结合使用。
Gateway的filter从生命周期上可以为“pre”和“post”类型。根据作用范围可分为针对于单个路由的gateway filter
,和针对于所有路由的Global Filer
针对单个路由的Filter, 它允许以某种方式修改HTTP请求或HTTP响应。过滤器可以作用在某些特定的请求路径上。Gateway内置了很多的GatewayFilter工厂。如果要使用这些Filter只需要在配置文件配置GatewayFilter Factory的名称
在Spring Cloud Gateway自定义过滤器,过滤器需要实现GatewayFilter和Ordered这两个接口
public class RequestTimeFilter implements GatewayFilter, Ordered { @Override public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) { Long startTime = new Date().getTime(); return chain.filter(exchange).then( Mono.fromRunnable(() -> { Long endTime = new Date().getTime(); System.out.println("当前请求消耗时间:"+ (endTime-startTime)); }) ); } @Override public int getOrder() { return 0; } }
该Filter配置在对应的路由
@Configuration public class FilterConfig { //配置Filter作用于那个访问规则上 @Bean public RouteLocator customerRouteLocator(RouteLocatorBuilder builder) { return builder.routes().route(r -> r.path("/services/user2/**") //去掉2个前缀 .filters(f -> f.stripPrefix(2) .filter(new RequestTimeFilter()) .addResponseHeader("X-Response-test", "test")) .uri("lb://user-server") .order(0) .id("test-RequestTimeFilter") ).build(); } }
GlobalFilter:全局过滤器,不需要在配置文件中配置,作用在所有的路由上,最终通过GatewayFilterAdapter包装成GatewayFilterChain可识别的过滤器,它为请求业务以及路由的URI转换为真实业务服务的请求地址的核心过滤器,不需要配置,系统初始化时加载,并作用在每个路由上。
模拟了一个登陆检查的Filter
@Component public class TimeGlobalFilter implements GlobalFilter, Ordered { @Override public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) { List<String> tokens = exchange.getRequest().getHeaders().get("token"); if (tokens == null || tokens.size() == 0) { //响应对象 ServerHttpResponse response = exchange.getResponse(); //构建错误结果 HashMap<String,Object> data = new HashMap<>(); data.put("code",401); data.put("message","未登录"); DataBuffer buffer = null; try { byte[] bytes = "先登录再进入好吗~~~~".getBytes("utf-8"); buffer = response.bufferFactory().wrap(bytes); //设置完成相应,不会继续执行后面的filter //response.setComplete(); response.setStatusCode(HttpStatus.UNAUTHORIZED); response.getHeaders().add("Content-Type","application/json;charset=UTF-8"); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } //把结果写给客户端 return response.writeWith(Mono.just(buffer)); } return chain.filter(exchange); } @Override public int getOrder() { return 0; } }
使用 buffer = response.bufferFactory().wrap(bytes) 构建响应内容,通过response.writeWith(Mono.just(buffer)); 把内容写给客户端。
spring: cloud: globalcors: #跨域配置 cors-configurations: '[/**]': allowedOrigins: "https://docs.spring.io" #允许的站点 allowedMethods: #允许的请求方式 - GET - POST - DELETE - PUT - HEAD - CONNECT - TRACE - OPTIONS allowHeaders: #允许的请求头 - Content-Type
全局超时 spring: cloud: gateway: httpclient: connect-timeout: 1000 response-timeout: 5s 指定路由超时配置 spring: cloud: gateway: routes: - id: per_route_timeouts uri: https://example.org predicates: - name: Path args: pattern: /delay/{timeout} metadata: response-timeout: 200 connect-timeout: 200
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。