SpringCloud之微服务API网关Gateway介绍

文章目录

  • 1 微服务API网关Gateway
    • 1.1 网关简介
    • 1.2 Spring Cloud Gateway介绍
    • 1.3 Gateway特性
    • 1.4 Gateway核心概念
      • 1.4.1 路由
        • 1.4.1.1 定义
        • 1.4.1.2 动态路由
      • 1.4.2 断言
        • 1.4.2.1 默认断言
        • 1.4.2.2 自定义Predicate
      • 1.4.3 过滤器
        • 1.4.3.1 默认过滤器
        • 1.4.3.2 自定义Filter(GatewayFilter)
        • 1.4.3.2 自定义Filter(GlobalFilter)
        • 1.4.3.3 自定义Filter(AbstractGatewayFilterFactory)
    • 1.5 Gateway工作流程
    • 1.6 实际操作
      • 1.6.1 pom.xml
      • 1.6.2 启动类
      • 1.6.3 配置文件 application.yml

1 微服务API网关Gateway

1.1 网关简介

如果没有网关,难道不行吗?功能上是可以的,我们直接调用提供的接口就可以了。那为什么还需要网关?

因为网关的作用不仅仅是转发请求而已。我们可以试想一下,如果需要做一个请求认证功能,我们可以接入到 API 服务中。但是倘若后续又有服务需要接入,我们又需要重复接入。这样我们不仅代码要重复编写,而且后期也不利于维护。

由于接入网关后,网关将转发请求。所以在这一层做请求认证,天然合适。这样这需要编写一次代码,在这一层过滤完毕,再转发给下面的 API。所以 API 网关的通常作用是完成一些通用的功能,如请求认证,请求记录,请求限流,黑白名单判断等。

API网关是一个服务器,是系统的唯一入口。
API网关方式的核心要点是,所有的客户端和消费端都通过统一的网关接入微服务,在网关层处理所有的非业务功能。通常,网关提供REST/HTTP的访问API。

1.2 Spring Cloud Gateway介绍

Spring Cloud GatewaySpring Cloud 的新一代API网关,基于WebFlux框架实现,它旨在为微服务架构提供一种简单而有效的统一的API路由管理方式。
Spring Cloud Gateway作为Spring Cloud生态系统中的网关,目标是替代Netflix ZUUL,具有更好的性能、更强的扩展性、以及更丰富的功能特性,其不仅提供统一的路由方式,并且基于Filter链的方式提供了网关基本的功能,例如:安全,监控/埋点,限流等。

1.3 Gateway特性

Spring Cloud Gateway特性:

  • 基于Spring Framework 5, Project Reactor和Spring Boot 2.0
  • 动态路由:能够匹配任何请求属性
  • 可以对路由指定 Predicate 和 Filter
  • 集成Hystrix断路器
  • 集成 Spring Cloud DiscoveryClient 服务发现功能
  • 易于编写的Predicate和Filter
  • 请求限流
  • 支持路径重写

1.4 Gateway核心概念

1.4.1 路由

1.4.1.1 定义

路由(Route)是网关最基础的部分,路由信息由一个ID,一个目标URI,一组断言过滤器组成。路由断言Predicate用于匹配请求,过滤器 Filter 用于修改请求和响应。如果断言为true,则说明请求URI和配置匹配,则执行路由。

spring:cloud:gateway:# 定义多个路由routes:# 一个路由route的id- id: path_route# 该路由转发的目标URIuri: https://example.org# 路由条件集合predicates:- Path=/test/**# 过滤器集合filters:- AddRequestHeader=X-Request-Id, 1024- AddRequestParameter=color, red

1.4.1.2 动态路由

网关接收外部请求,按照一定的规则,将请求转发给其他服务或者应用。如果站在服务调用的角度,网关就扮演着服务消费者的角色,此时,如果再来看看服务调用的目标URI配置,就会很自然的发现一个问题,服务提供者调用的地址是写死的,即网关没有动态的发现服务,这就涉及到了服务的自动发现问题,以及发现服务后,所涉及到的服务调用的负载均衡的问题。

可以通过Nacos或者Eureka注册中心动态发现服务,通过Ribbon进行服务调用的负载均衡。同样,Gateway也可以整合Nacos或者EurekaRibbon从而实现动态路由的功能。

想要使用动态路由的功能,首先要整合注册中心,这里以Nacos为例

pom依赖

<!--SpringCloud ailibaba nacos -->
<dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>

配置文件

