Gateway 统一网关

一、初识 Gateway

1. 为什么需要网关

我们所有的服务可以让任何请求访问,但有些业务不是对外公开的,这就需要用网关来统一替我们筛选请求,它就像是房间的一道门,想进入房间就必须经过门。而请求想要访问微服务,就必须通过网关再到微服务。

2. 网关的作用

  • 身份认证和权限校验

网关是微服务的入口,会验证用户是否有请求资格,如果没有则进行拦截

  • 服务路由、负载均衡

网关不处理业务,根据拟定好的规则,将请求转发到对应的微服务中,这个过程就是路由。当对应的微服务有部署了多个,同样需要根据拟定的规则做负载均衡。

  • 请求限流

请求量过高时,网关根据微服务能够接受的请求量来放行请求,避免服务压力过大。就像是红绿灯避免交通堵塞的原理类似。

在 SprignCloud 中网关的实现包括两种:

  • gateway
  • zuul:zuul 是基于 Servlet 实现的,属于阻塞式编程。而SpringCloudGateway 是基于 Spring5 中提供的 WebFlux, 属于响应式编程的实现,具备更好的性能。

二、入门案例

1. 创建新的module,引入SpringCloudGateway的依赖和nacos的服务发现依赖,如果没有统一管理版本号,需要加上<version></version>

<!--nacos服务注册发现依赖-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>
        <!--网关gateway依赖-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-gateway</artifactId>
        </dependency>

2.  编写启动类

