Spring Cloud之API网关(Gateway)

news2024/12/23 23:12:30

目录

API网关

好处

解决方案

Gateway

简介

特征

核心概念

Route(路由)

Predicate(断言)

Filter(过滤器)

工作流程

Route(路由)

路由配置方式

1.yml配置文件路由

2.bean进行配置

3.动态路由

动态路由

Predicate(断言)

特点

常见断言

示例

Filter(过滤器)

filter分类

Pre 类型

Post 类型

网关过滤器

格式

示例

全局过滤器

示例


在微服务架构中,一个系统由多个微服务组成,而这些服务可能部署在不同的地区、不同的机房,客户端想要连接,就需要知道它们具体的地址信息;

存在问题:

1.当服务数量众多时,客户端需要维护大量的服务地址,这对于客户端来说,是非常繁琐的

2.某些情况下存在跨域请求问题

3.认证难度大,每个微服务需要独立认证

API网关

        网关是一个搭建在客户端和微服务之间的服务,我们可以在 API 网关中处理一些非业务功能的逻辑,例如权限验证、监控、缓存、请求路由等

        网关就像整个微服务系统的门面一样,是系统对外的唯一入口。有了它,客户端会先将请求发送到 API 网关,然后由 API 网关根据请求的标识信息将请求转发到微服务实例

好处

1.网关与微服务交互时,客户端只需要知道网关地址即可,而不需要维护大量的服务地址,简化了客户端的开发

2.客户端直接与网关通信,能够减少客户端与各个服务的交互次数

3.客户端与后端的服务耦合度降低

4.节省流量,提高性能,提升用户体验

5.网关还提供了安全、流控、过滤、缓存、计费以及监控等 API 管理功能

解决方案

1.gateway

2.zuul

3.kong

4.Nginx+Lua

Gateway

简介

        Spring Cloud 团队基于 Spring 5.0、Spring Boot 2.0 和 Project Reactor 等技术开发的高性能 API 网关组件;旨在提供一种简单而有效的途径来发送 API,并为它们提供横切关注点,例如:安全性,监控/指标和弹性

特征

1.基于 Spring Framework 5、Project Reactor 和 Spring Boot 2.0 构建

2.任意请求属性上匹配路由

3.断言 和过滤器是特定于路由的

4.集成了 Hystrix 熔断器

5.集成了 Spring Cloud DiscoveryClient(服务发现客户端)

6.易于编写断言和过滤器

7.能够限制请求频率

8.能够重写请求路径

核心概念

gateway最主要的功能就是路由转发,而在定义转发规则时主要涉及到三个核心概念

Route(路由)

        网关最基本的模块。它由一个 ID、一个目标 URI、一组断言(Predicate)和一组过滤器(Filter)组成

Predicate(断言)

        路由转发的判断条件,我们可以通过 Predicate 对 HTTP 请求进行匹配,例如请求方式、请求路径、请求头、参数等,如果请求与断言匹配成功,则将请求转发到相应的服务。

Filter(过滤器)

        我们可以使用它对请求进行拦截和修改,还可以使用它对上文的响应进行再处理

工作流程

说明:

1.客户端将请求发送到gateway

2.gateway通过gateway Handler Mapping找到相匹配得到路由,将其发送给gateway web Handler

3.gateway web Handler通过指定的过滤器链,将请求转发到实际的服务节点中,执行业务返回响应结果

注意:

1.过滤器之间用虚线分开是因为过滤器可能会在转发请求之前(pre)或之后(post)执行业务逻辑

2.过滤器(Filter)可以在请求被转发到服务端前,对请求进行拦截和修改,例如参数校验、权限校验、流量监控、日志输出以及协议转换等

3.过滤器可以在响应返回客户端之前,对响应进行拦截和再处理,例如修改响应内容或响应头、日志输出、流量监控等。

        Gateway 的请求需要通过一定的匹配条件,才能定位到真正的服务节点。在将请求转发到服务进行处理的过程前后(pre 和 post),我们还可以对请求和响应进行一些精细化控制。

Route(路由)

        路由是网关最基础的部分,路由信息由一个ID、一个目的URL、一组断言工厂和一组Filter组成。如果断言为真,则说明请求URL和配置的路由匹配。

格式:

id:我们自定义的路由 ID,保持唯一

uri:目标服务地址

路由配置方式

