Gateway是什么?

springCloud GateWay是基于WebFlux框架实现的,底层是Netty。

SpringCloud GatewWay提供统一路由方式 基于Filter的方式提供了网关的基本功能。例如安全,性能,监控等。

Zuul是基于Sevelet2.5阻塞模型,GateWay是非阻塞模型

属于spring家族,能更好的与springCloud进行整合

路由三大核心概念 路由 断言 过滤器

路由 由id 目标url 一系列断言和过滤器组成,断言为true则路由匹配

断言 开发人员可以匹配HTTP请求中的所有内容(请求头,请求参数等),断言匹配则进行路由

过滤器 指的是spring框架中GateWayFilter实例,可以在请求路由之前或者之后队请求进行修改

过滤器 preFilter可以做参数校验 流量控制 权限校验 日志输出 协议转换等

postFilter可以做响应内容,响应头的修改,流量监控等

下面进入编码

新建 CloudGateWay9527模块

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.liuxu</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>cloud-gateway-9527</artifactId>
    <dependencies>
        <!--引入comm工程-->
        <dependency>
            <groupId>com.liuxu</groupId>
            <artifactId>cloud-commons</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
        <!--eurekaClient-->
        <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>
        <!--<!–springboot 必须有的  –>  gateWay项目 不需要引入web相关
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!–图像化显示相关–>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>-->
        <!--热启动-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
        </dependency>
    </dependencies>



</project>


主启动类


package com.liuxu;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;

/**
 * @author liuxu
 * @date 2021/11/1 21:31
 */
@EnableEurekaClient
@EnableDiscoveryClient
@SpringBootApplication
public class GateWay9527 {
    public static void main(String[] args) {
        SpringApplication.run(GateWay9527.class,args);
    }
}


配置yml


server:
  port: 9527 #端口号
