【微服务】6、一篇文章学会使用 SpringCloud 的网关

目录

  • 一、网关作用
  • 二、网关的技术实现
  • 三、简单使用
  • 四、predicates
    • (1) 网关路由可配置的内容
    • (2) 路由断言工厂(Route Predicate Factory)
  • 五、filters
    • (1) GatewayFilter
    • (2) 给全部进入 userservice 的请求添加请求头
    • (3) 全局过滤器 —— GlobalFilter
    • (4) 过滤器的执行顺序
  • 六、网关跨域
    • (1) 跨域
    • (2) 网关跨域处理

一、网关作用

📗 身份认证、权限校验
📗 服务路由、负载均衡
📗 请求限流

在这里插入图片描述

二、网关的技术实现

📝 在 SpringCloud 中有两种网关的技术实现
✏️ gateway(比 zuul 新)
✏️ zuul

✒️ Zuul 是基于 Servlet 实现的,属于阻塞式编程
✒️ Gateway 是基于 Spring5 中提供的 WebFlux 实现的。属于响应式编程,具有更好的性能

三、简单使用

✏️ 网关是一个新的微服务
✏️ 需要通过 nacos 进行服务注册和发现

🎄 (1) 创建新的模块(module),引入 SpringCloudGateway 和 Nacos 服务发现依赖

  <dependencies>
      <dependency>
          <groupId>org.springframework.cloud</groupId>
          <artifactId>spring-cloud-starter-gateway</artifactId>
      </dependency>

      <dependency>
          <groupId>com.alibaba.cloud</groupId>
          <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
      </dependency>
  </dependencies>

🎄 (2)把网关服务注册到 nacos 中,并编写路由配置

server:
  port: 10010 # 网关服务的端口号
spring:
  application:
    name: gateway # 服务名
  cloud:
    nacos:
      server-addr: localhost:8848 # nacos 服务发现地址
    gateway: # 网关相关配置
      routes: # 网关的路由配置
        - id: userservice # 路由编号(自定义), 保持唯一
          uri: lb://userservice # 路由的目标地址【lb: load balance】
          # uri: http://127.0.01:8081 # 路由的目标地址(直接写死)
          predicates: # 判断(断言)怎样的请求会被路由
            - Path=/users/** # 若请求路径是【/users/】开头的就路由到此
        - id: orderservice
          uri: lb://orderservice
          predicates:
            - Path=/orders/**

在这里插入图片描述

四、predicates

(1) 网关路由可配置的内容

✒️ id: 路由的唯一标识
✒️ uri:路由目的地【① lb: load balance;② http(不推荐)】
✒️ predicates:路由断言(判断请求是否符合要求,符合则路由转发到对应的 uri 的服务器)
✒️ filters:路由过滤器(处理请求响应

(2) 路由断言工厂(Route Predicate Factory)

📝 在配置文件中写的断言规则只是字符串(它会被 Predicate Factory 读取和处理,并转变为路由判断的条件)


✏️ Path=/user/** 是按照路径进行匹配
✏️ 是通过 PathRoutePredicateFactory 类来处理的

在这里插入图片描述


✏️ SpringCloudGateway 中的断言工厂:
在这里插入图片描述

五、filters

(1) GatewayFilter

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

在这里插入图片描述

官方提供了三十多种过滤器工厂:
https://docs.spring.io/spring-cloud-gateway/docs/current/reference/html/#gatewayfilter-factories

在这里插入图片描述

(2) 给全部进入 userservice 的请求添加请求头

spring:
  application:
    name: gateway # 服务名
  cloud:
    gateway: # 网关相关配置
      routes: # 网关的路由配置
        - id: userservice # 路由编号(自定义), 保持唯一
          uri: lb://userservice # 路由的目标地址【lb: load balance】
          # uri: http://127.0.01:8081 # 路由的目标地址(直接写死)
          predicates: # 判断(断言)怎样的请求会被路由
            - Path=/users/** # 若请求路径是【/users/】开头的就路由到此
          filters: # 过滤器
            - AddRequestHeader=color, skyblue
        - id: orderservice
          uri: lb://orderservice
          predicates:
            - Path=/orders/**
 @GetMapping("getUserById/{id}")
 public User getUserById(@PathVariable Long id,
                         @RequestHeader(value = "color", required = false) String color) {
     log.info("请求头: {}", color);
     return userService.getUserById(id);
 }

默认过滤器 default-filters 会对全部的路由请求都生效

spring:
  application:
    name: gateway # 服务名
  cloud:
    nacos:
      server-addr: localhost:8848 # nacos 服务发现地址
    gateway: # 网关相关配置
      routes: # 网关的路由配置
        - id: userservice # 路由编号(自定义), 保持唯一
          uri: lb://userservice # 路由的目标地址【lb: load balance】
          # uri: http://127.0.01:8081 # 路由的目标地址(直接写死)
          predicates: # 判断(断言)怎样的请求会被路由
            - Path=/users/** # 若请求路径是【/users/】开头的就路由到此
#          filters: # 过滤器
#            - AddRequestHeader=color, skyblue
        - id: orderservice
          uri: lb://orderservice
          predicates:
            - Path=/orders/**
      default-filters: # 默认过滤器
        - AddRequestHeader=color, green

(3) 全局过滤器 —— GlobalFilter

📝 全局过滤器的作用: 处理一切进入网关的请求微服务响应,与GatewayFilter 的作用一样
📝 区别:GatewayFilter 通过配置定义,处理逻辑是固定的
📝 GlobalFilter 的逻辑需要自己写代码实现


📚 需求:定义全局过滤器,拦截并判断用户身份

定义全局过滤器,拦截请求。判断请求参数是否满足以下条件:
① 参数中是否有 authorization
② authorization 的参数值是否是 admin
若 ① 和 ② 同时满足,则放行;否则拦截

// @Order(value = 6) // 过滤器执行顺序(值越小,优先级越高)
@Component // 放入 IoC
public class GlobalGatewayFilter implements GlobalFilter , Ordered {

    /**
     * 拦截并处理全部的请求,处理成功后通过 chain 进入下一个过滤器
     *
     * @param exchange 请求上下文(可获取 Request、Response 等信息)
     * @param chain    放行该请求,进入下一过滤器
     * @return 返回,标识当前过滤器结束
     */
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        // 获取请求参数
        // 该请求是 WebFlux 中的(与 HttpServletRequest 不同)
        ServerHttpRequest request = exchange.getRequest();
        // 获取请求参数(键值对)
        MultiValueMap<String, String> paramMap = request.getQueryParams();
        String paramVal = paramMap.getFirst("authorization");

        if (paramVal == null || !paramVal.equals("admin")) {
            // 拦截(返回)
            ServerHttpResponse response = exchange.getResponse();
            // 未登录状态码
            response.setStatusCode(HttpStatus.UNAUTHORIZED);
            return response.setComplete(); // 返回
        }

        // 放行
        return chain.filter(exchange);
    }

    @Override
    public int getOrder() {
        return 6;
    }
}

