Spring Cloud Gateway: 网关

news2024/12/27 13:49:11

文章目录

  • 网关
  • Hello world
  • 路由: Route
    • 谓词: Predicate
    • 过滤器: Filter
      • Gateway实现限流: RequestRateLimiter过滤器
      • 使用Gateway实现服务降级
  • 自定义全局过滤器
  • GateWay中执行流程

网关

API网关就是实现了前端项目和服务端项目之间的统一入口
Nginx实现的是用户和前端项目之间调用的入口
Ribbon实现是后端服务之间相互调用的负载均衡算法
在这里插入图片描述

API网关作用就是把各个服务对外提供的API汇聚起来,让外界看起来是一个统一的接口。同时在网关中提供额外的功能。

Hello world

一.搭建Eureka Server
二.搭建application client集群
三.搭建Gateway网关微服务
1.导入依赖

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

2.编写yml配置文件

server:
  port: 9999
eureka:
  client:
    service-url:
      defaultZone: http://localhost:8761/eureka/
spring:
  application:
    name: cloud-gateway
  cloud: # spring cloud相关配置的常用前缀
    gateway: # 网关技术配置前缀
      discovery: # 自动发现工具
        locator: # 本地逻辑
          enabled: true # 开启自动发现工具的本地路由逻辑
          lower-case-service-id: true # 把从EurekaServer上发现的服务名称,转换成全小写,只要小写的服务名称才能访问,大写的不行!!!!!!

四.启动服务
自动发现工具的本地路由规则是:
请求路径 - http://网关IP:网关端口/微服务的服务名/要访问的具体地址
gateway自动解析,把请求地址中的’微服务的服务名’截取,从Eureka Client发现的服务列表中查看,如果有同名服务,则开始转发。
如: http://localhost(网关IP):9999(网关端口)/application(服务集群名)/save(具体访问地址)

路由: Route

一个路由包含ID、URI、Predicate集合、Filter集合。
在Route中ID是自定义,但唯一,URI就是一个地址。
谓词: 路由前的条件和内容.
Filter负责在路由后,代理服务“之前”或“之后”做的一些事情。

谓词: Predicate

对前端发来的请求进行校验
1.Path: 用于匹配路由地址规则的谓词。

spring:
  cloud: 
    gateway:
      discovery:
        locator:
          enabled: false # 关闭自动发现工具的本地路由逻辑
          lower-case-service-id: true 
      routes: 
        - id: application-service # 路由的唯一名称,随便定义,不重复即可
          uri: lb://application-service # 规则满足后,转发到的地址。lb是spring cloud gateway支持的一种协议名
          predicates: Path=/edit # 谓词  路由地址规则  