@SpringBootApplication
public class GatewayApplication {

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

3. 路由配置及nacos地址

3.1 创建application.yml文件

server:
  port: 10010 # 网关端口
spring:
  application:
    name: gateway # 服务名称
  cloud:
    nacos:
      server-addr: localhost:8848 # nacos地址
    gateway:
      routes: # 网关路由配置(routes: 多个; route: 一个)
        - id: user-service # 路由id,自定义,只要唯一即可
          uri: lb://userservice # 第一种写法:路由的目标地址; lb(loadBalance)是指负载均衡,后面跟服务名称
          predicates: # 路由断言,也就是判断请求是否符合路由规则的条件(断言一般是布尔类型)
            - Path=/user/** # 这个是按照路径匹配,只要以/user/开头就符合要求
#        可以同时配置多个服务路由
        - id: baidu-demo
          uri: https://www.baidu.com  # 第二种写法:路由的目标地址 http就是固定地址
          predicates:
           - Path=/baidu/** # 注意使用本服务测试需要开启下面截取path,不然拼接的路径无效
#         filters: 
# path断言路由的请求格式默认为uri+path,如果不需要携带path可以截取掉
#           - StripPrefix=1    # 截取掉- Path中的第一级路径/baidu

# 初学期间为了方便调试与快速定位错误,可以将gateway打印日志级别调低
logging:
  level:
    org:
      springframework:
        cloud:
          gateway: trace

路由的配置包括:

1.路由id:路由的唯一标示

2.路由目标(uri):路由的目标地址,http代表固定地址,lb代表根据服务名负载均衡

3.路由断言(predicates):判断路由的规则,一般是布尔类型

4.路由过滤器(filters):对请求或响应做处理

重启网关服务, 访问 localhost:10010/user/1,如下图所示 

被拦截状态

至此案例到此结束,为了更好的了解网关在这期间默默的付出了哪些,下面将网关原理聊一聊。

用户发送请求后,首先会通过网关,而网关是不做任何业务的,会去注册中心 Nacos 中拉取服务列表,然后根据负载均衡选择一个服务发送用户的请求。如下图

三、断言工厂

我们配置文件中写的断言规则是字符串,这些字符串会被断言工厂(Route Predicate Factory读取处理,转变为路由判断的条件。断言工厂为我们把字符串转变为了判断条件。例如 Path=/user/** 是按照路径匹配,这个规则是由 org.springframework.cloud.gateway.handler.predicate.PathRoutePredicateFactory类来处理的。像这样的断言工厂在SpringCloudGateway还有十几个。

名称说明示例
After是某个时间点后的请求- After=2037-01-20T17:42:47.789-07:00[America/Denver]
Before是某个时间点之前的请求- Before=2031-04-13T15:14:47.433+08:00[Asia/Shanghai]
Between是某两个时间点之前的请求- Between=2037-01-20T17:42:47.789-07:00[America/Denver], 2037-01-21T17:42:47.789-07:00[America/Denver]
Cookie请求必须包含某些cookie- Cookie=chocolate, ch.p
Header请求必须包含某些header- Header=X-Request-Id, \d+
Host请求必须是访问某个host(域名)- Host=.somehost.org,.anotherhost.org
Method请求方式必须是指定方式- Method=GET,POST
Path请求路径必须符合指定规则- Path=/red/{segment},/blue/**
Query请求参数必须包含指定参数- Query=name, Jack或者- Query=name
RemoteAddr请求者的ip必须是指定范围- RemoteAddr=192.168.1.1/24
Weight权重处理

四、过滤器工厂

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

Spring提供了31种不同的路由过滤器工厂。例如:

名称说明
AddRequestHeader给当前请求添加一个请求头
RemoveRequestHeader移除请求中的一个请求头
AddResponseHeader给响应结果中添加一个响应头
RemoveResponseHeader从响应结果中移除有一个响应头
RequestRateLimiter限制请求的流量
……

下面举个例子给所有进入userservice的请求添加一个请求头:Truth=itcast is freaking awesome!

实现方式:

1.  局部过滤器(GatewayFilter)

filters : 配置在路由下的过滤器只对当前路由的请求生效, filters 在 routes 的目录下

1. 在gateway中修改application.yml文件, 给userservice的路由添加过滤器

spring:
  cloud:
    gateway:
      routes:
      - id: user-service 
        uri: lb://userservice 
        predicates: 
        - Path=/user/** 
        filters: # 路由过滤器
        - AddRequestHeader=Truth, me is freaking awesome! # 添加请求头

为了方便观察是否添加成功,这里改造方法如下 

2.  默认过滤器(DefaultFilter)

default-filters  : 对所有路由都生效的过滤器,  default-filters 和 routes 同级目录

spring:
  cloud:
    gateway:
      routes:
      - id: user-service 
        uri: lb://userservice 
        predicates: 
        - Path=/user/**
      default-filters: # 默认过滤器
      - AddRequestHeader=Truth, me is freaking awesome! 

3. 全局过滤器(GlobalFilter)

全局过滤器 (GlobalFilter) 的作用也是处理一切进入网关的请求和微服务响应,与上面的作用一样。

区别在于

  • GatewayFilter通过配置定义,处理逻辑是固定的。
  • 上面的逻辑需要自己写代码实现,定义方式是实现GlobalFilter接口。
public interface GlobalFilter {
    /**
     *  处理当前请求,有必要的话通过{@link GatewayFilterChain}将请求交给下一个过滤器处理
     *
     * @param exchange 请求上下文,里面可以获取Request、Response等信息
     * @param chain 用来把请求委托给下一个过滤器 
     * @return {@code Mono<Void>} 返回标示当前过滤器业务结束
     */
    Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain);
}

3.1 自定义全局过滤器

需求:定义全局过滤器,拦截请求,判断请求的参数是否满足下面条件:

参数中是否有authorization?authorization参数值是否为admin?如果同时满足则放行,否则拦截

实现步骤

1. 在 gateway 中定义一个过滤器

@Order(-1)  // 权重注解,值越小优先级越高
@Component
public class AuthorizeFilter implements GlobalFilter {
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        // 1.获取请求参数
        MultiValueMap<String, String> params = exchange.getRequest().getQueryParams();
        // 2.获取authorization参数
        String auth = params.getFirst("authorization");
        // 3.校验
        if ("admin".equals(auth)) {
            // 放行
            return chain.filter(exchange);
        }
        // 4.拦截
        // 4.1.禁止访问,设置状态码
        exchange.getResponse().setStatusCode(HttpStatus.FORBIDDEN);
        // 4.2.结束处理
        return exchange.getResponse().setComplete();
    }
}

