SpringCloud Gateway是基于WebFlux框架实现的,而WebFlux框架底层则应用了高性能的Reactor模式通信框架Netty。
Cloud全家桶中有个很重要的组件就是网关,在1.x版本中都是采纳的Zuul网关;
但在2.x版本中,zuul的降级始终跳票,SpringCloud最初本人研发了一个网关代替Zuul,那就是SpringCloud Gateway—句话:gateway是原zuul1.x版的代替

Gateway是在Spring生态系统之上构建的API网关服务,基于Spring 5,Spring Boot 2和Project Reactor等技术。
Gateway旨在提供一种简略而无效的形式来对API进行路由,以及提供一些弱小的过滤器性能,例如:熔断、限流、重试等。
SpringCloud Gateway是Spring Cloud的一个全新我的项目,基于Spring 5.0+Spring Boot 2.0和Project Reactor等技术开发的网关,它旨在为微服务架构提供—种简略无效的对立的API路由治理形式。
SpringCloud Gateway作为Spring Cloud 生态系统中的网关,指标是代替Zuul,在Spring Cloud 2.0以上版本中,没有对新版本的Zul 2.0以上最新高性能版本进行集成,依然还是应用的Zuul 1.x非Reactor模式的老版本。而为了晋升网关的性能,SpringCloud Gateway是基于WebFlux框架实现的,而WebFlux框架底层则应用了高性能的Reactor模式通信框架Netty。
Spring Cloud Gateway的指标提供对立的路由形式且基于 Filter链的形式提供了网关根本的性能,例如:平安,监控/指标,和限流。
3、为什么抉择Gateway?
Gateway的个性

基于Spring Framework 5,Project Reactor和Spring Boot 2.0进行构建;
动静路由:可能匹配任何申请属性;
能够对路由指定Predicate (断言)和Filter(过滤器);
集成Hystrix的断路器性能;
集成Spring Cloud 服务发现性能;
易于编写的Predicate (断言)和Filter (过滤器);
申请限流性能;
反对门路重写。

SpringCloud Gateway与Zuul的区别

在SpringCloud Finchley正式版之前,Spring Cloud举荐的网关是Netflix提供的Zuul。
Zuul 1.x,是一个基于阻塞I/O的API Gateway。
Zuul 1.x基于Servlet 2.5应用阻塞架构它不反对任何长连贯(如WebSocket)Zuul的设计模式和Nginx较像,每次I/操作都是从工作线程中抉择一个执行,申请线程被阻塞到工作线程实现,然而差异是Nginx用C++实现,Zuul用Java实现,而JVM自身会有第-次加载较慢的状况,使得Zuul的性能绝对较差。
Zuul 2.x理念更先进,想基于Netty非阻塞和反对长连贯,但SpringCloud目前还没有整合。Zuul .x的性能较Zuul 1.x有较大晋升。在性能方面,依据官网提供的基准测试,Spring Cloud Gateway的RPS(每秒申请数)是Zuul的1.6倍。
Spring Cloud Gateway建设在Spring Framework 5、Project Reactor和Spring Boot2之上,应用非阻塞API。
Spring Cloud Gateway还反对WebSocket,并且与Spring严密集成领有更好的开发体验

http://www.bilibili.com/media...
http://www.bilibili.com/media...
http://www.bilibili.com/media...
http://www.bilibili.com/media...
http://www.bilibili.com/media...
http://www.thinksaas.cn/user/...
二、三大外围概念
1、三大概念

Route(路由) : 路由是构建网关的根本模块,它由ID,指标URI,一系列的断言和过滤器组成,如断言为true则匹配该路由;
Predicate(断言) : 参考的是Java8的java.util.function.Predicate,开发人员能够匹配HTTP申请中的所有内容(例如申请头或申请参数),如果申请与断言相匹配则进行路由;
Filter(过滤) :指的是Spring框架中GatewayFilter的实例,应用过滤器,能够在申请被路由前或者之后对申请进行批改。

2、Gateway的工作流程

