gateway的使用

什么是Spring Cloud Gateway

网关作为流量的入口,常用的功能包括路由转发,权限校验,限流等。
Spring Cloud Gateway 是Spring Cloud官方推出的第二代网关框架,定位于取代 Netflix Zuul。相比 Zuul 来说,Spring Cloud Gateway 提供更优秀的性能,更强大的有功能。
SpringCloud Gateway 是基于 Spring 5.0,Spring Boot 2.0 和 Project Reactor 等技术开发的网关。为了提升网关的性能,SpringCloud Gateway 是基于 WebFlux 框架实现的,而 WebFlux 框架底层则使用了高性能的 Reactor 模式通信框架 Netty。
Spring Cloud Gateway 是由 WebFlux 实现的响应式的 API 网关。它不能在传统的 servlet 容器中工作,也不能构建成 war 包。
Spring Cloud Gateway 旨在为微服务架构提供一种简单且有效的 API 路由的管理方式,并基于 Filter 的方式提供网关的基本功能,例如说安全认证、监控、限流等等。

官网文档:https://docs.spring.io/spring-cloud-gateway/docs/current/reference/html/#gateway-request-predicates-factories

核心概念

路由(route)

路由是网关中最基础的部分,路由信息包括一个ID、一个目的URI、一组断言工厂、一组Filter组成。如果断言为真,则说明请求的URL和配置的路由匹配。

断言(predicates)

Java8中的断言函数,SpringCloud Gateway中的断言函数类型是Spring5.0框架中的ServerWebExchange。断言函数允许开发者去定义匹配Http request中的任何信息,比如请求头和参数等。

过滤器(Filter)

SpringCloud Gateway中的filter分为Gateway FilIer和Global Filter。Filter可以对请求和响应进行处理。

工作原理

Spring Cloud Gateway 的工作原理跟 Zuul 的差不多,最大的区别就是 Gateway 的 Filter 只有 pre 和 post 两种。
在这里插入图片描述

客户端向 Spring Cloud Gateway 发出请求。
如果 Gateway Handler Mapping 找到与请求相匹配的路由,将其发送到 Gateway Web Handler。
Handler 再通过指定的 过滤器链 来将请求发送到我们实际的服务执行业务逻辑,然后返回。
过滤器之间用虚线分开是因为过滤器可能会在发送代理请求之前(“pre”)或之后(“post”)执行业务逻辑。

Spring Cloud Gateway快速开始

环境搭建

  1. 引入依赖
<!-- gateway网关 -->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>

<!-- nacos服务注册与发现 -->
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>

注意:会和spring-webmvc的依赖冲突,需要排除spring-webmvc
2) 编写yml配置文件

server:
  port: 8877

spring:
  application:
    name: ahs-gateway
  cloud:
  #  nacos注册中心
    nacos:
      discovery:
        server-addr: 127.0.0.1:8848
    gateway:
      discovery:
        locator:
          enabled: false #默认为false,设为true开启通过微服务创建路由的功能,即可以通过微服务名访问服务
          lower-case-service-id: true
      enabled: true # 是否开启网关
      routes:
        - id: ahs-user-route
          uri: lb://ash-user
          #uri: http://www.baidu.com
          predicates:
            - Path=/user/test123
          filters:
            # ??
            # ??????
            - StripPrefix=1

路由断言工厂(Route Predicate Factories)配置
官方文档:https://docs.spring.io/spring-cloud-gateway/docs/current/reference/html/#gateway-request-predicates-factories

gateway自身提供的路有断言工厂
在这里插入图片描述

时间匹配
可以用在限时抢购的一些场景中。

spring:
  cloud:
    gateway:
      routes:
      - id: after_route #全局唯一自己随便定义
        uri: https://example.org:8080 #目标微服务请求的地址和端口
        # 测试url:https://example.org:8080/test
        predicates:
       # - After=2017-01-20T17:42:47.789-07:00[America/Denver] # 美国的时区
       # 在时间之后 当然也有- Before
        - After=2017-01-20T17:42:47.789-07:00[Asia/Shanghai] # 亚洲上海市区