Path=/edit/** 代表所有访问url中代用edit的都可以走这个路由

2.Query: 校验请求url是否包含指定的请求参数及参数值是否符合要求,只能校验请求地址参数,也就是 /path?参数

方式一: 只能指定是否有指定请求参数,不能指定参数值
predicates: Path=/demo/**,Query=abc

方式二: 常用,可以指定请求参数及参数值,但是不能指定参数值中带有","的参数值
predicates: 
  - Path=/demo/**
  - Query=name,fs.* # 请求参数必须包含name,请求参数的值必须以 fs开头
  - Query=age,18 # 请求参数必须包含age

方式三:
predicates: 可以指定请求参数值中带有","的参数值
  - Path=/demo02
  - name: Query
    args:
      param: abc
      regexp: 12,3

3.Header: 校验请求中是否包含指定的请求头及请求头数值是否符合要求
4.Method: 请求方式。支持多个值,使用逗号分隔
5.Cookie: 包含指定Cookie名和满足特定正则要求的值: Cookie参数值要是正则表达式
**

  predicates:
    - Path=/service/**  
    - Header=Host,.* # 请求头必须有Host,值为任意字符串
    - Header=abc,123 # 请求头中包含abc,且值为123
	- Method=GET,POST # 请求方式必须是GET或POST
    - Cookie=name,bjsxt.* # 请求必须包含名称是name,值符合bjsxt开头的cookie。

6.RemoteAddr: 允许访问的客户端IP

  predicates:
    - Path=/service/** 
    - RemoteAddr=192.168.41.252 # 客户端IP必须是192.168.41.252

7.Host: 匹配请求中Host请求头的值。满足Ant模式(之前在Spring Security中学习过)可以使用:

  • ? 匹配一个字符
  • * 匹配0个或多个字符
  • ** 匹配0个或多个目录
  predicates:
    - Path=/service/** 
    - Host=127.0.0.1:9999 # 请求头Host值必须是127.0.0.1:9999

8.时间限制:
下面三个一般只存在一个即可
Before: 在指定时间点之前
After: 在指定时间点之后。
Between: 请求时必须在设定的时间范围内,才进行路由转发。

  predicates:
    - Path=/service/** 
    - Before=2022-10-01T18:00:00.000+08:00[Asia/Shanghai] # 2022-10-01晚18点前可以访问
    - After=2020-10-01T08:00:00.000+08:00[Asia/Shanghai] # 2020-10-01早8点后可以访问
	- Between=2020-10-01T08:00:00.000+08:00[Asia/Shanghai],2022-10-01T18:00:00.000+08:00[Asia/Shanghai] # 2020-10-01早8点后,2022-10-01晚18点前可以访问

9.Weight: 对服务名指定分组合权重
Weight=组名,负载均衡权重
例: 在Eureka中注册两个服务,这个服务(项目)是相同的,应用程序名分别叫做application-service1和application-service2。
Gateway在路由匹配时application-service1将占20%,application-service2将占80%。

- id: application-service1
  uri: lb://application-service1
  predicates:
    - Path=/service/**
    - Weight=group1,2
- id: application-service2
  uri: lb://application-service2
  predicates:
    - Path=/service/**
    - Weight=group1,8

过滤器: Filter

路由转发之后,被代理的服务执行前后运行的
路由过滤器:框架内置的Filter实现都是路由过滤器,都是GatewayFilter实现类型。
全局过滤器:框架未内置全局过滤器实现,需自定义。全局过滤器需实现接口GlobalFilter。

          filters: #/配置路由规则
            - stripPrefix=1 #跳过路径中的前几级发送给下游地址
            - AddRequestHeader=sxt,123 #给下游请求添加请求头
            - AddRequestParameter=abc,123 #给下游服务传递请求参数
            - AddResponseHeader=cou,javaEE #设置响应头
            - DedupeResponseHeader=cou,RETAIN_FIRST #当相应头重复后﹑保留第一个
            - SetPath=/{segment} #重新的设置路徭

Gateway实现限流: RequestRateLimiter过滤器

常见限流算法
一.计数器算法: 每个请求让计数器加一,当到达设定值后,其他的请求都拒绝。到下一秒开始时,计数清零,重新开始计数。
二.漏桶算法: 不论请求多少,都以恒定速度处理请求
三.令牌桶算法: 在桶中放令牌,请求获取令牌后才能继续执行,不论请求多少,执行速率都由生产令牌的速率控制.
令牌桶算法
1.导入依赖

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

2.新建密钥解析器
注意这里使用IP解析

@Component
public class MyKeyResolver implements KeyResolver {
    @Override
    public Mono<String> resolve(ServerWebExchange exchange) {
        String ip = exchange.getRequest() // 获取请求对象
                .getRemoteAddress() // 获取客户端地址对象 InetSocketAddress
                .getAddress() // 获取客户端地址对象 InetAddress
                .getHostAddress(); // 获取客户端的主机地址(IP或唯一的主机名)
        return Mono.just(ip); // 创建返回结果对象
    }
}

3.yml配置文件

          filters:
            - name: RequestRateLimiter
              args:
                keyResolver: '#{@xxx}'
                redis-rate-limiter.replenishRate: 1 # 每秒令牌生成速率
                redis-rate-limiter.burstCapacity: 2 # 令牌桶容量上限

4.测试:
使用JMeter访问 http://localhost:9999/save 若干次,结果是,第一秒可处理2个请求(令牌桶上限),后续每秒可以处理1个请求(令牌生成速率)。

使用Gateway实现服务降级

1.导入依赖

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

2.在Gateway的controller创建托底方法

@RestController
public class MyController {
    @RequestMapping("/fallback")
    public String show(){
        return "托底方法";
    }
}

3.yml配置

          filters:
            - name: Hystrix
              args:
                name: fallback # 随意定义的名称。相当于@HystrixCommand注解中的commandKey属性。
                # 如果转发的服务不可用,请求转发到当前Gateway模块映射路径为fallback(随意命名和映射路径一致即可)的控制单元上。
                fallbackUri: forward:/fallback 

自定义全局过滤器

/**
 * 自定义全局过滤器。
 * 必须实现接口GlobalFilter
 * 当前类型的对象,必须被spring容器管理。
 * 无须配置,所有路由都生效。
 *
 * 执行顺序:
 *  先执行网关过滤器,后执行全局过滤器
 *  多个全局过滤器,执行顺序由Spring boot扫描管理当前对象的顺序决定。
 *  每个过滤器,都是完整执行后,才执行下一个过滤器。
 */
