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

news2024/10/5 21:18:46

目录

  • 一、网关作用
  • 二、网关的技术实现
  • 三、简单使用
  • 四、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 # 本次跨域访问检查的有效期

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

PX4从放弃到精通(二十七):固定翼姿态控制

文章目录前言一、roll/pitch姿态/角速率控制二、偏航角速率控制三、主程序前言 固件版本 PX4 1.13.2 欢迎交流学习&#xff0c;可加左侧名片 一、roll/pitch姿态/角速率控制 roll/pitch的姿态控制类似&#xff0c;这里只介绍roll姿态控制&#xff0c; 代码位置&#xff1a; …

如何确定NetApp FAS存储系统是否正常识别到了boot device?

近期处理了几个NetApp FAS存储控制器宕机的案例&#xff0c;其中部分有代表性的就是其实控制器并没有物理故障&#xff0c;问题是控制器里面的boot device的SSD盘出现了问题。这里给大家share一下如何确定系统是否成功识别到了boot device设备。 对于很多非专业人士来说&#…

mongodb使用docker搭建replicaSet集群与变更监听

在mongodb如果需要启用变更监听功能(watch)&#xff0c;mongodb需要在replicaSet或者cluster方式下运行。 replicaSet和cluster从部署难度相比&#xff0c;replicaSet要简单许多。如果所存储的数据量规模不算太大的情况下&#xff0c;那么使用replicaSet方式部署mongodb是一个…

凹凸/法线/移位贴图的区别

你是否在掌握 3D 资产纹理的道路上遇到过障碍&#xff1f; 不要难过&#xff01; 许多刚接触纹理或 3D 的艺术家在第一次遇到凹凸贴图&#xff08;Bump Map&#xff09;、法线贴图&#xff08;Normal Map&#xff09;和移位贴图&#xff08;Displacement Map&#xff09;时通常…

Linux Redis主从复制 | 哨兵监控模式 | 集群搭建 | 超详细

Linux Redis主从复制 | 哨兵监控模式 | 集群搭建 | 超详细一 Redis的主从复制二 主从复制的作用三 主从复制的流程四 主从复制实验4.1 环境部署4.2 安装Redis&#xff08;主从服务器&#xff09;4.3 修改Master节点Redis配置文件 (192.168.163.100)4.4 修改Slave节点Redis配置文…

MySQL-用户与权限

目录 &#x1f341;DB权限表 &#x1f341;新建普通用户 &#x1f342;创建新用户(create user) &#x1f342;创建新用户(grant) &#x1f341;删除普通用户 &#x1f341;修改用户密码 &#x1f342;Root用户修改自己的密码 &#x1f342;Root用户修改普通用户密码 &#x1f…

区块链概论

目录 1.概述 2.密码学原理 2.1.hash函数 2.2.签名 3.数据结构 3.1.区块结构 3.2.hash pointer 3.3.merkle tree 3.3.1.概述 3.3.2.证明数据存在 3.3.3.证明数据不存在 4.比特币的共识协议 4.1.概述 4.2.验证有效性 4.2.1.验证交易有效性 4.2.2.验证节点有效性 …

~~~~~不得不会的账号与权限管理小知识

目录一.用户账号和组账号概述二. useradd添加用户账号三. passwd 修改密码四. 修改用户账户的属性五 . userdel 删除用户账号六. 用户账号的初始配置文件七. 组账号文件八 . 文件/目录的权限及归属8.1设置文件和目录的权限chmod8.2 设置文件和目录的归属chown命令8.3 补充扩展:…

JAVA本地监听与远程端口扫描的设计与开发

随着Internet的不断发展&#xff0c;信息技术已成为社会进步的巨大推动力。不管是存储于服务器里还是流通于Internet上的信息都已成为一个关系事业成败的关键&#xff0c;这就使保证信息的安全变得格外重要。本地监听与远程端口扫描程序就是在基于Internet的端口扫描的基础上&a…

Optional类快速上手

目录 一、概述 二、使用 1、创建对象 2、安全消费值 3、安全获取值 4、过滤 5、判断 6、数据转换 一、概述 我们在编码的时出现最多的就是空指针异常&#xff0c;所以在很多情况下我们需要做各种非空的判断。 尤其是对象中的属性还是一个对象的情况下&#xff0c;这种…

Doris(3):创建用户与创建数据库并赋予权限