1.yml配置文件路由
#第一种:ws(websocket)方式: uri: ws://localhost:8888
#第二种:http方式: uri: http://localhost:8888/
#第三种:lb(注册中心中服务名字)方式: uri: lb://consumer
spring:
  cloud:
    gateway:
      routes:
         # 路由id,没有固定规则,建议配合服务名
        - id: consumer
          # 匹配后提供服务的路由地址
          # 需要注意的是uri的协议为lb,表示启用Gateway的负载均衡功能。lb://serviceName是spring cloud gateway在微服务中自动为我们创建的负载均衡uri。
          uri: lb://consumer
          predicates:
          # 断言:路径相匹配的进行路由
            - Path=/**
2.bean进行配置
@Configuration
public class GatewayConfig {
    @Bean
    public RouteLocator customerRouteLocator(RouteLocatorBuilder routeLocatorBuilder) {
        RouteLocatorBuilder.Builder routes = routeLocatorBuilder.routes();
        // 第一个参数是路由的唯一id
        routes.route("consumer",
                r -> r.path("/hello")
                        .uri("http://localhost:8888/hello")).build();
        return routes.build();
    }
}
3.动态路由

可以通过服务名进行转发,无需配置routes也可以转发

spring:
  application:
    name: gateway
  cloud:
    gateway:
      discovery:
        locator:
          #开启根据微服务名称自动转发
          enabled: true
          #小写
          lower-case-service-id: true

动态路由

        默认情况下,Gateway 会根据服务注册中心中维护的服务列表,以服务名作为路径创建动态路由进行转发,从而实现动态路由功能。

形式:

lb://service-name

lb:uri 的协议,表示开启 Spring Cloud Gateway 的负载均衡功能。

service-name:服务名,Spring Cloud Gateway 会根据它获取到具体的微服务地址。

Predicate(断言)

        Predicate 断言来实现 Route 路由的匹配规则。Predicate 是路由转发的判断条件,请求只有满足了 Predicate 的条件,才会被转发到指定的服务上进行处理;

特点

1.路由与断言的关系为:一对多,一个路由可以包含多个不同断言

2.一个请求想转发到指定的路由上,就必须同时匹配路由上的所有断言

3.当一个请求同时满足多个路由的断言条件时,请求只会被首个成功匹配的路由转发

常见断言

示例

配置文件 application.yml中添加配置内容

server:
  port: 9527  #端口号
spring:
  application:
    name: microServiceCloudGateway
  cloud:
    gateway: #网关路由配置
      routes:
        #将 micro-service-cloud-provider-dept-8001 提供的服务隐藏起来,不暴露给客户端,只给客户端暴露 API 网关的地址 9527
        - id: provider_dept_list_routh   #路由 id,没有固定规则,但唯一,建议与服务名对应
          uri: http://localhost:8001          #匹配后提供服务的路由地址
          predicates:
            #以下是断言条件,必选全部符合条件
            - Path=/dept/list/**               #断言,路径匹配 注意:Path 中 P 为大写
            - Method=GET #只能时 GET 请求时,才能访问

配置中在 spring.cloud.gateway.routes 下使用 predicates 属性,定义了以下两个断言条件:

- Path=/dept/list/*

-Method=GET

HTTP 请求同时满足以上所有的断言时,该请求才会被转发到指定的服务端中

 

Filter(过滤器)

        出于安全方面的考虑,服务端提供的服务往往都会有一定的校验逻辑,例如用户登陆状态校验、签名校验等;微服务架构中,系统由多个微服务组成,所有这些服务都需要这些校验逻辑,此时我们就可以将这些校验逻辑写到Gateway的 Filter 过滤器中。

filter分类

Gateway 提供了以下两种类型的过滤器,可以对请求和响应进行精细化控制:

Pre 类型

        这种过滤器在请求被转发到微服务之前可以对请求进行拦截和修改,例如参数校验、权限校验、流量监控、日志输出以及协议转换等操作。

Post 类型

        这种过滤器在微服务对请求做出响应后可以对响应进行拦截和再处理,例如修改响应内容或响应头、日志输出、流量监控等。

网关过滤器

GatewayFilter 是 Gateway 网关中提供的一种应用在单个或一组路由上的过滤器。它可以对单个路由或者一组路由上传入的请求和传出响应进行拦截,并实现一些与业务无关的功能,比如登陆状态校验、签名校验、权限校验、日志输出、流量监控等

格式
    spring:
      cloud:
        gateway: 
          routes:
            - id: xxxx
              uri: xxxx
              predicates:
                - Path=xxxx
              filters:
                - AddRequestParameter=X-Request-Id,1024 #过滤器工厂会在匹配的请求头加上一对请求头,名称为 X-Request-Id 值为 1024
                - PrefixPath=/dept #在请求路径前面加上 /dept
                ……

Gateway 内置了多达 31 种 GatewayFilter,下表中列举了几种常用的网关过滤器及其使用示例:

示例

application.yml 中在添加一个动态路由:

- id: provider_dept_get_routh

        uri: lb://MICROSERVICECLOUDPROVIDERDEPT #使用服务名代替上面的具体带端口         predicates:

                - Path=/get/**

        filters:

                - PrefixPath=/dept #在请求路径上增加一个前缀 /dept

全局过滤器

        GlobalFilter 是一种作用于所有的路由上的全局过滤器,通过它,我们可以实现一些统一化的业务功能,例如权限认证、IP 访问限制等。当某个请求被路由匹配时,那么所有的 GlobalFilter 会和该路由自身配置的 GatewayFilter 组合成一个过滤器链;

示例

1.新建一个名为 MyGlobalFilter 全局过滤器配置类

/**
* 自定义全局网关过滤器(GlobalFilter)
*/
@Component
@Slf4j
public class MyGlobalFilter implements GlobalFilter, Ordered {
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        log.info("进入自定义的全局过滤器 MyGlobalFilter" + new Date());
        String uname = exchange.getRequest().getQueryParams().getFirst("uname");
        if (uname == null) {
            log.info("参数 uname 不能为 null!");
            exchange.getResponse().setStatusCode(HttpStatus.NOT_ACCEPTABLE);
            return exchange.getResponse().setComplete();
        }
        return chain.filter(exchange);
    }
    @Override
    public int getOrder() {
        //过滤器的顺序,0 表示第一个
        return 0;
    }
}