@Component
public class MyGlobalFilter implements GlobalFilter {
    /**
     * 过滤方法。
     * 实现上,只有唯一的要求。必须调用方法chain.filter(exchange),并把方法的返回值,返回。
     * @param exchange
     * @param chain
     * @return
     */
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        System.out.println("前置全局过滤");
        //放行/执行下一个过滤器
        Mono<Void> result = chain.filter(exchange);
        System.out.println("后置全局过滤");
        return result;
    }
}

GateWay中执行流程

1.网关客户端访问Gateway网关,Gateway中Handler Mapping对请求URL进行处理。
2.处理完成后,交由Web Handler处理,Web Handler 运行时会被Filter过滤。Filter中前半部分代码是处理请求的代码。
3/处理完成后调用真实被代理的服务;被代理服务返回响应结果,结果会被Filter中后半部分代码过滤处理;
4,操作完成后把结果返回给Web Hanlder,再返回给Handler Mapping,最终响应给客户端。

GateWay的底层: 底层框架是Netty(NIO) :对java.net中内容进行封装 【NIO】 AIO进行封装

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

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

相关文章

【Linux】环境变量相关笔记

文章目录 echo $PATHexport和环境变量相关的命令main(int argc,char* argv[],char *env[])三个参数介绍getenv()通过系统调用获取su与su - 的区别&#xff1a;exportsource 和 .优先级 echo $PATH 是用来查环境变量的 export 从下面的图片当中可以看到&#xff0c;的确是将文…

ubuntu 20.04设置开机自启动脚本

1 建立开机启动服务 在 路径下 /lib/systemd/system/rc-local.service 的 rc-local.service 的脚本&#xff0c;内容规定了 rc.local 的启动顺序和行为 这行代码规定了这个service在开机启动时所执行的命令是&#xff1a;/etc/rc.local start。即运行 /etc/rc.local 脚本。不过…

《面试1v1》HashMap

没有人比中国人更懂 HashMap 我是 javapub&#xff0c;一名 Markdown 程序员从&#x1f468;‍&#x1f4bb;&#xff0c;八股文种子选手。 面试官&#xff1a;HashMap 是Java程序员用得最频繁的集合之一,可以给我简单介绍一下它的内部实现机制吗? 候选人&#xff1a; Hash…

C++ -3- 类和对象 (中) | 拷贝构造函数 赋值运算符重载

文章目录 4.拷贝构造函数什么是拷贝构造函数&#xff1f;应用——示例&#xff1a;日期计算器什么情况下需要自己实现拷贝构造函数&#xff1f; 5.赋值运算符重载运算符重载&#xff08;重要&#xff09;赋值运算符重载 拷贝构造函数和赋值重载函数 4.拷贝构造函数 什么是拷贝…

Baumer工业相机堡盟工业相机如何联合BGAPI SDK和OpenCV实现Mono12和Mono16格式位深度的图像保存(C++)

Baumer工业相机堡盟工业相机如何联合BGAPI SDK和OpenCV实现Mono12和Mono16位深度的图像保存&#xff08;C&#xff09; Baumer工业相机Baumer工业相机保存位深度12/16位图像的技术背景代码案例分享1&#xff1a;引用合适的类文件2&#xff1a;BGAPI SDK在图像回调中联合OpenCV保…

Effective C++条款条款42:了解typename的双重意义(Understand the two meanings of typename)

Effective C条款条款42&#xff1a;了解typename的双重意义&#xff08;Understand the two meanings of typename&#xff09; 条款42&#xff1a;了解typename的双重意义1、从属名称和非从属名称2、typename在traits机制中的运用3、牢记 总结 《Effective C》是一本轻薄短小的…

1.17 从0开始学习Unity游戏开发--场景切换

前面的所有文章我们都在一个固定的游戏场景内进行开发&#xff0c;在最开始介绍场景这个概念的时候就已经提及&#xff0c;这个场景可以是一张地图&#xff0c;或者是一个对战房间等等&#xff0c;所以显然这个场景可以有多个&#xff0c;并且可以从一个场景切换到另外一个场景…

Collection接口

文章目录 1. Java集合框架概述2. Collection接口中15个方法的使用3. Iterator(迭代器)接口4. Connection子接口一&#xff1a;List4.1 List的实现类4.2 源码分析4.2.1 ArrayList源码分析4.2.2 LinkedList源码分析4.2.3 Vector源码分析 4.3 List接口中的常用方法 5. Collection子…

死锁---银行家算法例题

1、知识点 1.银行家算法使用的四个必要的数据结构是: 可用资源向量Available&#xff0c;最大需求矩阵Max&#xff0c;分配矩阵Allocation&#xff0c;需求矩阵Need。 2.银行家算法是不是破坏了产生死锁的必要条件来达到避免死锁的目的&#xff1f;若是&#xff0c;请简述破…

