1. 为什么抛弃Zuul,选择Gateway
2. Spring Cloud Gateway是什么,有什么优点,有哪些核心概念
SpringCloud Gateway是基于WebFlux框架实现的,而WebFlux框架底层则使用了高性能的Reactor模式通信框架Netty。
核心概念:
Route(路由):这是网关的基本构建块。它由一个 ID,一个目标 URI,一组断言和一组过滤器定义。如果断言为真,则路由匹配,目标URI会被访问。
Predicate(断言):这是一个 Java 8 的 Predicate。输入类型是一个 ServerWebExchange。我们可以使用它来匹配来自 HTTP 请求的任何内容,例如 headers 或参数。
Filter(过滤器):这是org.springframework.cloud.gateway.filter.GatewayFilter的实例,我们可以使用它拦截和修改请求,并且对上文的响应,进行再处理。
filter在请求之前可以做参数校验,权限校验,流量监控,日志输出,协议转换等等
filter在请求之后可以做响应内容、响应头的修改,日志输出,流量监控等
特性:
基于Spring Framework 5、Project Reactor和Spring Boot 2.0构建
能够在任意请求属性上匹配路由
predicates(谓词) 和 filters(过滤器)是特定于路由的
集成了Hystrix断路器
集成了Spring Cloud DiscoveryClient
易于编写谓词和过滤器
请求速率限制
路径重写
3. Spring Cloud Gateway的路由配置文件如何配置
1. 配置文件做路由配置
server: port: 8080 spring: application: name: api-gateway cloud: gateway: routes: - id: url-api-gateway uri: https://www.baidu.com predicates: - Path=/toBaidu
routes 是一个数组格式,每一个route包含一个id、uri、断言组合predicates
上面配置的含义是:配置了一个 id 为 url-api-gateway 的URI代理规则,路由的规则为:当访问地址http://localhost:8080/toBaidu时,会路由到上游地址https://www.baidu.com
2. 代码配置做路由配置
@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class}) @ImportResource("classpath:context.xml") public class SuperHeroApplication { public static void main(String[] args) { // System.setProperty("spring.devtools.restart.enabled", "false"); SpringApplication.run(SuperHeroApplication.class, args); } @Bean public RouteLocator customRouteLocator(RouteLocatorBuilder builder) { return builder.routes() .route("url-api-gateway", r -> r.path("/toBaidu") .uri("https://www.baidu.com")) .build(); } }
通过@Bean配置RouteLocator路由定位器,只要调用route绑定id和断言器,uri绑定路由到目标
上面两种路由方式:都是传统的路由方式,即路由目标是指定uri,实际在微服务中更多的SpringCloud Gateway结合SpringCloud Eureka基于服务发现完成服务路由
实际基于服务发现的路由配置也很简单
配置uri:lb://gateway-service 其中lb协议就表示基于Eureka服务发现的服务路由模式,即从Eureka发现gateway-service微服务,并且能够自动负载均衡转发过去的
4. Spring Cloud Gateway 服务路由配置规则
每一个Predicate的使用,你可以理解为:当满足这种条件后才会被转发,如果是多个,那就是都满足的情况下被转发。
spring: cloud: gateway: routes: - id: time_route uri: http://ityouknow.com predicates: - After=2018-01-20T06:06:06+08:00[Asia/Shanghai] - Before=2018-01-20T06:06:06+08:00[Asia/Shanghai] - Between=2018-01-20T06:06:06+08:00[Asia/Shanghai], 2019-01-20T06:06:06+08:00[Asia/Shanghai] - Cookie=ityouknow, kee.e - Header=X-Request-Id, \d+ - Host=**.ityouknow.com - Method=GET - Path=/foo/{segment} - Query=smile - Query=keep, pu. - RemoteAddr=192.168.1.1/24
基于时间匹配 After、Before、Between
基于Cookie匹配 Cookie
基于请求头匹配 Header
基于主题匹配 Host
基于请求方式匹配 Method
基于请求路径匹配 Path
基于请求参数匹配 Query
基于IP地址匹配 RemoteAddr
各种 Predicates 同时存在于同一个路由时,请求必须同时满足所有的条件才被这个路由匹配。
一个请求满足多个路由的谓词条件时,请求只会被首个成功匹配的路由转发
5. SpringCloud Gateway的熔断机制如何配置
Spring Cloud Gateway 也可以利用 Hystrix 的熔断特性,在流量过大时进行服务降级,同样我们还是首先给项目添加上依赖。
spring-cloud-starter-netflix-hystrix
spring: cloud: gateway: routes: - id: hystrix_route uri: lb://spring-cloud-producer predicates: - Path=/consumingserviceendpoint filters: - name: Hystrix args: name: fallbackcmd fallbackUri: forward:/incaseoffailureusethis
6. SpringCloud Gateway 重试机制如何的
首先,我们要知道我们为什么要使用重试机制,通常我们在调用服务的时候,总是会不可避免的遇到像网络波动或是别的某种原因导致服务调用失败。
这个时候我们就会想要重新访问服务,这里我们就用到了重试机制。但是我们也不能滥用重试机制,比如如果我们写数据的时候使用重试机制就要分外小心了,必须做好接口的幂等性,防止数据重复写入库中。而且大量的重试机制势必会导致请求量增加,给系统的压力增大,所以我们设置合理的重试次数也是至关重要的。
下面我们来讲讲Spring Cloud Gateway中的重试机制和使用。我们来看下@GatewayAutoConfiguration,根据类名我们知道他是Gateway的自动装配类
7. SpringCloud Gateway 限流机制如何的
Spring Cloud Gateway使用Redis+Lua技术实现高并发和高性能的限流方案。
note:lb://gateway-service 表示服务发现的方式哦
一种常见的限流配置
server: port: 8099 spring: application: name: gateway-frame cloud: gateway: discovery: locator: enabled: true # 服务名小写 lower-case-service-id: true routes: - id: gateway-service # lb代表从注册中心获取服务,且已负载均衡方式转发 uri: lb://gateway-service predicates: - Path=/service/** # 限流filter配置 filters: - name: RequestRateLimiter args: key-resolver: '#{@uriKeyResolver}' redis-rate-limiter.replenishRate: 300 redis-rate-limiter.burstCapacity: 300 redis: host: xxxxxxx port: 6379 password: xxxxxx database: 0 # 注册中心 eureka: instance: prefer-ip-address: true client: service-url: defaultZone: http://xxxxxxx:8761/eureka/
1、引入filte的配置-name: RequestRateLimiter,这个是使用已经实现好的RequestRateLimiterGatewayFilterFactory类进行限流;
2、key-resolver:用于获取限流维度的实现类,可以根据ip、uri、设备号、用户id等进行限流,这里使用的uriKeyResolver对应实现使用uri限流的类;
3、redis-rate-limiter.burstCapacity:令牌桶容量,就是每一秒向令牌桶中发放的令牌数量,能够同时有多少个访问请求;
4、redis-rate-limiter.replenishRate:令牌桶每秒的填充量;
5、因为限流类依赖于redis进行统计数据的存储,所以这里要加上redis的连接配置;
8. SpringCloud Gateway 过滤器详解有哪些
Spring Cloud Gateway的filter生命周期只有两个:“pre”和“post”。
pre:在请求被路由之前调用。可以利用这个过滤器实现身份验证、在集群中选择请求的微服务、记录调试的信息。
post:在路由到服务器之后执行。这种过滤器可用来为响应添加HTTP Header、统计信息和指标、响应从微服务发送给客户端等。
Spring Cloud gateway的filter分为两种:GatewayFilter和Globalfilter。
GlobalFilter 会应用到所有的路由上
Gatewayfilter将应用到单个路由或者一个分组的路由上。可以修改请求的http的请求或者是响应,或者根据请求或者响应做一些特殊的限制
GatewayFilter
自定义 GatewayFilter自定义Gateway 过滤器工厂需要继承 AbstractGatewayFilterFactory 类,重写 apply 方法的逻辑。命名需要以 GatewayFilterFactory 结尾。
GlobalFilter
ForwardRoutingFilter 转发路由过滤器:
LoadBalancerClientFilter 负载均衡客户端过滤器:LoadBalancerClientFilter 在交换属性 GATEWAY_ REQUEST_ URL_ ATTR 中查找URL, 如果URL有一个 lb 前缀 ,例如 lb:// myservice,将使用 LoadBalancerClient 将微服务名称myservice通过Eureka提供的服务发现+负载均衡解析为实际的主机和端口。