2. 测试,访问 http://localhost:10010/user/1?authorization=admin 可以看到成功获取到响应结果

若不符合要求则无法获取结果

4. 过滤器的执行顺序

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

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

过滤器执行顺序

  1. 每一个过滤器都必须指定一个int类型的order值,order值越小,优先级越高,执行顺序越靠前。
  2. GlobalFilter通过实现Ordered接口,或者添加@Order注解来指定order,由我们自己指定。
  3. 路由过滤器和defaultFilterorderSpring指定,默认是按照声明顺序1递增
  4. 当过滤器的order值一样时,会按照 defaultFilter > 路由过滤器 > GlobalFilter的顺序执行。

 4.1 定义执行顺序的两种方式

5. 限流过滤器

限流:对应用服务器的请求做限制,避免因过多请求而导致服务器过载甚至宕机。限流算法如下:

  • 计数器算法,又包括固定窗口计数器算法、滑动窗口计数器算法
  • 漏桶算法(Leaky Bucket)
  • 令牌桶算法(Token Bucket

1. 计数器算法 --- 固定窗口计数器算法

  • 将时间划分为多个窗口;
  • 在每个窗口内每有一次请求就将计数器加一,当时间到达下一个窗口时,计数器重置。
  • 如果计数器超过了限制数量,则本窗口内所有的请求都被丢弃。

 但是这种会有个问题,假如我们在1s内允许通过的请求数量是100,如果在窗口失效的最后几毫秒发送了99个请求,接着又在下一个时间窗口开始时发送99个请求,那么这个用户这1s内就不止发送100个请求了,这就是临界值问题。

 

2. 计数器算法 --- 滑动窗口计数器算法

滑动窗口计算算法就是为了解决固定窗口计算算法存在临界值的问题而出现的。假设我们1秒内允许通过100个请求,但我们把1秒分成多个窗格(窗格数越多,流量过度越平滑)。

3. 漏桶算法

  • 将每个请求视作"水滴"放入"漏桶"进行存储;
  • "漏桶"以固定速率向外""出请求来执行,如果"漏桶"空了则停止"漏水”;
  • 如果"漏桶"满了则多余的"水滴"会被直接丢弃。

 

4. 令牌桶算法 

以固定的速率生成令牌,存入令牌桶中,如果令牌桶满了以后,多余令牌丢弃

六、跨域问题

  • 跨域:域名、端口、协议三者任意一个不同就是跨域

域名不同: www.taobao.com www.taobao.org www.jd.commiaosha.jd.com

端口不同:localhost:8080和localhost:8081

协议不同:https:xxx.com 和 http:xxx.com

  • 跨域问题:浏览器禁止请求发送者与服务端跨域ajax请求,说白了就是请求被浏览器拦截的问题
  • 解决方案:CORS (跨域资源共享)

网关处理跨域采用的同样是CORS方案,并且只需要简单配置即可实现:

spring:
  cloud:
    gateway:
      globalcors: # 全局的跨域处理
        add-to-simple-url-handler-mapping: true # 解决options请求被拦截问题
        corsConfigurations:
          '[/**]':
            allowedOrigins: # 允许哪些网站的跨域请求 
              - "http://localhost:8090"
            allowedMethods: # 允许的跨域ajax的请求方式
              - "GET"
              - "POST"
              - "DELETE"
              - "PUT"
              - "OPTIONS"
            allowedHeaders: "*" # 允许在请求中携带的头信息
            allowCredentials: true # 是否允许携带cookie
            maxAge: 360000 # 这次跨域检测的有效期, 有效期内浏览器不询问是否拦截

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

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

相关文章

ComfyUI系列——新手安装ComfyUI,就是这么简单

比较Midjoury、WebUI和ComfyUI 在了解ComfyUI的时候&#xff0c;还有其它两款类似的产品&#xff0c;于是就搜集了一下资料&#xff0c;以下是Midjoury、WebUI&#xff08;通常指的是Stable Diffusion Web UI&#xff09;和ComfyUI三者之间的异同点对比表。 特性MidjourneySt…

国内短剧系统源码搭建系统平台小程序新玩法

在数字化内容消费日益普及的今天&#xff0c;短剧小程序作为一种新兴的内容平台&#xff0c;其功能设计至关重要。一个好的短句系统不仅需要提供优质的内容展示&#xff0c;还需要具备一系列优秀功能以满足用户和运营者的需求。以下是一些必备的功能特点&#xff1a; 为大家介…

WebGL 添加背景图

1. 纹理坐标&#xff08;st坐标&#xff09;简介 ST纹理坐标&#xff08;也称为UV坐标&#xff09;是一种二维坐标系统&#xff0c;用于在三维模型的表面上精确地定位二维纹理图像。这种坐标系统通常将纹理的左下角映射到(0,0)&#xff0c;而右上角映射到(1,1)。 S坐标&#x…

leetcode_128:最长连续序列

给定一个未排序的整数数组 nums &#xff0c;找出数字连续的最长序列&#xff08;不要求序列元素在原数组中连续&#xff09;的长度。 请你设计并实现时间复杂度为 O(n) 的算法解决此问题。 示例 1&#xff1a; 输入&#xff1a;nums [100,4,200,1,3,2] 输出&#xff1a;4 解…

CSS揭秘:7. 伪随机背景

前置知识&#xff1a;CSS 渐变&#xff0c;5. 条纹背景&#xff0c;6. 复杂的背景图案 前言 本篇主要内容依然是关于背景的&#xff0c;无限平铺的背景会显得整齐美观&#xff0c;但又有些呆板&#xff0c;如何实现背景的多样性和随机性&#xff0c;是本篇的核心。 一、四种颜…

AI周报(10.20-10.26)

AI应用-牙科AI产品Pearl Pearl是一家致力于改善牙科患者护理的人工智能驱动型公司&#xff0c;推出了首款获得美国食品药品监督管理局&#xff08;FDA&#xff09;批准的人工智能&#xff0c;能够读取牙科X光片并即时识别疾病。今年7月获得5800万美元的B轮融资&#xff0c;以加…

GESP一级真题分析-202303-选择题1-输入输出设备、存储单位、默认数据类型、标识符命名

PDF文档回复:20241026 1 相关知识点 1) 输入输出设备 输入设备 是外界向计算机传送信息的装置。在微型计算机系统中&#xff0c;最常用的输入设备是键盘和鼠标。 此外还有电子光笔、数字化仪、图形扫描仪、触摸屏、麦克风、视频输入设备、条形码扫描等 输出设备 作用是将计…