客户端向Spring Cloud Gateway发出请求。而后在Gateway Handler Mapping 中找到与申请相匹配的路由,将其发送到GatewayWeb Handler。
Handler再通过指定的过滤器链来将申请发送到咱们理论的服务执行业务逻辑,而后返回。
过滤器之间用虚线离开是因为过滤器可能会在发送代理申请之前(“pre”)或之后(“post")执行业务逻辑。
三、Gateway配置
1、环境
新建模块:cloud-gateway-gateway9527
pom:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"

     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"     xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><parent>    <artifactId>cloud2021</artifactId>    <groupId>com.atguigu</groupId>    <version>1.0.0-SNAPSHOT</version></parent><modelVersion>4.0.0</modelVersion><groupId>com.atguigu.springcloud</groupId><artifactId>cloud-gateway-gateway9527</artifactId><dependencies>    <!--gateway-->    <dependency>        <groupId>org.springframework.cloud</groupId>        <artifactId>spring-cloud-starter-gateway</artifactId>    </dependency>    <!--eureka-client-->    <dependency>        <groupId>org.springframework.cloud</groupId>        <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>    </dependency>    <!-- 引入本人定义的api通用包,能够应用Payment领取Entity -->    <dependency>        <groupId>com.atguigu.springcloud</groupId>        <artifactId>cloud-api-commons</artifactId>        <version>${project.version}</version>    </dependency>    <!--个别根底配置类-->    <dependency>        <groupId>org.springframework.boot</groupId>        <artifactId>spring-boot-devtools</artifactId>        <scope>runtime</scope>        <optional>true</optional>    </dependency>    <dependency>        <groupId>org.projectlombok</groupId>        <artifactId>lombok</artifactId>        <optional>true</optional>    </dependency>    <dependency>        <groupId>org.springframework.boot</groupId>        <artifactId>spring-boot-starter-test</artifactId>        <scope>test</scope>    </dependency></dependencies>

</project>
复制代码
yaml:
server:
port: 9527

spring:
application:

name: cloud-gateway

eureka:
instance:

hostname: cloud-gateway-service

client: #服务提供者provider注册进eureka服务列表内

service-url:  register-with-eureka: true  fetch-registry: true  defaultZone: http://eureka7001.com:7001/eureka

复制代码
主启动类:
@SpringBootApplication
@EnableEurekaClient
public class GateWayMain9527
{

public static void main(String[] args) {    SpringApplication.run(GateWayMain9527.class, args);}

}
复制代码
业务类:无
2、gateway配置
为了保障能够路由跳转,加上如下代码:
server:
port: 9527

spring:
application:

name: cloud-gateway

#############################新增网关配置###########################
cloud:

gateway:  routes:    - id: payment_routh #payment_route    #路由的ID,没有固定规定但要求惟一,倡议配合服务名      uri: http://localhost:8001          #匹配后提供服务的路由地址      #uri: lb://cloud-payment-service #匹配后提供服务的路由地址      predicates:        - Path=/payment/get/**         # 断言,门路相匹配的进行路由    - id: payment_routh2 #payment_route    #路由的ID,没有固定规定但要求惟一,倡议配合服务名      uri: http://localhost:8001          #匹配后提供服务的路由地址      #uri: lb://cloud-payment-service #匹配后提供服务的路由地址      predicates:        - Path=/payment/lb/**         # 断言,门路相匹配的进行路由

eureka:
instance:

hostname: cloud-gateway-service

client: #服务提供者provider注册进eureka服务列表内

service-url:  register-with-eureka: true  fetch-registry: true  defaultZone: http://eureka7001.com:7001/eureka

复制代码
启动测试。

这回拜访http://localhost:9527/payment...就能够了。
3、编码方式配置
下面采纳yaml形式配置,当初能够应用编码方式配置。
@Configuration
public class GateWayConfig
{

@Beanpublic RouteLocator customRouteLocator(RouteLocatorBuilder routeLocatorBuilder){    RouteLocatorBuilder.Builder routes = routeLocatorBuilder.routes();    routes.route("path_route_atguigu",            r -> r.path("/guonei")                    .uri("http://news.baidu.com/guonei")).build();    return routes.build();}

}
复制代码
间接拜访http://localhost:9527/guonei
四、依据微服务名实现动静路由
这里要模仿应用gateway的形式实现动静路由,而不是ribbon了。
9527模块的yaml文件批改成这样:
server:
port: 9527

spring:
application:

name: cloud-gateway
新增网关配置

cloud:

gateway:  discovery:    locator:      enabled: true #开启从注册核心动态创建路由的性能,利用微服务名进行路由  routes:    - id: payment_routh #payment_route    #路由的ID,没有固定规定但要求惟一,倡议配合服务名      #uri: http://localhost:8001          #匹配后提供服务的路由地址      uri: lb://cloud-payment-service #匹配后提供服务的路由地址      predicates:        - Path=/payment/get/**         # 断言,门路相匹配的进行路由    - id: payment_routh2 #payment_route    #路由的ID,没有固定规定但要求惟一,倡议配合服务名      #uri: http://localhost:8001          #匹配后提供服务的路由地址      uri: lb://cloud-payment-service #匹配后提供服务的路由地址      predicates:        - Path=/payment/lb/**         # 断言,门路相匹配的进行路由

eureka:
instance:

hostname: cloud-gateway-service

client: #服务提供者provider注册进eureka服务列表内

service-url:  register-with-eureka: true  fetch-registry: true  defaultZone: http://eureka7001.com:7001/eureka

复制代码
启动测试:localhost:9527/payment/lb,发现的确实现了轮询操作
五、Predicate的应用
9527启动后,发现后盾呈现了这些

进入gateway官网(下面有),发现一共有11种Predicate

Predicate是什么

Spring Cloud Gateway将路由匹配作为Spring WebFlux HandlerMapping基础架构的一部分。
Spring Cloud Gateway包含许多内置的Route Predicate工厂。所有这些Predicate都与HTTP申请的不同属性匹配。多个Route Predicate工厂能够进行组合。
Spring Cloud Gateway创立Route 对象时,应用RoutePredicateFactory 创立 Predicate对象,Predicate 对象能够赋值给Route。Spring Cloud Gateway蕴含许多内置的Route Predicate Factories。
所有这些谓词都匹配HTTP申请的不同属性。多种谓词工厂能够组合,并通过逻辑and。
After Route Predicate Factory的应用
依照官网的说法:

在yaml文件底下加上一行即可,然而要批改成中国工夫:
测试,发现这样能够获取到下面格局的工夫:
public class T2 {

public static void main(String[] args) {    ZonedDateTime zbj = ZonedDateTime.now();    System.out.println(zbj);}

}

//输入
//2021-11-23T10:44:35.485+08:00[Asia/Shanghai]
复制代码
那么批改一下:
routes:

- id: payment_routh #payment_route    #路由的ID,没有固定规定但要求惟一,倡议配合服务名  #uri: http://localhost:8001          #匹配后提供服务的路由地址  uri: lb://cloud-payment-service #匹配后提供服务的路由地址  predicates:    - Path=/payment/lb/**     - After=2021-11-23T10:44:35.485+08:00[Asia/Shanghai]

复制代码
而后这样就代表下面这个路由只有在某某工夫之后能力应用,当初把下面after的工夫批改一下,再启动测试发现报错了,阐明的确失效了,这种有点相似秒杀场景、或者我的项目定时上线都能够采纳这种形式。

Cookie Route Predicate的应用
就是要求带不带cookie,或者带哪种cookie。
Cookie Route Predicate须要两个参数,一个是cookie name,一个是正则表达式。路由的规定会通过正则表达式与cookie进行匹配。

  • id: payment_routh2 #payment_route #路由的ID,没有固定规定但要求惟一,倡议配合服务名

    uri: http://localhost:8001 #匹配后提供服务的路由地址

    uri: lb://cloud-payment-service #匹配后提供服务的路由地址
    predicates:

    • Path=/payment/lb/** # 断言,门路相匹配的进行路由
    • After=2021-11-23T10:44:35.485+08:00[Asia/Shanghai]
    • Cookie=username, James

    复制代码
    这里采纳curl的形式发送申请:

其余的依照官网去写即可。
六、Filter的应用
路由过滤器可用于批改进入的HTTP申请和返回的HTTP响应,路由过滤器只能指定路由进行应用。Spring Cloud Gateway内置了多种路由过滤器,他们都由GatewayFilter的工厂类来产生。
过滤器个别只有两种:

GatewayFilter
GlobalFilter

自定义全局过滤器
过滤器太多了,要学也很麻烦,这里实现自定义过滤器,举个例子同时也更加通用,需要的话本人配即可:
创立个包filter,而后创立filter的类,须要实现两个接口:GlobalFilter、Ordered:
@Component
@Slf4j
public class MyLogGateWayFilter implements GlobalFilter,Ordered
{

@Overridepublic Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain){    log.info("***********come in MyLogGateWayFilter:  "+new Date());    String uname = exchange.getRequest().getQueryParams().getFirst("uname");    if(uname == null)    {        log.info("*******用户名为null,非法用户,o(╥﹏╥)o");        exchange.getResponse().setStatusCode(HttpStatus.NOT_ACCEPTABLE);        return exchange.getResponse().setComplete();    }    return chain.filter(exchange);}@Overridepublic int getOrder(){    return 0;}

}