在这里插入图片描述

(4) 过滤器的执行顺序

📚 请求进入网关会碰到三类过滤器:当前路由的过滤器、DefaultFilter、GlobalFilter

📚 请求路由后,会将当前路由过滤器、DefaultFilter、GlobalFilter 合并为一个过滤器链(集合)中,然后进行排序。排序之后,依次执行每个过滤器。

在这里插入图片描述


📚 每个过滤器都必须指定一个 int 类型的 order 值【order 值越小,优先级越高,执行顺序越靠前】
📚 GlobalFilter 通过实现 Ordered 接口或添加 @Order 注解来指定 order 值
📚 路由过滤器和 DefaultFilter 的 order 值由 Spring 指定【在各自过滤器内部按照声明顺序 从1 递增】
📚 当过滤器的 order 值一样时,优先级是:DefaultFilter > 路由过滤器 > GlobalFilter

server:
  port: 10010
spring:
  application:
    name: gateway
  cloud:
    nacos:
      server-addr: localhost:8848
    gateway:
      routes:
        - id: userservice
          uri: lb://userservice
          predicates:
            - Path=/users/**
          filters: # 路由过滤器
            - AddRequestHeader=color, red # order = 1
            - AddRequestHeader=color, blue # order = 2
            - AddRequestHeader=color, green # order = 3
      default-filters: # 默认过滤器
        - AddRequestHeader=name, zgq # order = 1
        - AddRequestHeader=name, ytr # order = 2
        - AddRequestHeader=name, zhn # order = 3

  • org.springframework.cloud.gateway.route.RouteDefinitionRouteLocator#getFilters(): ① 加载 DefaultFilter;② 加载路由过滤器;③ 合并 DefaultFilter 和路由过滤器
  • org.springframework.cloud.gateway.handler.FilteringWebHandler#handle(): ① 加载全局过滤器;② 与 DefaultFilter 和路由过滤器合并;③ 根据合并后的 order 值排序;④ 组织过滤器链

六、网关跨域

(1) 跨域

浏览器有个同源策略(Same-Origin Policy):默认情况下,AJAX 请求只能发送给同源的 URL

📚 AJAX:Asynchronous Javascript And XML【异步 JavaScript 和 XML】

  • 同源指 ① 协议、② 域名(IP)、③ 端口 相同
  • img、script、link、iframe、video、audio 等标签不受同源策略约束

在这里插入图片描述


跨域问题: 浏览器要求发送请求的来源和接收请求的接口的协议、域名和端口必须相同,否则该请求会被浏览器拦截


📚 CORS(Cross-Origin Resource Sharing):跨域资源共享

(2) 网关跨域处理

在这里插入图片描述

  • 要访问 http://localhost:10010/orders/getOrderById/101?authorization=admin 地址的资源
  • 发送请求的来源是 http://localhost:8082/#/pages/index/index

❌ 端口不相同(不符合浏览器的同源策略)

📚 跨域访问检查发送的是 OPTIONS 请求
📚 跨域访问检查有效期要合理

spring:
  cloud:
    gateway: # 网关相关配置
      globalcors: # 全局跨域处理
        add-to-simple-url-handler-mapping: true # 防止 options 请求被拦截
        cors-configurations:
          '[/**]': # 拦截全部路径
            allowedOrigins: # 允许跨域访问的来源
              - "http://localhost:8082"
            allowedMethods: # 允许跨域访问的请求方式
              - "GET"
              - "POST"
              - "DELETE"
              - "PUT"
              - "OPTIONS"
            allowedHeaders: "*" # 允许跨域访问携带请求头信息
            allowCredentials: true # 允许跨域访问携带 cookie
            maxAge: 360000 # 本次跨域访问检查的有效期

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

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

相关文章

如何在矩池云上部署 Carla,模拟自动驾驶

简介 Carla 是一款基于 Python 编写和 UE&#xff08;虚幻引擎&#xff09;的开源仿真器&#xff0c;用于模拟自动驾驶车辆在不同场景下的行为和决策。它提供了高度可定制和可扩展的驾驶环境&#xff0c;包括城市、高速公路和农村道路等。Carla 还提供了丰富的 API 和工具&…

LeetCode算法小抄 -- 环检测算法 和 拓扑排序算法

LeetCode算法小抄 -- 环检测算法 和 拓扑排序算法 环检测算法(DFS)[207. 课程表](https://leetcode.cn/problems/course-schedule/) 拓扑排序算法(DFS)[210. 课程表 II](https://leetcode.cn/problems/course-schedule-ii/) 环检测算法(BFS)拓扑排序算法(BFS) ⚠申明&#xff1…

Python Web开发技巧II

Postman安置Cookie 对于大型项目而已&#xff0c;所携带的cookie往往都不止一个&#xff0c;而是一堆&#xff0c;甚至特别特别长&#xff0c;postman文档提供的cookie操作是全局的&#xff0c;但需要一个一个打&#xff08;折磨&#xff09;&#xff0c;唯一的优点就是作用域…

3.7 曲率

学习目标&#xff1a; 如果我要学习高等数学中的曲率&#xff0c;我会遵循以下步骤&#xff1a; 1.熟悉相关的数学概念&#xff1a;在学习曲率之前&#xff0c;我们需要了解曲线、切线和曲率半径等相关的数学概念。因此&#xff0c;我会复习这些概念&#xff0c;以便更好地理…

Java阶段一Day21

Java阶段一Day21 文章目录 Java阶段一Day21多线程并发原理使用场景创建并启动线程创建线程的方法 进程线程的生命周期获取线程信息的方法 教师总结新单词多线程概念线程:一个顺序的单一的程序执行流程就是一个线程。代码一句一句的有先后顺序的执行。多线程:多个单一顺序执行的…

Nacos 客户端服务注册源码分析-篇二

Nacos 客户端服务注册源码分析-篇二 继续接上回&#xff0c;上回分析到 NacosNamingService 的整个注册的流程&#xff0c;其实是通过 NacosFactory.createNamingService 方法&#xff0c;反射获取 NacosNamingService 接口的实现类 NacosNamingService &#xff0c;而 NacosN…

【计算方法】正交区域查询---KD-Tree概念

一、说明 kd 树是一种二叉树数据结构&#xff0c;可以用来进行高效的 kNN 计算。kd 树算法偏于复杂&#xff0c;本篇将先介绍以二叉树的形式来记录和索引空间的思路&#xff0c;以便读者更轻松地理解 kd 树。 二、正交区域查找 2.1 定义 对于k维空间的张量数据表格&#xff0…

一键生成元宇宙 AI又杀疯了

人类十几年的进步水平&#xff0c;AI用几个月就能轻易实现。在展示了超强的文本对话能力和一键生图功能后&#xff0c;AI大模型不打算停下&#xff0c;开始挑战搭建3D空间这一更高难度的动作。 这次&#xff0c;Facebook母公司Meta想当一把主导者。几天前&#xff0c;它的首席…

信号生成和可视化——周期性/非周期性波形

信号生成和可视化 此示例说明如何使用 Signal Processing Toolbox™ 中提供的函数生成广泛使用的周期和非周期性波形、扫频正弦波和脉冲序列。尝试此示例Copy Command Copy Code 周期性波形 除了 MATLAB 中的 sin 和 cos 函数外&#xff0c;Signal Processing Toolbox™ 还…

redis主从复制详解

文章目录 主从复制概述主从复制的作用主要包括&#xff1a;数据冗余故障恢复负载均衡高可用基石 主从库之间采用的是读写分离的方式读操作写操作 主从复制原理全量复制确立主从关系全量复制的三个阶段第一阶段是主从库间建立连接、协商同步的过程&#xff0c;主要是为全量复制做…

MobileNetV3详细原理(含torch源码)

作者&#xff1a;爱笑的男孩。 个人简介&#xff1a;打工人。 持续分享&#xff1a;机器学习、深度学习、python相关内容、日常BUG解决方法及Windows&Linux实践小技巧。 如发现文章有误&#xff0c;麻烦请指出&#xff0c;我会及时去纠正。有其他需要可以私信我或者发我邮箱…

Linux系统上如何禁用 USB 存储

Linux系统上如何禁用 USB 存储 为了保护数据不被泄漏&#xff0c;我们使用软件和硬件防火墙来限制外部未经授权的访问&#xff0c;但是数据泄露也可能发生在内部。 为了消除这种可能性&#xff0c;机构会限制和监测访问互联网&#xff0c;同时禁用 USB 存储设备。 我是艾西&…

uni-app常用配置

保存自动格式化 工具》设置》编辑器设置》保存时自动格式化 JS语法检查 安装eslint-js插件eslint-js - DCloud 插件市场用于校验js和html中的js代码https://ext.dcloud.net.cn/plugin?id2037工具》设置》插件配置》eslint-js 启用实时校检 Vue语法检查 安装eslint-vue插件…

如何突破LinkedIn领英限制,导出非好友邮箱等社交方式

相信做外贸的朋友都有使用过Linkedin&#xff0c;如果还没有使用过的话&#xff0c;我只能说您错过一个很好的平台。只要是厉害的外贸人都特别擅长用Linkedin找客户。 那为什么说Linkedin是外贸业务员开发客户最有效的途径呢&#xff1f;主要基于以下几点&#xff1a; 第一&a…

强训之【井字棋和密码强度等级】

目录 1.井字棋1.1题目1.2思路讲解1.3代码展示 2.密码强度判断2.1题目2.2思路讲解2.3代码 3.选择题 1.井字棋 1.1题目 链接: link 描述 给定一个二维数组board&#xff0c;代表棋盘&#xff0c;其中元素为1的代表是当前玩家的棋子&#xff0c;0表示没有棋子&#xff0c;-1代表…

禅道OpenAI更新至1.2版本,超多实用功能惊喜上线!

广受欢迎的禅道OpenAI插件近日成功发布&#xff0c;截至目前已更新至1.2版本。 截至本版本发布&#xff0c;禅道OpenAI已经拥有了神奇海螺&#xff08;ChatGPT聊天&#xff09;、需求润色、任务润色、Bug润色及本次的需求一键生成用例功能&#xff0c;仍有更多实用的新功能正在…

计算机视觉__基本图像操作(显示、读取、保存)

计算机视觉__基本图像操作&#xff08;显示、读取、保存&#xff09; 本文目录&#xff1a; ✨ 一、前言 ✨ 二、图像显示&#xff08;使用OpenCV和Matplotlib显示图像&#xff09; &#xff08;1&#xff09;、使用OpenCV显示图像 &#xff08;2&#xff09;、使用Matplotl…

电磁兼容(EMC)的标准与测试内容

在国际范围上&#xff0c;电磁兼容标准的制定已经有了70多年的发展历程&#xff0c;最早为了保护无线电通信和广播&#xff0c;国际无线电干扰特别委员会&#xff08;CISPR&#xff09;对各种用电设备和系统提出了相关的电磁干扰发射限值和测量方法。到了20世纪60&#xff5e;7…

被裁了,39 岁阿里 P9,攒下 1.5 亿....

今天刷知乎&#xff0c;在问题 “40 岁因为财务自由决定不上班的人&#xff0c;个人资产总和到底有多少” 下看到一位阿里 P9 的匿名回答让我狠狠的酸了一把~ 这刚刚失业的四十岁高级码农自曝了自己的人生经历&#xff0c;作为一名“阿里 P9”的程序员&#xff0c;他讲述了自己…

聚观早报|阿里云正式推出通义千问;京东零售开启5年最大组织变革

今日要闻&#xff1a;国家网信办规范生成式人工智能服务&#xff1b;阿里云正式推出通义千问&#xff1b;京东零售开启5年来最大组织变革&#xff1b;飞书将推出智能AI助手「My AI」&#xff1b;乐高将继续扩大在华零售布局 国家网信办规范生成式人工智能服务 4 月 11 日&…