Java-图书管理系统

我的个人主页 欢迎来到我的Java图书管理系统&#xff0c;接下来让我们一同探索如何书写图书管理系统吧&#xff01; 1管理端和用户端 2建立相关的三个包&#xff08;book、operation、user&#xff09; 3建立程序入口Main类 4程序运行 1.首先图书馆管理系统分为管理员端和…

6.stm32 OLED显示屏

调试方式 串口调试&#xff1a;通过串口通信&#xff0c;将调试信息发送到电脑端&#xff0c;电脑使用串口助手显示调试信息 显示屏调试&#xff1a;直接将显示屏连接到单片机&#xff0c;将调试信息打印在显示屏上 Keil调试模式&#xff1a;借助Keil软件的调试模式&#…

【阅读笔记】Instruction-based Hypergraph Pretraining

Abstract中可以提炼的信息&#xff1a; 背景&#xff1a;预训练的作用是为了增强图学习模型将知识从大数据集转移到下游任务的适应性。 想解决的问题&#xff1a;训练目标的不同与数据分布的不同会阻碍预训练知识的迁移。 文章受到基于指令的提示词在语言模型训练广泛应用的启发…

Vue学习笔记(四)

事件处理 我们可以使用 v-on 指令 (通常缩写为 符号) 来监听 DOM 事件&#xff0c;并在触发事件时执行一些 JavaScript。用法为 v-on:click"methodName" 或使用快捷方式 click"methodName" 事件处理器的值可以是&#xff1a; 内联事件处理器&#xff1…

