Spring Cloud系列—Spring Cloud Gateway服务网关的部署与使用指南

news2024/12/25 10:54:04

Gateway网关

文章目录

  • Gateway网关
      • 1. 网关基本简介
        • 1.1 什么是网关
        • 1.2 为什么需要网关?
      • 2. 快速搭建gateway网关
        • 2.1 创建新模块
        • 2.2 引入依赖
        • 2.3 编写启动类
        • 2.4 配置路由规则
        • 2.5 测试
      • 3. 路由过滤
      • 4. 过滤器
        • 4.1 简介
        • 4.2 网关过滤器
          • 4.2.2 种类
        • 4.3 自定义过滤器
          • 4.3.1 自定义GatewayFilter
          • 4.3.2 自定义GlobalFilter
        • 4.4 跨域问题
          • 4.4.1 什么是跨域问题
          • 4.4.2 解决跨域问题
      • 5. 总结

1. 网关基本简介

1.1 什么是网关

网关,简而言之,是一个系统的单一入口点,它接收所有外部请求,并根据请求的特性(如路径、HTTP方法等)将其转发给内部的各个微服务。

比如说,你想要向一个小区内的一个朋友送信,必须要经过看门大爷的同意,大爷如果认为好人,就会把信带给你要送的人;如果大爷认为你是坏人,就会拦截你。

image-20240514143346013

1.2 为什么需要网关?
  1. 路由:微服务架构通常由多个服务组成,每个服务可能部署在不同的地址和端口上。网关可以根据请求的URL或其他条件,将外部请求路由到正确的服务实例上,从而隐藏了服务实例的具体位置。
  2. 负载均衡:当服务有多个实例时,网关可以根据不同的负载均衡策略(如轮询、随机、最少连接等)将请求分发到不同的实例,确保系统资源的有效利用和服务的稳定性。
  3. 统一鉴权和认证:在微服务架构中,每个服务都可能有自己的安全要求。网关可以作为统一的鉴权和认证点,处理所有服务的安全验证,简化了服务之间的安全通信。
  4. 跨域处理:由于浏览器的同源策略,前端应用在访问不同域名或端口的后端服务时可能会遇到跨域问题。网关可以配置CORS(跨源资源共享)策略,允许前端应用安全地访问后端服务。
  5. 熔断和限流:网关可以集成熔断和限流机制,当后端服务出现问题时,网关可以快速失败,防止级联故障。同时,限流可以控制对后端服务的请求速率,防止服务过载。
  6. 监控和日志:网关是所有外部请求的入口点,可以在这一层收集和记录重要的监控数据和日志信息,帮助开发者和运维人员快速定位问题和性能瓶颈。

2. 快速搭建gateway网关

基本步骤:

  1. 创建新模块
  2. 引入网关依赖
  3. 编写启动类
  4. 配置路由规则
2.1 创建新模块

创建一个新模块gatewawy

image-20240514150510201

2.2 引入依赖
        <!--网关-->
        <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>
        <!--负载均衡-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-loadbalancer</artifactId>
        </dependency>
2.3 编写启动类
@SpringBootApplication
public class GatewayApplication {
    public static void main(String[] args) {
        SpringApplication.run(GatewayApplication.class, args);
    }
}

2.4 配置路由规则

gateway模块:

server:
  port: 8080 
