SpringCloudgateway原理与配置详解史上最全
前⾔
疯狂创客圈(笔者尼恩创建的⾼并发研习社)Springcloud ⾼并发系列⽂章,将为⼤家介绍三个版本的⾼并发秒杀:
⼀、
⼆、版本2 :springcloud + redis 分布式锁秒杀
三、版本3 :springcloud + Nginx + Lua ⾼性能版本秒杀
以及有关Springcloud ⼏篇重要⽂章:
⼀、
⼆、
三、
这是《SpringCloud gateway 详解》篇,为⼤家解读如果做到使⽤SpringCloud gateway 。
1.1 SpringCloud Gateway 简介
SpringCloud Gateway 是 Spring Cloud 的⼀个全新项⽬,该项⽬是基于 Spring 5.0,Spring Boot 2.0 和 Project Reactor 等技术开发的⽹关,它旨在为微服务架构提供⼀种简单有效的统⼀的 API 路由管理⽅式。
SpringCloud Gateway 作为 Spring Cloud ⽣态系统中的⽹关,⽬标是替代 Zuul,在Spring Cloud 2.0以上版本中,没有对新版本的Zuul 2.0以上最新⾼性能版本进⾏集成,仍然还是使⽤的Zuul 2.0之前的⾮Reactor模式的⽼版本。⽽为了提升⽹关的性能,SpringCloud Gateway是基于WebFlux框架实现的,⽽WebFlux框架底层则使⽤了⾼性能的Reactor模式通信框架Netty。
Spring Cloud Gateway 的⽬标,不仅提供统⼀的路由⽅式,并且基于 Filter 链的⽅式提供了⽹关基本的功能,例如:安全,监控/指标,和限流。
提前声明:Spring Cloud Gateway 底层使⽤了⾼性能的通信框架Netty。
1.2 SpringCloud Gateway 特征
SpringCloud官⽅,对SpringCloud Gateway 特征介绍如下:
(1)基于 Spring Framework 5,Project Reactor 和 Spring Boot 2.0
(2)集成 Hystrix 断路器
(3)集成 Spring Cloud DiscoveryClient
(4)Predicates 和 Filters 作⽤于特定路由,易于编写的 Predicates 和 Filters
(5)具备⼀些⽹关的⾼级功能:动态路由、限流、路径重写
从以上的特征来说,和Zuul的特征差别不⼤。SpringCloud Gateway和Zuul主要的区别,还是在底层的通信框架上。
简单说明⼀下上⽂中的三个术语:
(1)Filter(过滤器):
和Zuul的过滤器在概念上类似,可以使⽤它拦截和修改请求,并且对上游的响应,进⾏⼆次处理。过滤器为
org.springframework.cloud.gateway.filter.GatewayFilter类的实例。
(2)Route(路由):
⽹关配置的基本组成模块,和Zuul的路由配置模块类似。⼀个Route模块由⼀个 ID,⼀个⽬标 URI,⼀组断⾔和⼀组过滤器定义。如果断⾔为真,则路由匹配,⽬标URI会被访问。
(3)Predicate(断⾔):
这是⼀个 Java 8 的 Predicate,可以使⽤它来匹配来⾃ HTTP 请求的任何内容,例如 headers 或参数。断⾔的输⼊类型是⼀个ServerWebExchange。
1.3 SpringCloud Gateway和架构
Spring在2017年下半年迎来了Webflux,Webflux的出现填补了Spring在响应式编程上的空⽩,Webflux的响应式编程不仅仅是编程风格的改变,⽽且对于⼀系列的著名框架,都提供了响应式访问的开发包,⽐如Netty、Redis等等。
SpringCloud Gateway 使⽤的Webflux中的reactor-netty响应式编程组件,底层使⽤了Netty通讯框架。
1.3.1 SpringCloud Zuul的IO模型
Springcloud中所集成的Zuul版本,采⽤的是Tomcat容器,使⽤的是传统的Servlet IO处理模型。
⼤家知道,servlet由servlet container进⾏⽣命周期管理。container启动时构造servlet对象并调⽤servlet init()进⾏初始化;container 关闭时调⽤servlet destory()销毁servlet;container运⾏时接受请求,并为每个请求分配⼀个线程(⼀般从线程池中获取空闲线程)然后调⽤service()。
弊端:servlet是⼀个简单的⽹络IO模型,当请求进⼊servlet container时,servlet container就会为其绑
定⼀个线程,在并发不⾼的场景下这种模型是适⽤的,但是⼀旦并发上升,线程数量就会上涨,⽽线程资源代价是昂贵的(上线⽂切换,内存消耗⼤)严重影响请求的处理时间。在⼀些简单的业务场景下,不希望为每个request分配⼀个线程,只需要1个或⼏个线程就能应对极⼤并发的请求,这种业务场景下servlet模型没有优势。
所以Springcloud Zuul 是基于servlet之上的⼀个阻塞式处理模型,即spring实现了处理所有request请求的⼀个
servlet(DispatcherServlet),并由该servlet阻塞式处理处理。所以Springcloud Zuul⽆法摆脱servlet模型的弊端。虽然Zuul 2.0开始,使⽤了Netty,并且已经有了⼤规模Zuul 2.0集部署的成熟案例,但是,Springcloud官⽅已经没有集成改版本的计划了。
nginx和网关怎么配合使用
1.3.2 Webflux模型
Webflux模式替换了旧的Servlet线程模型。⽤少量的线程处理request和response io操作,这些线程称为Loop线程,⽽业务交给响应式编程框架处理,响应式编程是⾮常灵活的,⽤户可以将业务中阻塞的操作提交到响应式框架的work线程中执⾏,⽽不阻塞的操作依然可以在Loop线程中进⾏处理,⼤⼤提⾼了Loop线程的利⽤率。官⽅结构图:
Webflux虽然可以兼容多个底层的通信框架,但是⼀般情况下,底层使⽤的还是Netty,毕竟,Netty是⽬前业界认可的最⾼性能的通信框架。⽽Webflux的Loop线程,正好就是著名的Reactor 模式IO处理模
型的Reactor线程,如果使⽤的是⾼性能的通信框架Netty,这就是Netty的EventLoop线程。
关于Reactor线程模型,和Netty通信框架的知识,是Java程序员的重要、必备的内功,个中的原理,具体请参见尼恩编著的《Netty、Zookeeper、Redis⾼并发实战》⼀书,这⾥不做过多的赘述。
1.3.3 Spring Cloud Gateway的处理流程
客户端向 Spring Cloud Gateway 发出请求。然后在 Gateway Handler Mapping 中到与请求相匹配的路由,将其发送到 Gateway Web Handler。Handler 再通过指定的过滤器链来将请求发送到我们实际的服务执⾏业务逻辑,然后返回。过滤器之间⽤虚线分开是因为过滤器可能会在发送代理请求之前(“pre”)或之后(“post”)执⾏业务逻辑。
1.4 Spring Cloud Gateway路由配置⽅式
1.4.1 基础URI⼀种路由配置⽅式
如果请求的⽬标地址,是单个的URI资源路径,配置⽂件⽰例如下:
application:
name: api-gateway
cloud:
gateway:
routes:
- id: url-proxy-1
uri: blog.csdn
predicates:
-
Path=/csdn
各字段含义如下:
id:我们⾃定义的路由 ID,保持唯⼀
uri:⽬标服务地址
predicates:路由条件,Predicate 接受⼀个输⼊参数,返回⼀个布尔值结果。该接⼝包含多种默认⽅法来将 Predicate 组合成其他复杂的逻辑(⽐如:与,或,⾮)。
1.4.2 基于代码的路由配置⽅式
转发功能同样可以通过代码来实现,我们可以在启动类 GateWayApplication 中添加⽅法 customRouteLocator() 来定制转发规则。package com.springcloud.gateway;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.ute.RouteLocator;
import org.springframework.ute.builder.RouteLocatorBuilder;
import t.annotation.Bean;
@SpringBootApplication
public class GatewayApplication {
public static void main(String[] args) {
SpringApplication.run(GatewayApplication.class, args);
}
@Bean
public RouteLocator customRouteLocator(RouteLocatorBuilder builder) {
utes()
.route("path_route", r -> r.path("/csdn")
.
uri("blog.csdn"))
.build();
}
}
上⾯两个⽰例中 uri 都是指向了我的CSDN博客,在实际项⽬使⽤中可以将 uri 指向对外提供服务的项⽬地址,统⼀对外输出接⼝。
1.4.3 和注册中⼼相结合的路由配置⽅式
在uri的schema协议部分为⾃定义的lb:类型,表⽰从微服务注册中⼼(如Eureka)订阅服务,并且进⾏服务的路由。
⼀个典型的⽰例如下:
cloud:
gateway:
routes:
- id: seckill-provider-route
uri: lb://seckill-provider
predicates:
- Path=/seckill-provider/**
- id: message-provider-route
uri: lb://message-provider
predicates:
- Path=/message-provider/**
application:
name: cloud-gateway
eureka:
instance:
prefer-ip-address: true
client:
service-url:
defaultZone: localhost:8888/eureka/
注册中⼼相结合的路由配置⽅式,与单个URI的路由配置,区别其实很⼩,仅仅在于URI的schema协议不同。单个URI的地址的schema协议,⼀般为http或者https协议。
1.5 详解:SpringCloud Gateway 匹配规则
Spring Cloud Gateway 的功能很强⼤,我们仅仅通过 Predicates 的设计就可以看出来,前⾯我们只是使⽤了 predicates 进⾏了简单的条件匹配,其实 Spring Cloud Gataway 帮我们内置了很多 Predicates 功能。
Spring Cloud Gateway 是通过 Spring WebFlux 的 HandlerMapping 做为底层⽀持来匹配到转发路由,Spring Cloud Gateway 内置了很多 Predicates ⼯⼚,这些 Predicates ⼯⼚通过不同的 HTTP 请求参数来匹配,多个 Predicates ⼯⼚可以组合使⽤。
1.5.1 Predicate 断⾔条件介绍
Predicate 来源于 Java 8,是 Java 8 中引⼊的⼀个函数,Predicate 接受⼀个输⼊参数,返回⼀个布尔值结果。该接⼝包含多种默认⽅法来将 Predicate 组合成其他复杂的逻辑(⽐如:与,或,⾮)。可以⽤于接⼝请求参数校验、判断新⽼数据是否有变化需要进⾏更新操作。
在 Spring Cloud Gateway 中 Spring 利⽤ Predicate 的特性实现了各种路由匹配规则,有通过 Header、请求参数等不同的条件来进⾏作为条件匹配到对应的路由。⽹上有⼀张图总结了 Spring Cloud 内置的⼏种 Predicate 的实现。
[
说⽩了 Predicate 就是为了实现⼀组匹配规则,⽅便让请求过来到对应的 Route 进⾏处理,接下来我们接下 Spring Cloud GateWay 内置⼏种 Predicate 的使⽤。
1.5.2 通过请求参数匹配
Query Route Predicate ⽀持传⼊两个参数,⼀个是属性名⼀个为属性值,属性值可以是正则表达式。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。