鹅厂面试官:Transformer 为何需要位置编码?

最近这一两周看到不少互联网公司都已经开始秋招发放Offer。 不同以往的是&#xff0c;当前职场环境已不再是那个双向奔赴时代了。求职者在变多&#xff0c;HC 在变少&#xff0c;岗位要求还更高了。 最近&#xff0c;我们又陆续整理了很多大厂的面试题&#xff0c;帮助一些球…

前端零基础入门到上班:【Day2】开发环境VSCode安装

VSCode 安装教程&#xff1a;图文保姆教程 引言 在前端开发中&#xff0c;选择合适的代码编辑器是提高工作效率的重要一步。Visual Studio Code&#xff08;简称 VSCode&#xff09;作为一款强大的开源编辑器&#xff0c;因其简洁易用、功能强大、扩展性好而广受开发者喜爱。…

【智能大数据分析 | 实验四】Spark实验:Spark Streaming

【作者主页】Francek Chen 【专栏介绍】 ⌈ ⌈ ⌈智能大数据分析 ⌋ ⌋ ⌋ 智能大数据分析是指利用先进的技术和算法对大规模数据进行深入分析和挖掘&#xff0c;以提取有价值的信息和洞察。它结合了大数据技术、人工智能&#xff08;AI&#xff09;、机器学习&#xff08;ML&a…

Postman常见问题及解决方(全)

&#x1f345; 点击文末小卡片 &#xff0c;免费获取软件测试全套资料&#xff0c;资料在手&#xff0c;涨薪更快 1、网络连接问题 如果Postman无法发送请求或接收响应&#xff0c;可以尝试以下操作&#xff1a; 检查网络连接是否正常&#xff0c;包括检查网络设置、代理设置…

前端零基础入门到上班:【Day3】从零开始构建网页骨架HTML

HTML 基础入门&#xff1a;从零开始构建网页骨架 目录 1. 什么是 HTML&#xff1f;HTML 的核心作用 2. HTML 基本结构2.1 DOCTYPE 声明2.2 <html> 标签2.3 <head> 标签2.4 <body> 标签 3. HTML 常用标签详解3.1 标题标签3.2 段落和文本标签3.3 链接标签3.4 图…

市面上热门的四款PDF转换器解析!!

在互联网普及的今天&#xff0c;PDF和Excel已经成为我们工作中不可或缺的两种文件格式。PDF常用于文档的阅读、打印和分享&#xff0c;而Excel则适用于数据的分析和处理。但是&#xff0c;有时候我们需要在两者之间进行转换&#xff0c;例如将PDF中的数据导入到Excel中进行进一…

物联网数据采集网关详细介绍-天拓四方

一、物联网数据采集网关的概述 物联网数据采集网关&#xff0c;简称数据采集网关&#xff0c;是物联网系统中的重要组成部分&#xff0c;位于物联网设备和云端平台之间。其主要职责是实现数据的采集、汇聚、转换、传输等功能&#xff0c;确保来自不同物联网设备的数据能够统一…

Hadoop 踩坑汇总

文章目录 一、完整教程二、解决问题问题①&#xff1a; DataNode 没有问题②&#xff1a; 网页打不开 三、大功告成&#xff01;&#xff01; 一、完整教程 这个教程比较详细&#xff0c;博主是按照这个来执行的 https://blog.csdn.net/qq_47831505/article/details/123806514…

VsCode插件:前端每日一题

Javascript本地存储的方式有哪些&#xff1f; 区别及应用场景? 1. Cookie Cookie 是网站为了辨别用户身份、进行session跟踪而储存在用户本地终端上的数据。Cookie 通常包含了用户的一些个人信息&#xff0c;如用户名、密码、浏览记录、偏好设置等。Cookie 一般在用户访问网站…