请求的时间必须在after配置的之后

before时间断言工厂配置

spring:
  cloud:
    gateway:
      routes:
      - id: before_route
        uri: https://example.org
        predicates:
        - Before=2017-01-20T17:42:47.789-07:00[America/Denver]

请求的时间必须在Before配置的之前

betwen断言工厂配置

spring:
  cloud:
    gateway:
      routes:
      - id: between_route
        uri: https://example.org
        predicates:
        - Between=2017-01-20T17:42:47.789-07:00[America/Denver], 2017-01-21T17:42:47.789-07:00[America/Denver]

请求的时间必须在betwen配置时间之间

Cookie断言共产匹配

spring:
  cloud:
    gateway:
      routes:
      - id: cookie_route
        uri: https://example.org
        predicates:
        - Cookie=chocolate, ch.p  # k v 健值对

就是一个键值对!请求的Cookie必须要有一个键值对chocolate:ch.p。满足我就给你访问

Header匹配
spring:
cloud:
gateway:
routes:
- id: header_route
uri: https://example.org
predicates:
# Header匹配 请求中带有请求头名为 x-request-id,其值与 \d+ 正则表达式匹配
- Header=X-Request-Id, \d+

这个路由规则匹配Header中包含X-Request-Id并且值为纯数字的请求。

主机路有断言匹配

spring:
  cloud:
    gateway:
      routes:
      - id: host_route
        uri: https://example.org
        predicates:
        - Host=**.somehost.org,**.anotherhost.org

请求http://localhost:8080 -H “Host: www.somehost.org” 可以请求通过

2.2.4 路径匹配

  routes:
    - id: provider_routh
      uri: lb://SPRINGCLOUD-PROVIDER-DEPT   #目标微服务名!而且是以负载均衡方式去获取!
      predicates:    						#断言
        - Path=/testGateWay01

请求的路中必须包含testGateWay01

Method 路由断言

routes:
- id: provider_routh
uri: lb://SPRINGCLOUD-PROVIDER-DEPT #目标微服务名!而且是以负载均衡方式去获取!
predicates: #断言
- Path=/testGateWay01
- Method=GET,POST

这个路由匹配所有的GET POST请求,并且请求的前缀是testGateWay01。

.Query 查询路由断言


      routes:
        - id: provider_routh
          uri: lb://SPRINGCLOUD-PROVIDER-DEPT   #目标微服务名!而且是以负载均衡方式去获取!
          predicates:    						#断言
            - Path=/testGateWay01
            - Query=green
            - Query=red, gree.

1.如果请求中包含green的参数,则匹配成功。
2.如果一个请求中包含参数red并且值匹配·gree.·这个正则,那么路由匹配。比如:green和greet。

2.2.5 自定义路由断言工厂
自定义路由断言工厂需要继承 AbstractRoutePredicateFactory 类,重写 apply 方法的逻辑。在 apply 方法中可以通过 exchange.getRequest() 拿到 ServerHttpRequest 对象,从而可以获取到请求的参数、请求方式、请求头等信息。
注意: 命名需要以 RoutePredicateFactory 结尾

1、 必须spring组件 bean
2、类必须加上RoutePredicateFactory作为结尾
3、必须继承AbstractRoutePredicateFactory
4、必须声明静态内部类 声明属性来接收 配置文件中对应的断言的信息
5、 需要结合shortcutFieldOrder进行绑定
6、通过apply进行逻辑判断 true就是匹配成功 false匹配失败

@Component
@Slf4j
public class CheckAuthRoutePredicateFactory extends AbstractRoutePredicateFactory<CheckAuthRoutePredicateFactory.Config> {

    public CheckAuthRoutePredicateFactory() {
        super(Config.class);
    }