【数字 IC / FPGA】 有关建立/保持时间计算的思考

引言 最近准备一些数字IC的机试&#xff0c;刷到了一些有关静态时序分析的题目。有一些比较经典的题目&#xff0c;在这里整理分享一下。 有什么疑问可以在评论区交流~互相进步 双D触发器典型电路 假设时钟周期为Tcycle,Tsetup,Thold分别为触发器建立保持时间&#xff0c;为…

Mac OS挂载ext4硬盘

一、安装macFUSE Home - macFUSE 如下载macfuse-4.4.3dmg安装 安装过程可能会遇到“若要要启用系统扩展,您需要在恢复环境中修改安全性设置”的提示&#xff0c;如下图&#xff1a; 解决&#xff1a; 关机&#xff0c;直到键盘灯全灭了&#xff01; 再按住开机键&#xff0c…

机器视觉技术分享-彩色图像处理 含c++ ,python代码说明

彩色图像处理是指对彩色图像进行数字处理和分析的过程&#xff0c;其目的是提取图像的有用信息&#xff0c;改善图像质量&#xff0c;实现图像的增强、复原、分割、匹配、识别等功能。 针对彩色图像处理&#xff0c;可以采用以下一些常见的方法&#xff1a; 1. 颜色空间转换&…

简简单单认识一下Inscode

CSDN最新推出的Inscode服务是一个在线编程工具&#xff0c;旨在为开发者提供一个便捷的编写、运行和分享代码的环境&#xff0c;让开发者无需在本地搭建编程环境&#xff0c;即可快速编写和运行代码。 Inscode支持多种编程语言&#xff0c;包括Java、Python、C等&#xff0c;同…

C语言进阶之回调函数详解分析方法

一、函数指针 在讲回调函数之前&#xff0c;我们需要了解函数指针。 我们都知道&#xff0c;C语言的灵魂是指针&#xff0c;我们经常使用整型指针&#xff0c;字符串指针&#xff0c;结构体指针等。 int *p1; char *p2; STRUCT *p3; // STRUCT为我们定义的结构体 但是好像我…

PlumGPT【告别梯子,拥抱AI】

相信很多人苦于没有openai账号或者有着种种原因至今还没有使用过chatgpt&#xff0c;今天向大家推荐一个网站&#xff0c;在国内也可以任意方便使用&#xff0c;让你的办公效率最大化。 那就是PlumGPT&#xff1a;https://plumgpt.com/ PlumGPT&#xff08;国内版的chatgpt&a…

Mybatis分页实现

1. Rowbounds Rowbounds将所有符合条件的数据加载到内存&#xff0c;然后再实现逻辑切割。 Override public List<User> getAllUser() {RowBounds rowBounds new RowBounds(1, 2);return userMapper.getAllUser(rowBounds); }查询sql&#xff08;没有任何分页逻辑&…

【Redis】常用命令、各种数据结构及命令

目录 一、常见数据结构 二、常用命令 1、查询符合的所有key 2、删除key 3、判断key是否存在 4、给key设置过期时间 5、查看key的剩余过期时间 三、不同数据类型的操作命令 1、String 1.set 2.get 3.mset 4.mget 5.incr 6.incrby 7.incrbyfloat 8.setnx 9.se…

C++——内存分配与动态内存管理

文章目录&#x1f490;专栏导读&#x1f490;文章导读&#x1f337;C/C内存分布&#x1f33a;牛刀小试&#x1f33a;C语言动态内存管理&#x1f337;C动态内存管理&#x1f33a;对于内置类型&#x1f33a;对于自定义类型&#x1f337;operator new与operator delete函数&#x…

便携式明渠流量计有哪几种呢?

便携式明渠流量计有几种&#xff1f; 目前来说市面上是有两种&#xff0c;但最终的作用或者说是功能都是用来和明渠在线流量计做液位和流量比对的一种装置。 这两种有什么区别呢&#xff1f; 一种就是便携式明渠流量计磁致伸缩流量计&#xff0c;另一种就是便携式明渠超声波…

浅析EasyCVR基于B/S架构的技术特点与能力应用

EasyCVR基于云边端协同&#xff0c;可支持海量视频的轻量化接入与汇聚管理。平台兼容性强、拓展度高&#xff0c;可提供视频监控直播、视频轮播、视频录像、云存储、回放与检索、智能告警、服务器集群、语音对讲、云台控制、电子地图、平台级联等功能。 EasyCVR视频融合平台采用…