Doris 采用 MySQL 协议进行通信&#xff0c;用户可通过 MySQL client 或者 MySQL JDBC连接到 Doris 集群。选择 MySQL client 版本时建议采用5.1 之后的版本&#xff0c;因为 5.1 之前不能支持长度超过 16 个字符的用户名。 1 创建用户 Root 用户登录与密码修改 Doris 内置 ro…

从C出发 19 --- 函数定义细节剖析

因为编译器是自上而下执行代码的&#xff0c;当编译到 paw2 的时候不知道是什么东西&#xff0c;看起来像一个函数但是前面的代码没有发现它&#xff0c;这个时候编译器就会报错 为了防止编译器报错 应该在调用前先声明 &#xff0c;注意声明的三要素 声明的作用: 让编译器先…

# 切削加工形貌的相关论文阅读【1】-球头铣刀铣削球面的表面形貌建模与仿真研究

切削加工形貌论文【1】-球头铣刀铣削球面的表面形貌建模与仿真研究1. 论文【2】-球头铣刀加工表面形貌建模与仿真1.1 切削加工形貌仿真-考虑的切削参数1.2 其他试验条件1.3 主要研究目的1.4 试验与分析结果1.5 面粗糙度的评价指标2. 论文【1】-球头铣刀加工球面&#xff08;曲面…

Flutter Row 实例 —— 新手礼包

大家好&#xff0c;我是 17。 本文在 3.31 日全站综合热榜第一。 新手礼包一共 3 篇文章&#xff0c;每篇都是描述尽量详细&#xff0c;实例讲解&#xff0c;包会&#xff01; Flutter Row 实例 —— 新手礼包Flutter TextField UI 实例 —— 新手礼包Flutter TextField 交…

CDN如何成为大站标配?

在当下的互联网应用中充斥了大量的静态内容&#xff0c;这些静态和准动态内容在访问请求中占据了大量的网络资源&#xff0c;如果这些请求全部指向源站服务器&#xff0c;很容易导致网络的拥塞甚至是服务器的宕机&#xff0c;对正常的业务开展造成严重影响。为了解决这种情况&a…

共享电子邮件的运作方式

通过电子邮件共享&#xff0c;您可以使用评论轻松管理围绕电子邮件展开的讨论&#xff0c;而无需多次转发和回复。这提供了一种轻松的方式&#xff0c;让您可以通过电子邮件与同事分享信息&#xff0c;并获得他们对此的意见/反馈/建议。 电子邮件共享的运作方式 您收到或发送的…

开源流媒体服务器ZLMediaKit在Windows上运行、配置、按需拉流拉取摄像头rtsp视频流)并使用http-flv网页播放

场景 目前市面上有很多开源的流媒体服务器解决方案&#xff0c;常见的有SRS、EasyDarwin、ZLMediaKit和Monibuca等。 1、SRS GitHub - ossrs/srs: SRS is a simple, high efficiency and realtime video server, supports RTMP, WebRTC, HLS, HTTP-FLV, SRT, MPEG-DASH and …

【linux】 安装 java 环境

目录1.检查linux 下是否安装java(jdk)环境2.查看 linux 的操作系统版本3.下载jdk4.新建java文件夹用于安装jdk5.将下载到本地的jdk压缩包上传到linux服务器6.配置环境变量1.检查linux 下是否安装java(jdk)环境 可通过下面五条命令来查看linux 系统是否安装了java 环境 1、java …

$ZZZ 以 Launchpad 形式多平台首发,GoSleep 成 Sleep to Earn 叙事成 X2E 新宠

“ GoSleep 的治理代币 $ZZZ 将以 Launchpad 形式登录 Bitget、Gate.io以及MXC&#xff0c;这或许预示着 Sleep to Earn 叙事或成 X2E 新宠” “Sleep to Earn” 成为 X2E 市场新发力点 StepN 在去年为 X2E 赛道做了一个很好的示范&#xff0c;这也让这个领域不再仅仅局限于基于…

HarmonyOS/OpenHarmony应用开发-Stage模型ArkTS语言Ability基类

Ability模块提供对Ability生命周期、上下文环境等调用管理的能力&#xff0c;包括Ability创建、销毁、转储客户端信息等。 说明: 模块首批接口从API version 9 开始支持。模块接口仅可在Stage模型下使用。 导入模块: import Ability from ohos.app.ability.Ability; 接口说明…