2.使用浏览器访问“http://eureka7001.com:9527/dept/list”,我们会发现访问报 406 错误

3.浏览器访问“http://eureka7001.com:9527/dept/list?uname=123”

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

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

相关文章

智能汽车安全:保护车辆远程控制和数据隐私

第一章&#xff1a;引言 智能汽车技术的快速发展为我们带来了许多便利&#xff0c;但也引发了一系列安全和隐私问题。本文将探讨智能汽车安全的重要性&#xff0c;以及如何保护车辆远程控制和数据隐私。 第二章&#xff1a;智能汽车远程控制 智能汽车的远程控制是一项令人兴…

解释一下React中的钩子(hooks),例如useState和useEffect。

聚沙成塔每天进步一点点 ⭐ 专栏简介 前端入门之旅&#xff1a;探索Web开发的奇妙世界 欢迎来到前端入门之旅&#xff01;感兴趣的可以订阅本专栏哦&#xff01;这个专栏是为那些对Web开发感兴趣、刚刚踏入前端领域的朋友们量身打造的。无论你是完全的新手还是有一些基础的开发…

第二章 基于模型的系统工程 P2|系统建模语言SysML实用指南学习

仅供个人学习记录 建模原则 模型与MBSE方法定义 模型描述的是domain of interest MBSE方法是指以系统模型作为主要制品来实现全部或者部分的系统工程过程 系统建模目的 模型的用途在系统的整个开发全生命周期中是不断完善的&#xff0c;是通过持续完整的需求来描述的。 …

Vue 父子组件传参、插槽

setup 函数中有两个主要的参数&#xff1a;props、context 。 props 用于接收父组件传递过来的数据&#xff0c;父传子。 context 指的是 setup 的上下文&#xff0c;它有三个属性&#xff1a;attrs、slots、emit 。 attrs 用于&#xff1a;当父组件传递过来的数据&#xff…

设计模式(18)桥接模式

一、介绍&#xff1a; 1、定义&#xff1a;桥接(Bridge)模式属于结构型设计模式。通过提供抽象化和实现化之间的桥接结构&#xff0c;来实现二者的解耦。把抽象(abstraction)与行为实现(implementation)分离开来&#xff0c;从而可以保持各部分的独立性以及应对它们的功能扩展…

游戏研发的解决方案有哪些?

游戏研发的解决方案可以根据不同的需求和情境而有所不同&#xff0c;以下是一些常见的游戏研发解决方案&#xff1a; 游戏引擎&#xff1a; 游戏引擎是游戏研发的基础&#xff0c;它提供了开发游戏所需的核心功能&#xff0c;如图形渲染、物理引擎、音效管理、动画等。一些流行…

css四种导入方式

1 行内样式 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>Title</title> </head> <body> <h1 style"color: blue">我是标题</h1> </body> </htm…

简单电子琴设计verilog蜂鸣器8音阶,视频/代码

名称&#xff1a;简单电子琴设计verilog 软件&#xff1a;QuartusII 语言&#xff1a;Verilog 代码功能&#xff1a; 简易电子琴电路 1、输入为8个按键&#xff0c;每个按键对应一个音阶 2、输出为speaker蜂鸣器&#xff0c;当其中一直按键按下时&#xff0c;输出特定频率…

k8s 部署nginx前端