    @Override
    public Predicate<ServerWebExchange> apply(Config config) {
        return new GatewayPredicate() {

            @Override
            public boolean test(ServerWebExchange serverWebExchange) {
                log.info("调用CheckAuthRoutePredicateFactory" + config.getName());
                if(config.getName().equals("www")){
                    return true;
                }
                return false;
            }
        };
    }

    /**
     * 快捷配置
     * @return
     */
    @Override
    public List<String> shortcutFieldOrder() {
        return Collections.singletonList("name");
    }

    public static class Config {

        private String name;

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }
    }
}

yml中配置

spring:
  cloud:
    gateway:
      #设置路由:路由id、路由到微服务的uri、断言
      routes:
      - id: order_route  #路由ID,全局唯一
        uri: lb://test-service  #目标微服务的请求地址和端口
        predicates:
        # 测试路径 http://localhost:8080/test123/api/change
        - Path=/test123   #Path路径匹配
        # 自定义CheckAuth断言工厂
        - CheckAuth=www   
        filters:
            - StripPrefix=1 # 转发之前去掉1层路径  变成 -> http://localhost:8080/api/change

过滤器工厂( GatewayFilter Factories

GatewayFilter是网关中提供的一种过滤器,可以对进入网关的请求和微服务返回的响应做处理

在这里插入图片描述

SpringCloudGateway 内置了很多的过滤器工厂,我们通过一些过滤器工厂可以进行一些业务逻辑处理器,比如添加剔除响应头,添加去除参数等

spring:
  cloud:
    gateway:
      routes: # 网关路由配置
        - id: user-service
          uri: lb://userservice
          predicates:
            - Path=/user/**
          filters: # 过滤器
            - AddRequestHeader=info, AddRequestHeader! # 添加请求头

userservice项目中controller中的请求方法上获取Info的内容

@RestController
@RequestMapping("/user")
public class UserController {
    @Autowired
    private UserService userService;

    @GetMapping("/{id}")
    public User queryByid(@PathVariable("id") Long id,
                          @RequestHeader(value = "Info",required = false) String info) {
        System.out.println(info);
        return userService.queryById(id);
    }
}

默认过滤器
如果要对所有的路由都生效,则可以将过滤器工厂写到default下。格式如下

spring:
    gateway:
      routes: # 网关路由配置
        - id: user-service # 路由id,自定义,只要唯一即可
          # uri: http://127.0.0.1:8081 # 路由的目标地址 http就是固定地址
          uri: lb://userservice # 路由的目标地址 lb就是负载均衡,后面跟服务名称
          predicates: # 路由断言,也就是判断请求是否符合路由规则的条件
            - Path=/user/** # 这个是按照路径匹配,只要以/user/开头就符合要求
          #filters: # 过滤器
          #  - AddRequestHeader=info, AddRequestHeader! # 添加请求头
        - id: feign-order-service
          uri: lb://feignorderservice
          predicates:
            - Path=/order/**
          filters:
          	- PrefixPath=/mall-order  # 添加前缀 对应微服务需要配置context-path
      default-filters: # 默认过滤器,会对所有的路由请求都生效
        - AddRequestHeader=Info,'default filers request header!' # 添加请求头

为匹配的路由统一添加前缀

spring:
    gateway:
      routes: # 网关路由配置
        - id: user-service # 路由id,自定义,只要唯一即可
          # uri: http://127.0.0.1:8081 # 路由的目标地址 http就是固定地址
          uri: lb://userservice # 路由的目标地址 lb就是负载均衡,后面跟服务名称
          predicates: # 路由断言,也就是判断请求是否符合路由规则的条件
            - Path=/user/** # 这个是按照路径匹配,只要以/user/开头就符合要求
        - id: feign-order-service
          uri: lb://feignorderservice
          predicates:
            - Path=/order/**
          filters:
          	- PrefixPath=/api  # 添加前缀 对应微服务需要配置context-path

对应为服务中需要票配置

server:
  servlet:
    context-path: /api

重定向操作

spring:
  cloud:
    gateway:
      #设置路由:路由id、路由到微服务的uri、断言
      routes:
      - id: user-service  #路由ID,全局唯一
        uri: lb://userservice #目标微服务的请求地址和端口
        #配置过滤器工厂
        predicates:
        - Path=/order/**
        filters:
        - RedirectTo=302, https://www.baidu.com/  #重定向到百度

自定义过滤器工厂
继承AbstractNameValueGatewayFilterFactory且我们的自定义名称必须要以GatewayFilterFactory结尾并交给spring管理。

@Component
@Slf4j
public class CheckAuthGatewayFilterFactory extends AbstractNameValueGatewayFilterFactory {

    @Override
    public GatewayFilter apply(NameValueConfig config) {
        return (exchange, chain) -> {
            log.info("调用CheckAuthGatewayFilterFactory==="
                    + config.getName() + ":" + config.getValue());
            return chain.filter(exchange);
        };
    }
}
配置自定义的过滤器工厂
spring:
  cloud:
    gateway:
      #设置路由:路由id、路由到微服务的uri、断言
      routes:
      - id: user-service  #路由ID,全局唯一
        uri: lb://userservice #目标微服务的请求地址和端口
        #配置过滤器工厂
        predicates:
        - Path=/order/**
        #配置过滤器工厂
        filters:
        - CheckAuth=www,女

全局过滤器(Global Filters)配置

GlobalFilter 接口和 GatewayFilter 有一样的接口定义,只不过, GlobalFilter 会作用于所有路由。
官方声明:GlobalFilter的接口定义以及用法在未来的版本可能会发生变化。
LoadBalancerClientFilter
LoadBalancerClientFilter 会查看exchange的属性 ‘ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR 的值(一个URI),如果该值的scheme是 lb,比如:lb://myservice ,它将会使用Spring Cloud的LoadBalancerClient 来将 myservice 解析成实际的host和port,并替换掉 ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR 的内容。
其实就是用来整合负载均衡器Ribbon的

需求:定义全局过滤器,拦截请求,判断请求的参数是否满足下面条件:
参数中是否有authorization,
authorization参数值是否为admin
如果同时满足则放行,否则拦截

自定义全局过滤器

/@Order(-1) //过滤器执行顺序
@Component //spring容器管理
public class AuthorizationFilter implements GlobalFilter, Ordered {
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        // 1.获取请求参数
        ServerHttpRequest request = exchange.getRequest();
        MultiValueMap<String, String> params = request.getQueryParams();
        // 2.获取参数中的 authorization 参数
        String auth = params.getFirst("authorization");
        // 3.判断参数值是否等于 admin
        if ("admin".equals(auth)) {
            // 4.是,放行
            return chain.filter(exchange);
        }
        // 5.否,拦截
        // 5.1.设置状态码
        exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
        // 5.2.拦截请求
        return exchange.getResponse().setComplete();
    }

    @Override
    public int getOrder() {
        return -1;
    }
}

注意:Order注解和implements Ordered作用是完全一样的,二选一即可。

过滤器加载流程

在这里插入图片描述

org.springframework.cloud.gateway.route.RouteDefinitionRouteLocator#getFilters()方法是先加载defaultFilters,然后再加载某个route的filters,然后合并。
org.springframework.cloud.gateway.handler.FilteringWebHandler#handle()方法会加载全局过滤器,与前面的过滤器合并后根据order排序,组织过滤器链

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/19765.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

ADV7391BCPZ-ASEMI代理亚德诺ADV7391BCPZ原厂芯片

编辑-Z ADV7391BCPZ参数描述&#xff1a; 型号&#xff1a;ADV7391BCPZ VDD&#xff1a;1.8V VAA&#xff1a;3.3V 全驱动输出电流&#xff1a;34.6 mA 低驱动输出电流&#xff1a;4.3 mA 输出电容&#xff1a;10 pF 模拟输出延迟&#xff1a;6 ns DAC模拟输出倾斜&am…

文件一直处于修改状态 git checkout 无法还原的问题解决方法

问题描述 最近在 RT-Thread 时&#xff0c;使用 Git 回退版本验证问题&#xff0c;后来 git pull 拉取最新代码后&#xff0c;发现里面有几个文件&#xff0c;一直为【修改】状态&#xff0c;并且无法还原&#xff0c;git checkout xxx git reset --hard 都用了&#xff0c;依旧…

简单两步创建nVisual建筑场景

nVisual是一款网络基础设施可视化管理软件&#xff0c;通过模型可规划即将建设的机房效果&#xff0c;或者将已有的机房场景复刻至系统中&#xff0c;便于运维管理者清晰的了解机房设备及线缆路由连接关系。 数据初始我们需要将数据中心场景复刻至系统中&#xff0c;建筑场景也…

【Java】抽象类与接口

文章目录 1.抽象类1.1抽象方法 2.接口3.抽象类和接口的区别3.1代码中区分&#xff1a;3.2设计层面区分 在面向对象编程中&#xff0c;抽象是非常重要的一个特征。在Java中可以通过抽象类或接口的形式实现这一特性。 1.抽象类 Java关键字 abstract对应抽象类的使用 1.1抽象方法…

Calico的BGP打通Kubernetes网络和局域网

1、项目背景 随着云原生技术的不断发展&#xff0c;容器化应用已成为企业构建云原生架构的重要方式。而随着集群规模不断扩大&#xff0c;跨主机通信的需求也越来越重要。在 Kubernetes 集群中&#xff0c;Pod 是最小的调度和管理单位&#xff0c;而网络也是 Kubernetes 中最重…

二叉树OJ

文章目录 二叉树OJ根据二叉树创建字符串思路示例代码 二叉树的层序遍历思路示例代码 二叉树的层序遍历 II思路示例代码 二叉树的最近公共祖先思路1示例代码1思路2示例代码2 二叉搜索树与双向链表思路1示例代码1思路2示例代码2 迭代实现二叉树的三种遍历前序遍历思路示例代码 中…

哪些蓝牙耳机戴久不疼?长时间佩戴不疼的蓝牙耳机推荐

现在的真无线耳机已经成为了人们的标配之一了&#xff0c;各个厂家也紧随其后&#xff0c;生产出了多种无线耳机&#xff0c;不少人的选购蓝牙耳机一般都是对音质、佩戴和连接&#xff0c;但通常人们佩戴蓝牙耳机都是在半天左右&#xff0c;小编专门整理了一期舒适度高的耳机&a…

ElasticSeach 集成 springboot

声明是ElasticSearch? ElasticSearch是一个基于Lucene的搜索服务器。它提供了一个分布式多用户能力的全文搜索引擎&#xff0c; 基于RESTful web接口。Elasticsearch是用Java开发的&#xff0c;并作为Apache许可条款下的开放源码发布&#xff0c;是 当前流行的企业级搜索引擎…

Unity 坐标系

一、左手坐标系与右手坐标系 常见的三维软件都采用笛卡尔坐标系&#xff0c;也就是常见的xyz轴坐标系。笛卡尔坐标系可以是左手坐标系也可以是右手坐标系&#xff0c;如下图所示 两种坐标系是镜像对称的。而Unity采用左手系&#xff0c;且xyz轴的默认方向与图中的左手系完全一…

便携式车用CAN分析仪

产品简介 USBCAN-C系列便携式车用CAN分析仪&#xff0c;通过USB接口快速扩展一路CAN通道&#xff0c;使接入CAN网络非常容易&#xff0c;它具有一体式和小巧紧凑的外形&#xff0c;特别适合于随身携带。CAN接口采用金升阳电源模块和信号隔离芯片实现2500V DC电气隔离&#xff0…

KVM存储池管理与磁盘格式

KVM存储池管理与磁盘格式 KVM必须配置一个目录作为存储磁盘镜像&#xff08;存储卷&#xff09;的目录&#xff0c;我们称这个目录为存储池 存储池管理 默认存储池 /var/lib/libvirt/images/ 创建基于文件夹的存储池&#xff08;目录&#xff09; mkdir -p /data/vmfs定义…

WhatsApp如何让客户参与变得更简单?

WhatsApp对你的品牌来说可能和Twitter和Facebook一样重要&#xff0c;你可能已经把它们纳入你的社交媒体战略。 是的&#xff0c;WhatsApp不仅仅可以用来给同事发短信或与远方的亲戚视频聊天&#xff0c;它也适用于商业。 在发展WhatsApp业务时&#xff0c;小企业主得到了最优…

【网络】Socket编程-UDP篇

文章目录 预备知识源IP地址和目的IP地址源MAC地址和目的MAC地址源端口号和目的端口号"端口号port" 和 "进程ID"认识TCP/UDP协议网络字节序 Socket编程sockaddr结构API接口 简单的UDP网络程序服务器server服务端创建套接字:socket函数**socket的底层原理** …

Unity学习笔记 关于Unity相机的FOV以及水平FOV和垂直FOV之间的转换

前言 关于FOV FOV 是在任何给定时间通过人眼、相机取景器或在显示屏上可见的可观察世界的范围。它指的是整个区域的覆盖范围&#xff0c;而不是单个固定焦点。FOV 还描述了一个人可以看到可见世界的角度。 FOV 越宽&#xff0c;可以看到的可观察世界就越多。它是水平、垂直和对…

使用 OpenCV 进行基于 ESP32 CAM 的目标检测和识别

概述:基于 ESP32 CAM 的目标检测和识别 本教程介绍了使用OpenCV基于 ESP32 CAM的目标检测和识别主题。OpenCV 是一个开源的图像处理库,不仅在工业界而且在研发领域都得到了非常广泛的应用。 这里对于对象检测,我们使用了cvlib 库。该库使用 COCO 数据集上的预训练 AI 模型…

JSON-框架的具体使用

JSON-框架的具体使用 非 SpringBoot 项目 Jackson Jackson 是另一个流行的JSON序列化和反序列化库&#xff0c;具有以下特点 速度快&#xff1a;Jackson 采用了高效的JSON解析算法和字节码生成技术&#xff0c;使得其序列化和反序列化速度非常快。支持全类型序列化&#xff1…

4年外包终于上岸,我只能说别去....

我大学学的是计算机专业&#xff0c;毕业的时候&#xff0c;对于找工作比较迷茫&#xff0c;也不知道当时怎么想的&#xff0c;一头就扎进了一家外包公司&#xff0c;一干就是4年。现在终于跳槽到了互联网公司了&#xff0c;我想说的是&#xff0c;但凡有点机会&#xff0c;千万…

C语言-【移位操作符详解】

这篇文章主要介绍了C语言中移位操作符&#xff0c;文章中通过详细的代码以及有关计算机中零碎的知识点对移位操作符进行了一个更好的解释&#xff0c;需要的小伙伴们可以一起学习学习吖&#xff5e; 移位操作符:移动的是补码的二进制序列。 在C语言当中&#xff0c;有两种移位…

「OceanBase 4.1 体验」|OCP Express

文章目录 一、简介二、特性介绍2.1 数据库管理2.2 数据库可观测性 一、简介 OCP Express 是一个基于 Web 的 OceanBase 4.x 轻量化管理工具&#xff0c;作为 OceanBase 数据库的工具组件&#xff0c;它集成在 OceanBase 数据库集群中&#xff0c;支持数据库集群关键性能指标查看…

一个月内面了30家公司,薪资从18K变成28K,真行啊····

工作3年&#xff0c;换了好几份工作&#xff08;行业流行性大&#xff09;&#xff0c;每次工作都是裸辞。朋友都觉得不可思议。因为我一直对自己很有信心&#xff0c;而且特别不喜欢请假面试&#xff0c;对自己负责也对公司负责。 但是这次没想到市场环境非常不好&#xff0c;…