spring:application:name: cloud-gatewaycloud:nacos:discovery:server-addr: localhost:8848gateway:routes:#路由的ID,没有固定规则但要求唯一,建议配合服务名- id: config_route#匹配后提供服务的路由地址, 这里lb之后,跟的是要调用的服务名称uri: lb://nacos-provider-8002# 断言,路径相匹配的条件predicates:- Path=/routeconfig/rest/**

此时,当id为config_route的路由规则匹配某个请求后,在调用该请求对应的服务时,就会从nacos注册中心自动发现服务,并在服务调用的时候实现负载均衡。

1.4.2 断言

断言(Predicate)参考Java8 中的断言 Predicate ,用于实现请求匹配逻辑,例如匹配路径、请求头、请求参数等。请求与断言匹配则执行该路由。

Gateway中,有一些的内置Predicate Factory,有了这些Pridicate Factory,在运行时,Gateway 会自动根据需要创建其对应的 Pridicate 对象测试路由条件。

1.4.2.1 默认断言

Gateway提供的断言有:Path 路由断言,After 路由断言,Cookie 路由断言,Header 路由断言 ,Host 路由断言 ,Method 路由断言
Path 路由断言 Factory: 根据请求路径匹配的路由条件工厂

spring:cloud:gateway:routes:- id: path_routeuri: https://example.orgpredicates:# 如果可以匹配的PathPattern有多个,则每个路径模式以,分开- Path=/red/{segment},/blue/{segment}

After 路由断言 Factory: 在指定日期时间之后发生的请求都将被匹配

spring:cloud:gateway:routes:- id: after_routeuri: https://example.orgpredicates:- After=2017-01-20T17:42:47.789-07:00[America/Denver]

Cookie 路由断言 FactoryCookie 路由断言 Factory有两个参数,cookie名称和正则表达式。请求包含此cookie名称且正则表达式为真的将会被匹配。

spring:cloud:gateway:routes:- id: cookie_routeuri: https://example.orgpredicates:- Cookie=chocolate, ch.p

Header 路由断言 FactoryHeader 路由断言 Factory有两个参数,header名称和正则表达式。请求包含此header名称且正则表达式为真的将会被匹配。

spring:cloud:gateway:routes:- id: header_routeuri: https://example.orgpredicates:- Header=X-Request-Id, \d+

Host 路由断言 FactoryHost 路由断言 Factory包括一个参数:host name列表。使用Ant路径匹配规则, . 作为分隔符。

spring:cloud:gateway:routes:- id: host_routeuri: https://example.orgpredicates:- Host=**.somehost.org,**.anotherhost.org

Method 路由断言 FactoryMethod 路由断言 Factory只包含一个参数:需要匹配的HTTP请求方式

spring:cloud:gateway:routes:- id: method_routeuri: https://example.orgpredicates:- Method=GET

1.4.2.2 自定义Predicate

可以自定义Predicate来实现复杂的路由匹配规则

实现自定义 Predicate 工厂
通过HostRoutePredicateFactory创建Predicate进行路由判断
@Component
public class MyHostRoutePredicateFactory extends AbstractRoutePredicateFactory<MyHostRoutePredicateFactory.Config> {public MyHostRoutePredicateFactory() {// Config 类作为 Predicate 的配置参数类super(Config.class);}public static class Config {// 路由匹配规则private String hostName;public String getHostName() {return hostName;}public void setHostName(String hostName) {this.hostName = hostName; }}// 生成一个 Predicate 实例@Overridepublic Predicate<ServerWebExchange> apply(Config config) {// 实现匹配逻辑return exchange -> {// 根据config实现匹配判断         String host = exchange.getRequest().getURI().getHost();// 匹配配置中的域名return host.equals(config.getHostName());};} 
}

使用

RouteLocator locator = new RouteLocatorBuilder(router).routes().route("test_route", r -> r.path("/test").filters(f -> f.filter(new MyHostRoutePredicateFactory.Config("www.test.com"))).uri("http://localhost:8080")).build();

1.4.3 过滤器

过滤器(Filter) 指的是Spring框架中GatewayFilter的实例,使用过滤器,可以在请求被路由前后对请求进行修改

1.4.3.1 默认过滤器

配置文件中添加过滤器 filters

filters:- AddRequestHeader=name,zs          #请求头添加name:zs- AddRequestParameter=color,blue    #请求参数添加color:blue- AddResponseHeader=phone,973345344 #响应头添加phone:973345344- PrefixPath=/mypath			    #添加路径前缀/mypath- StripPrefix=n					    #删除路径前缀n个

Spring Cloud Gateway内置的多种过滤器类,例如:

  • AddRequestHeader GatewayFilter:在请求头中添加参数
  • PrefixPath GatewayFilter:请求路径前缀
  • Hystrix GatewayFilter:断路器
  • RateLimit GatewayFilter:限流
  • Retry GatewayFilter:重试

1.4.3.2 自定义Filter(GatewayFilter)

可以通过实现GatewayFilterOrdered接口自定义Filter来实现请求处理逻辑:

@Component
public class TokenFilter implements GatewayFilter, Ordered {@Overridepublic Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {//请求处理逻辑log.info("请求路径:"+ exchange.getRequest().getPath());ServerHttpRequest request = exchange.getRequest();MultiValueMap<String, HttpCookie> cookies = request.getCookies();List<HttpCookie> tokens = cookies.get("access_token");if (tokens == null || tokens.size() == 0) {throw new RuntimeException("少了cookie!");}return chain.filter(exchange);}@Overridepublic int getOrder() {return 0; }
}

1.4.3.2 自定义Filter(GlobalFilter)

public class MyFilter implements GlobalFilter {@Overridepublic Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {ServerHttpRequest request = exchange.getRequest();ServerHttpResponse response = exchange.getResponse();return null;}
}

1.4.3.3 自定义Filter(AbstractGatewayFilterFactory)

通过继承AbstractGatewayFilterFactory来实现

public class DemoGatewayFilterFactory extends AbstractGatewayFilterFactory<DemoGatewayFilterFactory.Config> {@Overridepublic GatewayFilter apply(Config config) {return null;}//Config 静态内部类,负责指定网关的参数static class Config{private String arg1;}
}

注意DemoGatewayFilterFactory 的命名方式:由Demo + GatewayFilterFactory组成,
其中Demo是自己起名字,GatewayFilterFactory是固定的。
范型中的Config是我们待会要用到的静态内部类,用于声明过滤器中传递的参数

Spring Cloud Gateway中,自定义的过滤器会在全局过滤器链中生效,不需要显式配置在路由配置中。这是因为AbstractGatewayFilterFactory类已经实现了GatewayFilterFactory接口,并且通过Spring的自动装配机制将其注册到全局过滤器链中,并且可以在任何路由上生效。

需要注意的是,在全局过滤器链中的顺序是根据Spring Bean加载顺序决定的。可以通过设置@Order注解或实现Ordered接口来控制自定义过滤器在全局过滤器链中的顺序。

1.5 Gateway工作流程

客户端向 Spring Cloud Gateway发出请求,然后在Gateway Handler Mapping中找到与请求相匹配的路由,将其发送到 Gateway Web HandlerHandler再通过指定的过滤器链来对请求进行过滤处理,最后发送到我们实际的服务执行业务逻辑,然后返回。
在这里插入图片描述
过滤器链被虚线分隔,是因为过滤器既可以在转发请求前拦截请求,也可以在请求处理之后对响应进行拦截处理。

1.6 实际操作

1.6.1 pom.xml

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

1.6.2 启动类

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

1.6.3 配置文件 application.yml

spring: application:name: cloud-gateway cloud:gateway:routes:# 路由的ID,没有固定规则但要求唯一,建议配合服务名- id: config_route# 匹配后提供服务的路由地址uri: http://ityouknow.com# 断言,路径相匹配的条件predicates:- Path=/routeconfig/rest/**- id: header_routeuri: http://ityouknow.compredicates:- Header=X-Request-Id, \d+

参考连接:
https://mp.weixin.qq.com/s/LY66FPCajHkzXJUFlfSNYg
https://blog.csdn.net/h1774733219/article/details/124384527
https://blog.csdn.net/qq_46203643/article/details/127150590

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

react18 之 06 之 useReducer 结合 useContext使用 (实现全局状态管理、复杂组件交互逻辑、多个组件需要共享和更新某个状态)

目录 react18 之 06 之 useReducer 结合 useContext使用 (实现全局状态管理、复杂组件交互逻辑、多个组件需要共享和更新某个状态)useReducer 结合 useContext使用 实现全局共享RootCom.jsxA.jsxASon.jsxB.jsxC.jsx执行效果 react18 之 06 之 useReducer 结合 useContext使用 (…

【Excel】记录Match和Index函数的用法

最近一直用到的两个处理EXCEL表格数据的函数向大家介绍一下&#xff0c;写这篇博文的目的也是为了记录免得自己忘记了&#xff0c;嘻嘻。 先上百度的链接 Match函数的用法介绍&#xff1a;https://jingyan.baidu.com/article/2fb0ba40b4933941f3ec5f71.html 小结&#xff1a;…

【云原生持续交付和自动化测试】5.2 自动化测试和集成测试

往期回顾&#xff1a; 第一章&#xff1a;【云原生概念和技术】 第二章&#xff1a;【容器化应用程序设计和开发】 第三章&#xff1a;【基于容器的部署、管理和扩展】 第四章&#xff1a;【微服务架构设计和实现】 第五章&#xff1a;【5.1 自动化构建和打包容器镜像】 5…

【雕爷学编程】MicroPython动手做(27)——物联网之掌控板小程序2

知识点&#xff1a;什么是掌控板&#xff1f; 掌控板是一块普及STEAM创客教育、人工智能教育、机器人编程教育的开源智能硬件。它集成ESP-32高性能双核芯片&#xff0c;支持WiFi和蓝牙双模通信&#xff0c;可作为物联网节点&#xff0c;实现物联网应用。同时掌控板上集成了OLED…

「从零入门推荐系统」22:chatGPT、大模型在推荐系统中的应用

作者 | gongyouliu 编辑 | gongyouliu 提示&#xff1a;全文2.5万字&#xff0c;预计阅读时长2小时&#xff0c;可以先收藏再慢慢阅读。 我们在上一章介绍了chatGPT、大模型的基本概念、核心技术原理等基础知识&#xff0c;有了这些背景知识的铺垫&#xff0c;下面我们来介绍ch…

Laravel 框架安装路由和控制器 ①

作者 : SYFStrive 博客首页 : HomePage &#x1f4dc;&#xff1a; THINK PHP &#x1f4cc;&#xff1a;个人社区&#xff08;欢迎大佬们加入&#xff09; &#x1f449;&#xff1a;社区链接&#x1f517; &#x1f4cc;&#xff1a;觉得文章不错可以点点关注 &#x1f44…

【Shell】基础语法(一)

文章目录 一、shell的介绍二、执行脚本三、shell的基本语法1. 变量的使用2. 变量的分类 一、shell的介绍 Shell的作用是解释执行用户的命令&#xff0c;用户输入一条命令&#xff0c;Shell就解释执行一条&#xff0c;这种方式称为交互式&#xff08;Interactive&#xff09;&a…

介绍Sping Boot的5个扩展点

1、初始化器ApplicationContextInitializer 我们在启动Spring Boot项目的时候&#xff0c;是执行这样一个方法来启动的 我们一层一层往下点&#xff0c;最终发现执行的是这个方法 所以我们在启动项目的时候也可以这样启动 new SpringApplication(SpringbootExtensionPointAp…

ubuntu22安装如何安装window软件(.exe)

ubuntu未提供相应程序安装包&#xff0c;如何使用的ubuntu22.04 安装window提供的exe程序呢&#xff1f; 这里我了解有两种方案&#xff1a; 使用模拟器进行window程序的运行&#xff0c;但是肯定会有相应的性能损耗如&#xff08;wine&#xff09;在linux上运行virtualbox或…

React Native获取手机屏幕宽高(Dimensions)

import { Dimensions } from react-nativeconsole.log(Dimensions, Dimensions.get(window)) 参考链接&#xff1a; https://www.reactnative.cn/docs/next/dimensions#%E6%96%B9%E6%B3%95 https://chat.xutongbao.top/

嵌入式开发学习(STC51-7-矩阵按键)

内容 按下S1-S16键&#xff0c;对应数码管最左边显示0-F 矩阵按键简介 独立按键与单片机连接时&#xff0c;每一个按键都需要单片机的一个I/O 口&#xff0c;若某单片机系统需较多按键&#xff0c;如果用独立按键便会占用过多的I/O口资源&#xff1b;而单片机 系统中I/O口资…

Flutter运行app时向logcat输出当前打开的界面路径且点击可跳转

当一个项目大了目录文件多了&#xff0c;我们往往会为了找到一个文件花费大量的时间和精力&#xff0c;为了快捷方便的调试我们的项目&#xff0c;我们往往需要在打开app运行的时候需要知道当前打开的界面的文件在哪儿&#xff0c;我们这个代码就能快捷的知道我们app正在打开的…