1.构建docker镜像&#xff0c;k8s拉取镜像运行 ​​​​​​​docker自己安装 [rootmaster1 ~]# docker pull nginx:1.24.0 [rootmaster1 ~]# mkdir k8s-nginx [rootmaster1 ~]# cd k8s-nginx [rootmaster1 k8s-nginx]# vim nginx.conf server_tokens off;server {listen …

第四章 文件管理 七、文件共享

目录 一、基于索引结点的共享方式&#xff08;硬链接) 1、知识回顾&#xff1a; 2、例子&#xff1a; 二、基于符号链的共享方式&#xff08;软链接) 1、例子 三、总结 一、基于索引结点的共享方式&#xff08;硬链接) 1、知识回顾&#xff1a; 索引结点&#xff0c;是一…

前端《中国象棋》游戏

源码下载地址 支持&#xff1a;远程部署/安装/调试、讲解、二次开发/修改/定制 查看视频 本程序是一个基于Html/css/javascrip的网页端象棋APP&#xff0c;其中引入JQuery来简便开发。 在程序中&#xff0c;使用一个Map二维数组来表示棋盘&#xff0c;通过给棋子设置不同的横坐…

【Gradle-11】动态修改VersionName和VersionCode

前言 有个读者问了一个比较有意思又很常见的问题&#xff0c;怎么修改VersionName和VersionCode&#xff1f; 这位读者提问的方式也挺好&#xff0c;报错信息和尝试过的方式都提到了。 关于报错以及解决方案&#xff0c;正如上图我评论回复所说。 静态修改直接在build.gradl…

canvas 状态管理

本文简介 带尬猴&#xff0c;我是德育处主任 canvas 绘图时会根据当前状态来绘制。很多的 canvas 库都利用到这一特性。比如 p5.js 利用了 canvas 状态特性衍生出 push 和 pop 函数实现状态隔离&#xff08;既然提到了&#xff0c;下一篇就讲这个&#xff09;。 有兴趣了解 p…

Fabric.js 样式不更新怎么办?

本文简介 带尬猴&#xff0c;我嗨德育处主任 不知道你有没有遇到过在使用 Fabric.js 时无意中一些骚操作修改了元素的样式&#xff0c;但刷新画布却没更新元素样式&#xff1f; 如果你也遇到同样的问题的话&#xff0c;可以尝试使用本文的方法。 是否需要重新绘制 我先举个例…

Linux - firewall-cmd 命令添加端口规则不生效排查

文章目录 linux 防火墙 firewall-cmd 命令详解问题排查 linux 防火墙 firewall-cmd 命令详解 基本语法 firewall-cmd --zonezone-name --add-serviceservice-name --permanent命令参数 --zone&#xff1a;指定要添加服务的区域名称。 --add-service&#xff1a;指定要添加的…

开源利器:it-tools 项目介绍

作为一名开发人员&#xff0c;我们在日常工作和学习中常常需要使用一系列小工具&#xff0c;如JSON格式化、JSON转表格、当前时间戳、XML格式化、SQL格式化、密码生成以及UUID生成等。通常情况下&#xff0c;我们会在网上搜索各种在线工具来满足这些需求。然而&#xff0c;这些…

vue3实现图片裁剪上传功能

1、安装引入vue-cropper&#xff08;可参考&#xff1a;https://www.npmjs.com/package/vue-cropper&#xff09; npm install vue-croppernextimport vue-cropper/dist/index.cssimport { VueCropper } from "vue-cropper"; 2、组件完整代码 <template><…

SpringMVC Day 03 : 处理静态资源

前言 欢迎来到第三天的 SpringMVC 学习系列&#xff01;在前两天的教程中&#xff0c;我们已经学习了如何搭建 SpringMVC 环境、创建控制器和处理请求等基础知识。今天&#xff0c;我们将继续探索 SpringMVC 的功能&#xff0c;并学习如何处理静态资源。 在现代 Web 应用程序…

CloudQuery + StarRocks:打造高效、安全的数据库管控新模式

随着技术的迅速发展&#xff0c;各种多元化的数据库产品应运而生&#xff0c;它们不仅类型众多&#xff0c;而且形式各异&#xff0c;国产化数据库千余套&#xff0c;开源数据库百余套 OceanBase 、PolarDB 、StarRocks…还有一些像 Oracle、MySQL 这些传统数据库。这些数据库产…

php+JavaScript实现callback跨域请求jsonp数据

摘要 JSONP 是 JSON with Padding 的缩写&#xff0c;是一种解决跨域数据获取的方案。由于浏览器的同源策略限制&#xff0c;不同域名之间的前端JS代码不能相互访问到对方的数据&#xff0c;JSONP通过script标签的特性&#xff0c;实现在不同域名的网页间传递数据。 其原理是…