spring:
  application:
    name: gateway-service # 服务名称
  cloud:
    nacos:
      server-addr: 192.168.56.101:8848 # Nacos服务注册中心的地址和端口
    gateway:
      routes:
        - id: user # 路由的唯一标识符,自定义,需要保证唯一性
          uri: lb://user-service # 路由的目标服务地址,lb表示使用负载均衡,user-service是注册中心中的服务名
          predicates: # 路由断言,用来判断请求是否符合路由规则
            - Path=/users/**,/addresses/** # 路由断言的路径模式,匹配以/users/或/addresses/开头的请求路径

解析:

  1. default-filters部分定义一个全局过滤器,这些过滤器会对所有通过网关的请求生效。
  2. routes部分,定义了一条路由规则,该规则将所有符合指定路径模式的请求路由到user-service服务。这条规则使用了路径断言Path,匹配所有以/users//addresses/开头的请求。通过使用负载均衡lb://前缀,网关能够根据注册中心中的服务实例信息进行负载均衡。

user-service模块:

server:
  port: 8084
spring:
  application:
    name: user-service
  cloud:
    nacos:
      server-addr: 192.168.56.101:8848
2.5 测试

测试接口:

@ApiOperation("网关测试接口")
@GetMapping("/gateway-test")
public String testGateway(){
    return "网关测试成功";
}

nacos:

image-20240514160742494

测试:

image-20240514160300872

3. 路由过滤

在前面的gatewayroutes部分有四个属性可以配置:

  • id:路由的唯一标示
  • predicates:路由断言,其实就是匹配条件
  • filters:路由过滤条件
  • uri:路由目标地址,lb://代表负载均衡,从注册中心获取目标微服务的实例列表,并且负载均衡选择一个访问。

我们在配置文件中写的断言规则只是字符串,这些字符串会被 Predicate Factory(断言工厂) 读取并处理,转变为路由判断的条件。例如 Path=/user/** 是按照路径匹配,这个规则是由org.springframework.cloud.gateway.handler.predicate.PathRoutePredicateFactory 类来处理的,这里重点关注路由断言predicates

名称说明示例
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权重处理

4. 过滤器

4.1 简介

过滤器是用于修改进入网关的请求和发出网关的响应的组件。过滤器的作用范围可以是特定的路由,也可以是全局的。过滤器可以用来添加或修改请求头和响应头,修改请求体,进行权限校验,限流,熔断等。

4.2 网关过滤器

单体架构时我们只需要完成一次用户登录、身份校验,就可以在所有业务中获取到用户信息。而微服务拆分后,每个微服务都独立部署,不再共享数据。也就意味着每个微服务都需要做登录校验,这显然不可取。

而登录校验必须在请求转发到微服务之前做,否则就失去了意义。网关的请求转发是Gateway内部代码实现的,要想在请求转发之前做登录校验,就必须了解Gateway内部工作的基本原理。

image-20240514161937208

如图所示:

  1. 客户端请求进入网关后由HandlerMapping对请求做判断,找到与当前请求匹配的路由规则(Route),然后将请求交给WebHandler去处理。
  2. WebHandler则会加载当前路由下需要执行的过滤器链(Filter chain),然后按照顺序逐一执行过滤器(后面称为**Filter**)。
  3. 图中Filter被虚线分为左右两部分,是因为Filter内部的逻辑分为prepost两部分,分别会在请求路由到微服务之前之后被执行。
  4. 只有所有Filterpre逻辑都依次顺序执行通过后,请求才会被路由到微服务。
  5. 微服务返回结果后,再倒序执行Filterpost逻辑。
  6. 最终把响应结果返回。

观察得知:如果我们能够定义一个过滤器,在其中实现登录校验逻辑,并且将过滤器执行顺序定义到NettyRoutingFilter之前,就能解决前面的问题。

4.2.2 种类

网关过滤器链中的过滤器有两种:

  • GatewayFilter:路由过滤器,作用范围比较灵活,可以是任意指定的路由Route.
  • GlobalFilter:全局过滤器,作用范围是所有路由,不可配置。

下面是一些常用的Gateway FilterGlobal Filter

  • AddRequestHeader:添加请求头。
  • AddResponseHeader:添加响应头。
  • RewritePath:重写请求路径。
  • PrefixPath:为请求路径添加前缀。
  • SetPath:设置请求路径。
  • Retry:设置重试逻辑。
  • CircuitBreaker:集成熔断器。
  • RequestRateLimiter:限流过滤器。
  • SecureHeaders:添加安全相关的响应头。
  • TokenRelay:用于将认证信息传递给下游服务。

Gateway中内置了很多的GatewayFilter,详情使用可以参考官方文档:

Spring Cloud Gateway

例如AddRequestHeaderGatewayFilterFacotry,顾明思议,就是添加请求头的过滤器,可以给请求添加一个请求头并传递到下游微服务。

使用的使用只需要在application.yaml中这样配置:

spring:
  cloud:
    gateway:
      routes:
      - id: test_route
        uri: lb://test-service
        predicates:
          -Path=/test/**
        filters:
          - AddRequestHeader=key, value # 逗号之前是请求头的key,逗号之后是value

如果想要让过滤器作用于所有的路由,则可以这样配置:

spring:
  cloud:
    gateway:
      default-filters: # default-filters下的过滤器可以作用于所有路由
        - AddRequestHeader=key, value
      routes:
      - id: test_route
        uri: lb://test-service
        predicates:
          -Path=/test/**
4.3 自定义过滤器
4.3.1 自定义GatewayFilter
  1. 编写过滤器工厂GatewayFilterFactory

自定义GatewayFilter不是直接实现GatewayFilter,而是实现AbstractGatewayFilterFactory。最简单的方式是这样的:

@Component
public class PrintAnyGatewayFilterFactory extends AbstractGatewayFilterFactory<Object> {
    @Override
    public GatewayFilter apply(Object config) {
        return new GatewayFilter() {
            @Override
            public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
                // 获取请求
                ServerHttpRequest request = exchange.getRequest();
                // 编写过滤器逻辑
                System.out.println("过滤器执行了");
                // 放行
                return chain.filter(exchange); 
            }
        };
    }
}

注意:该类的名称一定要以GatewayFilterFactory为后缀!!!

  1. 配置路由规则
spring:
  cloud:
    gateway:
      default-filters:
            - PrintAny # 此处直接以自定义的GatewayFilterFactory类名称前缀类声明过滤器

另外,这种过滤器还可以支持动态配置参数,不过实现起来比较复杂,示例:

  1. 编写过滤器工厂GatewayFilterFactory

@Component
public class PrintAnyGatewayFilterFactory // 父类泛型是内部类的Config类型
                extends AbstractGatewayFilterFactory<PrintAnyGatewayFilterFactory.Config> {

    @Override
    public GatewayFilter apply(Config config) {
        // OrderedGatewayFilter是GatewayFilter的子类,包含两个参数:
        // - GatewayFilter:过滤器
        // - int order值:值越小,过滤器执行优先级越高
        return new OrderedGatewayFilter(new GatewayFilter() {
            @Override
            public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
                // 获取config值
                String a = config.getA();
                String b = config.getB();
                String c = config.getC();
                // 编写过滤器逻辑
                System.out.println("a = " + a);
                System.out.println("b = " + b);
                System.out.println("c = " + c);
                // 放行
                return chain.filter(exchange);
            }
        }, 100);
    }

    // 自定义配置属性,成员变量名称很重要,下面会用到
    @Data
    static class Config{
        private String a;
        private String b;
        private String c;
    }
    // 将变量名称依次返回,顺序很重要,将来读取参数时需要按顺序获取
    @Override
    public List<String> shortcutFieldOrder() {
        return List.of("a", "b", "c");
    }
        // 返回当前配置类的类型,也就是内部的Config
    @Override
    public Class<Config> getConfigClass() {
        return Config.class;
    }

}
  1. 配置路由规则
spring:
  cloud:
    gateway:
      default-filters:
            - name: PrintAny # 自定义过滤器的名称
              args: # 过滤器传递的参数,手动指定参数名,无需按照参数顺序
                a: 1
                b: 2
                c: 3
4.3.2 自定义GlobalFilter

自定义GlobalFilter则简单很多,直接实现GlobalFilter即可,而且也无法设置动态参数:

@Component
public class PrintAnyGlobalFilter implements GlobalFilter, Ordered {
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        // 编写过滤器逻辑
        System.out.println("未登录,无法访问");
        // 放行
        // return chain.filter(exchange);

        // 拦截
        ServerHttpResponse response = exchange.getResponse();
        response.setRawStatusCode(401);
        return response.setComplete();
    }

    @Override
    public int getOrder() {
        // 过滤器执行顺序,值越小,优先级越高
        return 0;
    }
}
4.4 跨域问题
4.4.1 什么是跨域问题

跨域问题(Cross-Origin Resource Sharing, CORS)是指由于浏览器的同源策略(Same-Origin Policy)限制,一个源(域名、协议和端口)的网页无法向另一个源发送HTTP请求的问题。同源策略是一种安全机制,旨在防止恶意网站访问敏感数据。

同源的定义是:如果两个页面的协议、域名(或IP地址)和端口都相同,则它们具有相同的源。例如,以下两个URL具有相同的源:

  • http://example.com:80/index.html
  • http://example.com:80/page.html

而以下URL与上面的URL不同源:

  • https://example.com:80/index.html (协议不同)
  • http://www.example.com:80/index.html (域名不同)
  • http://example.com:81/index.html (端口不同)

当尝试从不同源的客户端发送请求到服务器时,浏览器会阻止这些请求,除非服务器明确允许跨源请求。这就是所谓的跨域问题。

4.4.2 解决跨域问题

全局CORS配置:在网关的配置文件中,可以定义全局的CORS配置,这些配置会应用到所有的路由上。

spring:
  application:
    name: gateway
  cloud:
    nacos:
      server-addr: 192.168.56.101:8848
    gateway:
      globalcors:
        add-to-simple-url-handler-mapping: true # 因为ajax发起者会通过options请求来向服务器询问是否允许跨域,所以需要设置为true来解决options请求被拦截问题
        corsConfigurations:
          '[/**]':
            allowedOrigins: "http://www.xxx.com" # 允许那些网站跨域访问
            allowedMethods: # 允许的HTTP方法
              - GET
              - POST
              - PUT
              - DELETE
            allowedHeaders: "*" # 允许的请求头
            allowCredentials: true # 是否允许发送Cookie
            maxAge: 3600 # 预检请求的缓存时间(秒)

5. 总结

本文深入探讨了Spring Cloud Gateway网关的核心概念及其在微服务架构中的快速部署方法,除此之外着重讲解了Gateway过滤器(Filters)的重要性以及相关使用,包括过滤器的种类、自定义过滤器的实现以及过滤器在解决跨域问题中的作用。

至于具体的应用要根据实际开发要求编写,这里就不过多展示了,希望对大家有所帮助。


参考资料:

Gateway网关 - wenxuehai - 博客园 (cnblogs.com)

gateway Strict-origin-when-cross-origin跨域问题解决 | 少将全栈 (whatled.com)

微服务02

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

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

相关文章

能播放SWF文件的FlashPlayer播放器

问题&#xff1a; 你是不是遇到了 flash 动画 放不了了&#xff1f; 以前的flash游戏玩不了了 在网上很难找到好用的&#xff0c;免费Flashplayer播放器&#xff0c; 找到的也没法保存.exe 以前买的课件放不了了 一打开就更新提示&#xff1a; 再不就是意外能打开了但【创建…

50. UE5 RPG FGameplayEffectContext

接下来&#xff0c;我想实现处理完伤害时&#xff0c;将伤害的触发格挡或者触发暴击时的逻辑传递到数据集的PostGameplayEffectExecute里面&#xff0c;这样&#xff0c;在处理IncomingDamage时&#xff0c;我们可以通过释放触发格挡或者触发暴击在UI上面进行对应的效果表现。 …

Ubuntu环境搭建与共享文件

vmtool 然后依次执行以下指令 sudo apt-get update 更新包列表。访问系统的软件仓库源,检查所有已知软件包的最新版本,并更新本地数据库,使得可以安装或升级到最新的软件版本。sudo apt-get upgrade 升级所有已安装的软件包到它们的最新版本。这不包括新安装的软件包,仅限…

24/05/14总结

签到2&#xff1a; 签到界面上有时间显示&#xff0c;签到码输入框&#xff0c;开始签到&#xff0c;当倒计时结束&#xff0c;老师端和学生端都会显示签到结果&#xff0c;所以签到结果需要建表&#xff1a;&#xff08;签到了的学生和未签到的学生&#xff0c; 这次签到的时间…

【iOS】工厂模式

文章目录 前言设计模式的三大原则简单工厂模式工厂方法模式抽象工厂模式关于三兄弟的升级与降级注意 前言 上文讲完了iOS的架构模式&#xff0c;接下来聊一聊设计模式&#xff0c;设计模式有许多&#xff0c;主要介绍一下工厂模式 设计模式的三大原则 S 单一职责原则 告诉我…

adobe安装“Error:SyntaxError:JSON Parse error:Unexpec

mac电脑安装Adobe时&#xff0c;会提示错误“Error:SyntaxError:JSON Parse error:Unexpected EOF”&#xff0c;这是怎么回事儿的&#xff0c;不管您是安装AI、PS、PR还是LR&#xff0c;如果也遇到相同的问题&#xff0c;可以参考一下方法解决&#xff1a; 「adobe安装提示错误…

LLM应用-prompt提示:让大模型总结生成思维导图

第一步&#xff1a;大模型生成markdown思维导图格式 例如&#xff1a;kimi 总结pdf文档案例&#xff1a; 生成的markdown格式&#xff1a; # 知识图谱的构建及应用 ## 一、知识图谱的构建 ### 1. 数据采集 - 来源&#xff1a;结构化数据库、半结构化网页、非结构化文本 - 预处…

三星将采用铁电材料实现1000层3D NAND

在2022年的技术日上&#xff0c;三星公布了一项宏伟目标&#xff0c;即到2030年推出层数超过1000层的先进NAND芯片。据Wccftech报道&#xff0c;这家韩国存储巨头似乎正逐步接近这一目标&#xff0c;计划在NAND芯片制造中应用新型“铁电”材料。 最近美国火奴鲁鲁举行的VLSI技术…

Mujoco仿真【将urdf文件转化为xml文件】

最近开始学习mujoco仿真方面的内容 先前写过一篇博客&#xff1a;强化学习&#xff1a;MuJoCo机器人强化学习仿真入门&#xff08;1&#xff09;_mujoco仿真-CSDN博客 简单介绍了mujoco仿真的一些内容&#xff0c;下面想在Mujoco中将urdf转为xml文件&#xff0c;了解到mujoco是…

pikachu靶场通关之csrf漏洞通关教程

目录 CSRF&#xff08;get型&#xff09; 1.打开网站&#xff0c;点击右上角提示 2.登录之后&#xff0c;点击修改个人信息 3.修改上述内容&#xff0c;打开抓包工具 4.抓到修改用户信息的数据包 5.构造虚假url&#xff0c;诱导用户点击 6.弹到修改后的界面 ​编辑 7.返…

windows11 Django环境安装

相关文档 1、验证python和pip3环境 C:\Users\Administrator>python Python 3.12.3 (tags/v3.12.3:f6650f9, Apr 9 2024, 14:05:25) [MSC v.1938 64 bit (AMD64)] on win32 Type "help", "copyright", "credits" or "license" for…

数据库学习之select语句练习

目录 素材 练习 1、显示所有职工的基本信息。 结果 2、查询所有职工所属部门的部门号&#xff0c;不显示重复的部门号。 结果 3、求出所有职工的人数。 结果 4、列出最高工和最低工资。 结果 5、列出职工的平均工资和总工资。 结果 6、创建一个只有职…

【LeetCode刷题】136.只出现一次的数字(Ⅰ)

【LeetCode刷题】136.只出现一次的数字&#xff08;Ⅰ&#xff09; 1. 题目&#xff1a;2.思路分析&#xff1a;思路1&#xff1a;一眼异或&#xff01; 1. 题目&#xff1a; 2.思路分析&#xff1a; 思路1&#xff1a;一眼异或&#xff01; 看到题目&#xff0c;如果有一定基…

助力数字农林业发展服务香榧智慧种植,基于YOLOv5全系列【n/s/m/l/x】参数模型开发构建香榧种植场景下香榧果实检测识别系统

作为一个生在北方但在南方居住多年的人&#xff0c;居然头一次听过香榧&#xff08;fei&#xff09;这种作物&#xff0c;而且这个字还不会念&#xff0c;查了以后才知道读音&#xff08;fei&#xff09;&#xff0c;三声&#xff0c;这着实引起了我的好奇心&#xff0c;我相信…

在macOS中开发的Django项目部署到局域网的Win10服务器上

由于windows10是日常办公电脑&#xff0c;没有服务器基本环境&#xff0c;部署工程耗费不少时间&#xff0c;记录一下。 1、安装Python 访问Python官方下载页面&#xff1a;Python Downloads&#xff0c;下载适用于Windows的安装程序并按照提示进行安装。开发环境python版本是…

主从Reactor服务器

目录&#xff1a; 目录&#xff1a; 目标&#xff1a; 本文讲解思路&#xff1a; 各模块的功能以及代码&#xff1a; 1.服务器相关模块&#xff1a;服务器模块的功能是对所有的连接以及线程进⾏管理 2.协议相关模块&#xff1a;协议模块是对当前的Reactor模型服务器提供应…

GPT-4o:全面深入了解 OpenAI 的 GPT-4o

GPT-4o&#xff1a;全面深入了解 OpenAI 的 GPT-4o 关于 GPT-4o 的所有信息ChatGPT 增强的用户体验改进的多语言和音频功能GPT-4o 优于 Whisper-v3M3Exam 基准测试中的表现 GPT-4o 的起源追踪语言模型的演变GPT 谱系&#xff1a;人工智能语言的开拓者多模式飞跃&#xff1a;超越…

FSMC的NOR Flash/PSRAM 控制器功能介绍(STM32F4)

目录 概述 1 FSMC支持的类型 1.1 信号类型概述 1.2 FSMC的应用 2 外部存储器接口信号 2.1 I/O NOR Flash 2.2 PSRAM/SRAM 3 支持的存储器和事务 4 通用时序规则 5 NOR Flash/PSRAM 控制器异步事务 5.1 模式 1 - SRAM/PSRAM (CRAM) 5.2 模式 A - SRAM/PSRAM (CRAM…

电机控制杂谈——“双采样双更新模式”对模型预测控制/PI控制的提升有多大?

1.采样频率与PWM开关频率的关系 一般有以下两种采样模式。 如下图&#xff08;a&#xff09;所示&#xff0c;这种方式称之为单采单更模式&#xff0c;即在一个PWM周期内&#xff0c;采样一次&#xff0c;更新一次PWM占空比&#xff0c;在这种情况下&#xff0c;采样频率&…

独立服务器和云服务器哪个好?

在当今数字时代&#xff0c;网站托管是任何在线业务成功的关键要素之一。但是&#xff0c;当谈到选择正确的托管解决方案时&#xff0c;很容易陷入独立服务器与云服务器之间的抉择。两者都有各自的优势和限制&#xff0c;因此在决定哪种类型的托管适合您的业务之前&#xff0c;…