spring:
  application:
    name: cloud-gateway #服务名
  cloud:
    gateway:
      routes:
        - id: payment_routh  #不指定,但是要求唯一
          uri: http://localhost:8001 #匹配后提供服务的地址
          predicates:
            - Path=/provider/** 断言 以/provider/开头的请求路径的所有请求

eureka:
  client:
   # 是否从Eureka抓取注册信息 单节点情况下无用 集群情况下才能配合robbion使用负载均衡
    fetch-registry: true
    # 注册如Eureka 用  true
    register-with-eureka: true
    service-url:
      # 设置与eureka server交互的地址查询和注册服务都需要这个地址 向注册中心注册
      defaultZone: http://localhost:7001/eureka/


启动注册中心 7001 网关 9527 服务提供方 8001

访问http://localhost:9527/provider/ok

可以通过网关访问到8001

spring gateway 接口超时的设计 spring gateway 会话保持_spring

上面是通过网关访问8001 的真实地址

还可以通过服务名进行动态路由

在启动服务提供方8002

配置开启动态路由


server:
  port: 9527 #端口号
spring:
  application:
    name: cloud-gateway #服务名
  cloud:
    gateway:
      discovery:
        locator:
          enabled: true # 开启动态路由
      routes:
        - id: payment_routh1  #不指定,但是要求唯一
          uri: http://localhost:8001 #匹配后提供服务的地址 固定路由
          predicates:
            - Path=/provider/**
        - id: payment_routh2  #不指定,但是要求唯一
          uri: lb://cloud-provider #匹配后提供服务的地址 动态路由
          predicates:
            - Path=/provider/**


eureka:
  client:
   # 是否从Eureka抓取注册信息 单节点情况下无用 集群情况下才能配合robbion使用负载均衡
    fetch-registry: true
    # 注册如Eureka 用  true
    register-with-eureka: true
    service-url:
      # 设置与eureka server交互的地址查询和注册服务都需要这个地址 向注册中心注册
      defaultZone: http://localhost:7001/eureka/


重启9527

发现访问http://localhost:9527/provider/port返回值一直是8001

因为上面配置相同的路由规则 ,优先访问最靠前 最精确的路由

修改配置如下


server:
  port: 9527 #端口号
spring:
  application:
    name: cloud-gateway #服务名
  cloud:
    gateway:
      discovery:
        locator:
          enabled: true # 开启动态路由
      routes:
        #- id: payment_routh1  #不指定,但是要求唯一
          #uri: http://localhost:8001 #匹配后提供服务的地址 固定路由
          #predicates:
            #- Path=/provider/**
        - id: payment_routh2  #不指定,但是要求唯一
          uri: lb://cloud-provider #匹配后提供服务的地址 动态路由
          predicates:
            - Path=/provider/**


eureka:
  client:
   # 是否从Eureka抓取注册信息 单节点情况下无用 集群情况下才能配合robbion使用负载均衡
    fetch-registry: true
    # 注册如Eureka 用  true
    register-with-eureka: true
    service-url:
      # 设置与eureka server交互的地址查询和注册服务都需要这个地址 向注册中心注册
      defaultZone: http://localhost:7001/eureka/


http://localhost:9527/provider/port可以轮询访问8001 8002

下面介绍常用断言

常用断言有以下几种

spring gateway 接口超时的设计 spring gateway 会话保持_ide_02

下面演示CookieRoutePredicate


server:
  port: 9527 #端口号
spring:
  application:
    name: cloud-gateway #服务名
  cloud:
    gateway:
      discovery:
        locator:
          enabled: true # 开启动态路由
      routes:
        #- id: payment_routh1  #不指定,但是要求唯一
          #uri: http://localhost:8001 #匹配后提供服务的地址 固定路由
          #predicates:
            #- Path=/provider/**
        - id: payment_routh2  #不指定,但是要求唯一
          uri: lb://cloud-provider #匹配后提供服务的地址 动态路由
          predicates:
            - Path=/provider/**
            - Cookie=username,zhangsan #cookie断言


eureka:
  client:
   # 是否从Eureka抓取注册信息 单节点情况下无用 集群情况下才能配合robbion使用负载均衡
    fetch-registry: true
    # 注册如Eureka 用  true
    register-with-eureka: true
    service-url:
      # 设置与eureka server交互的地址查询和注册服务都需要这个地址 向注册中心注册
      defaultZone: http://localhost:7001/eureka/


spring gateway 接口超时的设计 spring gateway 会话保持_ide_03

这时候访问port端口会报错

带上cookie会正常返回

spring gateway 接口超时的设计 spring gateway 会话保持_intellij-idea_04

GateWay的过滤器按生命周期可以分为两种 pre 和post

按照类型分GlobaFilter 和 GateWayFilter

可以在配置文件中配置

也可以实现 GlobaFilter 进行自定义规则(常用

首先去除Cookie断言,然后编写全局权限校验


package com.liuxu.filter;

import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.PathContainer;
import org.springframework.http.server.RequestPath;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

/**
 * @author liuxu
 * @date 2020/7/8 14:19
 */
@Component
public class MyLogGateWayFilter implements GlobalFilter, Ordered {
    /**
     * 全局过滤器过滤器接口
     * @param exchange
     * @param chain
     * @return
     */
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        System.out.println(exchange);
        String username =  exchange.getRequest().getQueryParams().getFirst("username");
       if(username==null){
           System.out.println("*****************用户名非法");
           exchange.getResponse().setStatusCode(HttpStatus.NOT_ACCEPTABLE);
           ServerHttpResponse response = exchange.getResponse();
           return exchange.getResponse().setComplete();
       }
       //通过
        return chain.filter(exchange);
    }

    /**
     * 过滤器顺序
     * @return
     */
    @Override
    public int getOrder() {
        return 0;
    }
}


重启9527

访问http://localhost:9527/provider/port

spring gateway 接口超时的设计 spring gateway 会话保持_intellij-idea_05

发现系统不可用被校验

带上用户http://localhost:9527/provider/port?username=13发现通过

GateWay的使用介绍完毕