Gateway简述

前言

​ 在微服务架构中,一个系统会被拆分为很多个微服务。那么作为客户端调用多个微服务接口的地址。另外微服务架构的请求中,90%的都携带认证信息/用户登录信息,都需要做相关的限制管理,API网关由此应允而生。

这样的架构会存在许多的问题:

  1. 客户端多次请求不同的微服务,增加客户端代码或配置编写的复杂性。
  2. 认证复杂,每个服务都需要独立认证。
  3. 存在跨域请求,在一定场景下处理相对复杂。

所谓的API网关,就是指系统的统一入口,它封装了应用程序的内部结构,为客户端提供统一服务,一些与业务本身功能无关的公共逻辑可以在这里实现,诸如认证、鉴权、监控、路由转发等等。

网关的核心功能特性:

  • 请求路由
  • 权限控制
  • 限流

常见网关

1)Ngnix+lua

基于Nginx+Lua开发,性能高,稳定,有多个可用的插件(限流、鉴权等等)可以开箱即用。

​ 使用nginx的反向代理和负载均衡可实现对api服务器的负载均衡及高可用。 lua是一种脚本语言,可以来编写一些简单的逻辑, nginx支持lua脚本。

缺点:

  1. 只支持Http协议。
  2. 二次开发,自由扩展困难。
  3. 提供管理API,缺乏更易用的管控、配置方式。

2)Zuul

​ Zuul的路由功能实现了统一处理外部请求的功能,负责将外部请求转发到具体的微服务实例上,是实现外部访问统一入口的基础。zuul还提供过滤器功能,负责对请求的处理过程进行干预,是实现请求校验、服务聚合等功能的基础。Zuul的底层基于Servlet,本质上就是一系列的filter过滤器,也是它的核心。Zuul2是采用Netty实现异步IO。

缺点:

  1. 缺乏管控,无法动态配置。
  2. 依赖组件较多。
  3. 处理Http请求依赖的是Web容器,性能不如Nginx。

3)Gateway

底层使用了高性能的通信框架Netty,提供了异步支持,提供了抽象负载均衡,提供了抽象流控,并默认实现了RedisRateLimiter

介绍

​ Spring Cloud Gateway基于 Spring 5.0,Spring Boot 2.0 和 Project Reactor 等技术开发的网关,它旨在为微服务架构提供一种简单有效的统一的 API 路由管理方式。基于 Filter 链的方式提供了网关基本的功能,例如:安全,监控/指标,和限流。底层使用了高性能的通信框架Netty,提供了异步支持,提供了抽象负载均衡,提供了抽象流控,并默认实现了RedisRateLimiter。

为了提升网关的性能,SpringCloud Gateway是基于WebFlux框架实现的,而WebFlux框架底层则使用了高性能的Reactor模式通信框架Netty。

特性

(1)基于 Spring Framework 5,Project Reactor 和 Spring Boot 2.0

(2)可集成 Hystrix 、Sentinel实现熔断降级

(3)集成 Spring Cloud DiscoveryClient

(4)Predicates 和 Filters 作用于特定路由,易于编写的 Predicates 和 Filters

(5)具备一些网关的高级功能:动态路由、限流、路径重写

三大核心概念:

Filter(过滤器):

​ **使用它拦截和修改请求,并且对上游的响应,进行二次处理。**org.springframework.cloud.gateway.filter.GatewayFilter的实例,用于请求被路由前或者之后对请求进行修改。

pre类型

​ Filter在pre类型的过滤器可以做参数效验、权限效验、流量监控、日志输出、协议转换等。

post类型

​ Filter在post类型的过滤器可以做响应内容、响应头的修改、日志输出、流量监控等

Route(路由):

​ 网关配置的基本组成模块,和Zuul的路由配置模块类似。一个Route模块由一个 ID,一个目标 URI,一组断言和一组过滤器定义。如果断言为真,则路由匹配,目标URI会被访问。

Predicate(断言):

​ 这是一个 Java 8 的 Predicate。输入类型是一个 ServerWebExchange。可以使用它来匹配来自 HTTP 请求的任何内容,例如 headers 或参数。如果请求与断言相匹配则进行路由。

Gateway核心架构

1、路由 Route

​ 路由(Route) 是 gateway 中最基本的组件之一,表示一个具体的路由信息载体。主要定义了下面的几个信息:

  1. id:路由标识符,区别于其他 Route。
  2. uri:路由指向的目的地 uri,即客户端请求最终被转发到的微服务。
  3. order:用于多个 Route 之间的排序,数值越小排序越靠前,匹配优先级越高。
  4. predicate:断言的作用是进行条件判断,只有断言都返回真,才会真正的执行路由。
  5. filter:过滤器用于修改请求和响应信息。
  6. predicate:断言,用于进行条件判断,只有断言都返回真,才会真正的执行路由。

2、过滤器

Gateway的过滤器的作用是:是在请求的传递过程中,对请求和响应做一些手脚。

1)Gateway的过滤器的生命周期:

​ Pre:这种过滤器在请求被路由之前调用。可利用这种过滤器实现身份验证、在集群中选择 请求的微服务、记录调试信息等。

​ Post:这种过滤器在路由到微服务以后执行。这种过滤器可用来为响应添加标准的HTTP Header、收集统计信息和指标、将响应从微服务发送给客户端等。

Gateway 的Filter从作用范围可分为两种: GatewayFilter与GlobalFilter。GatewayFilter:应用到单个路由或者一个分组的路由上;GlobalFilter:应用到所有的路由上。

2)GatewayFilter 局部过滤器

​ 局部过滤器是针对单个路由的过滤器。他分为内置过滤器和自定义过滤器。在SpringCloud Gateway中内置了很多不同类型的网关路由过滤器。

内置的局部过滤器内容
过滤器工厂作用参数
AddRequestHeader为原始请求添加HeaderHeader的名称及值
AddRequestParameter为原始请求添加请求参数参数名称及值
AddResponseHeader为原始响应添加HeaderHeader的名称及值
DedupeResponseHeader剔除响应头中重复的值需要去重的Header名称及去重策略
Hystrix为路由引入Hystrix的断路器保护HystrixCommand 的名称
FallbackHeaders为fallbackUri的请求头中添加具体的异常信息Header的名称
PrefixPath为原始请求路径添加前缀前缀路径
PreserveHostHeader为请求添加一个preserveHostHeader=true的属性,路由过滤器会检查该属性以决定是否要发送原始的Host
RequestRateLimiter用于对请求限流,限流算法为令牌桶keyResolver、 rateLimiter、 statusCode、 denyEmptyKey、 emptyKeyStatus
RedirectTo将原始请求重定向到指定的URLhttp状态码及重定向的url
RemoveHopByHopHeadersFilter为原始请求删除IETF组织规定的一系列Header默认就会启用,可以通过配置指定仅删除哪些Header
RemoveRequestHeader为原始请求删除某个HeaderHeader名称
RemoveResponseHeader为原始响应删除某个HeaderHeader名称
RewritePath重写原始的请求路径原始路径正则表达式以及重写后路径的正则表达式
RewriteResponseHeader重写原始响应中的某个HeaderHeader名称,值的正则表达式,重写后的值
SaveSession在转发请求之前,强制执行WebSession::save操作
secureHeaders为原始响应添加一系列起安全作用的响应头无,支持修改这些安全响应头的值
SetPath修改原始的请求路径修改后的路径
SetResponseHeader修改原始响应中某个Header的值Header名称,修改后的值
SetStatus修改原始响应的状态码HTTP 状态码,可以是数字,也可以是字符串
StripPrefix用于截断原始请求的路径使用数字表示要截断的路径的数量
Retry针对不同的响应进行重试retries、statuses、methods、series
RequestSize设置允许接收最大请求包的大小。如果请求包大小超过设置的值,则返回 413 Payload Too Large请求包大小,单位为字节,默认值为5M
ModifyRequestBody在转发请求之前修改原始请求体内容修改后的请求体内容
ModifyResponseBody修改原始响应体的内容修改后的响应体内容

​ 当内置过滤器没有办法满足需求的时候,就可以通过继承AbstractGatewayFilterFactory来实现自定义过滤器。

3)GlobalFilter 全局过滤器

全局过滤器作用于所有路由, 无需配置。通过全局过滤器可以实现对权限的统一校验,安全性验证等功能。SpringCloud Gateway内部也是通过一系列的内置全局过滤器对整个路由转发进行处理。

网关全局过滤器

全局过滤器常用于访问鉴权,大概执行逻辑如下:

  • 当客户端第一次请求服务时,服务端对用户进行信息认证(登录)。

  • 认证通过,将用户信息进行加密形成token,返回给客户端,作为登录凭证。

  • 以后每次请求,客户端都携带认证的token。

  • 服务端对token进行解密,判断是否有效。

    //鉴权示例
    @Component
    public class AuthGlobalFilter implements GlobalFilter {@Overridepublic Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {String token = exchange.getRequest().getQueryParams().getFirst("token");if (StringUtils.isBlank(token)) {System.out.println("鉴权失败");exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);return exchange.getResponse().setComplete();}return chain.filter(exchange);}
    }

网关限流

​ 网关是所有请求的公共入口,所以可以在网关进行限流。可以采用Sentinel组件/Hystrix组件来实现网关的限流。

从1.6.0版本开始,Sentinel提供了SpringCloud Gateway的适配模块,可以提供两种资源维度的限流:

  • route维度:即在Spring配置文件中配置的路由条目,资源名为对应的routeId
  • 自定义API维度:用户可以利用Sentinel提供的API来自定义一些API分组

​ 当在限流的时候,不想返回默认的错误,那么就需要自定义错误,指定自定义的返回格式。

//route维度
@PostConstruct
public void initBlockHandlers() {BlockRequestHandler blockRequestHandler = new BlockRequestHandler() {public Mono<ServerResponse> handleRequest(ServerWebExchange serverWebExchange, Throwable throwable) {Map map = new HashMap<>();map.put("code", 0);map.put("message", "接口被限流了");return ServerResponse.status(HttpStatus.OK).contentType(MediaType.APPLICATION_JSON).body(BodyInserters.fromValue(map));}
};GatewayCallbackManager.setBlockHandler(blockRequestHandler);
}
//--------------------------------------------------------------------
//自定义API维度
@PostConstruct
private void initCustomizedApis() {Set<ApiDefinition> definitions = new HashSet<>();ApiDefinition api1 = new ApiDefinition("order_api").setPredicateItems(new HashSet<ApiPredicateItem>() {{add(new ApiPathPredicateItem().setPattern("/order-serv/api/**").                 setMatchStrategy(SentinelGatewayConstants.URL_MATCH_STRATEGY_PREFIX));}});definitions.add(api1);GatewayApiDefinitionManager.loadApiDefinitions(definitions);
}
@PostConstruct
private void initGatewayRules() {Set<GatewayFlowRule> rules = new HashSet<>();rules.add(new GatewayFlowRule("product_route").setCount(3).setIntervalSec(1));rules.add(new GatewayFlowRule("order_api").setCount(1).setIntervalSec(1));GatewayRuleManager.loadRules(rules);
}

执行流程

  • Gateway Client 向 Spring Cloud Gateway 发送请求
  • 请求首先会被 HttpWebHandlerAdapter 进行提取组装成网关上下文
  • 然后网关的上下文会传递到 DispatcherHandler ,它负责将请求分发给 RoutePredicateHandlerMapping
  • RoutePredicateHandlerMapping 负责路由查找,并根据路由断言判断路由是否可用
  • 如果过断言成功,由FilteringWebHandler 创建过滤器链并调用
  • 通过特定于请求的 Fliter 链运行请求,Filter 被虚线分隔的原因是Filter可以在发送代理请求之前(pre)和之后(post)运行逻辑
  • 执行所有pre过滤器逻辑。然后进行代理请求。发出代理请求后,将运行“post”过滤器逻辑。
  • 处理完毕之后将 Response 返回到 Gateway 客户端

其他

1、Nginx网关和Gateway网关的区别

Nignx是流量网关,Gateway是业务网关。 一般流量网关配置在前,业务网关配置在后。

​ 流量网关相当于访问的一个总入口,前端页面的一个容器,类似于防火。主要的功能有管理日志,流量监控,黑白名单,请求的负载均衡,全局限流等。Nginx是C语言写的,Nginx主要是负载均衡,反向代理,以及做web服务器。

而业务网关是针对具体的后端应用和服务,主要的功能是缓存策略、鉴权策略等。GateWay是java语言写的,Gateway主要是路由、断言和过滤器,利用这些可以做流控。

2、Gateway 组件缺陷以及优化思路

问题1、每次请求级别都会重新组装出一个 FilterChain,并进行排序,内存分配和排序会占用 CPU

问题2、在默认情况下,如果其中一个路由配置出错了,会导致整个网关路由不可用,除非 isFailOnRouteDefinitionError 被关闭。

问题3、路由内存优化,同一份路由的配置内容竟然以 3 种形式常驻于内存中。

问题4、内存泄漏优化。通讯底座是netty,通信内容较大时,例如文件上传,则会触发内存的新分配,而 SpringCloud Gateway 在对接 netty 时存在逻辑缺陷,会导致新分配的池化内存无法完全回收,导致堆外内存泄漏。并且这块堆外内存时 netty 使用 unsafe 自行分配的,通过常规的 JVM 工具还无法观测,非常隐蔽。

问题5、预构建 URI 。针对不可变对象的一次变更,从而进行了一次深拷贝,重新重构了一个 URI

问题6、对象缓存。尽量避免调用链路中出现 new 关键字,它会加大 CPU 的开销,从而影响 IO,可以使用 ThreadLocal 或者对象池化技术进行对象复用。

来自SpringCloud Gateway 在微服务架构下的最佳实践

3、登录鉴权图

在这里插入图片描述

总结

​ Gateway主要用于为微服务架构提供一种简单有效的统一的 API 路由管理方式,主要用于微服务API共性做统一要求。采用Filter链的形式,对API做了请求头部信息做限制,对微服务常用的认证授权也做了对应限制,并可对高并发进行流量限制。经过层层过滤之后,对请求接口进行服务接口路由到对应的服务接口。

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

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

相关文章

DevOps系列文章之 Python基础

列表 Python中的列表类似于C语言中的数组的概念&#xff0c;列表由内部的元素组成&#xff0c;元素可以是任何对象 Python中的列表是可变的 简单的理解就是&#xff1a;被初始化的列表&#xff0c;可以通过列表的API接口对列表的元素进行增删改查 1、定义列表 1.可以将列表当成…

《2023年网信人才培训-网络安全从业人员能力素养提升培训》第一期成功举办

随着网络强国和数字中国建设的步伐加快&#xff0c;建设规模宏大、结构合理、素质优良的人才队伍成为一项重要工作。知了汇智作为数字产教融合基地&#xff0c;通过与高校、企业等多方合作&#xff0c;建立了完整的网络安全人才培养生态链。凭借自身技术优势和丰富的产业资源&a…

m4s格式转换mp4

先安装 ffmpeg&#xff0c;具体从官网可以查到&#xff0c;https://ffmpeg.org&#xff0c;按流程走。 转换代码如下&#xff0c;可以任意选择格式导出 import subprocess import osdef merge_audio_video(input_audio_path, input_video_path, output_mp4_path):# 构建 FFmpe…

呈现数据的精妙之道:选择合适的可视化方法

在当今数据时代&#xff0c;数据可视化已成为理解和传达信息的重要手段。然而&#xff0c;选择适合的数据可视化方法对于有效地呈现数据至关重要。不同的数据和目标需要不同的可视化方法&#xff0c;下面我们将探讨如何选择最佳的数据可视化方法来呈现数据。 1. 理解数据类型&a…

在线OJ平台项目

一、项目源码 Online_Judge yblhlk/Linux课程 - 码云 - 开源中国 (gitee.com) 二、所用技术与开发环境 1.所用技术: MVC架构模式 (模型&#xff0d;视图&#xff0d;控制器) 负载均衡系统设计 多进程、多线程编程 C面向对象编程 & C 11 & STL 标准库 C Boost 准标…

【前端】CSS技巧与样式优化

目录 一、前言二、精灵图1、什么是精灵图2、为什么需要精灵图3、精灵图的使用①、创建CSS精灵图的步骤1&#xff09;、选择合适的图标2&#xff09;、合并图片3&#xff09;、设置背景定位 ②、优化CSS精灵图的技巧1&#xff09;、维护方便2&#xff09;、考虑Retina屏幕3&…

业务系统架构实践总结

我从2015年起至今2022年&#xff0c;在业务平台&#xff08;结算、订购、资金&#xff09;、集团财务平台&#xff08;应收应付、账务核算、财资、财务分析、预算&#xff09;、本地生活财务平台&#xff08;发票、结算、预算、核算、稽核&#xff09;所经历的业务系统研发实践…

18V降压5V芯片

航誉微高效率同步降压芯片。输出电流可以高达2A。采用两种工作模式&#xff1a;PWM与PFM切换工作。92%的占空比实现了低压操作并延长了便携系统的电池使用寿命&#xff1b;输出电压可调&#xff1b;振荡频率为 600KHz&#xff08;典型值&#xff09;。内部同步开关提高了效率并…

D.OASIS City 和 Warrix 在The Sandbox 庆祝 Rise of the 10th Legend十周年

D.OASIS 首次展示了变革性娱乐 D.OASIS City&#xff0c;正如它与 WARRIX 一起承诺的那样。WARRIX 是获得泰国国家队球衣生产授权的标志性运动服装品牌。 这款激动人心的游戏冒险游戏于今天推出&#xff0c;让用户能够投入 D.OASIS City x WARRIX&#xff1a;Rise of the 10th…

一文速学-让神经网络不再神秘,一天速学神经网络基础-激活函数(二)

前言 思索了很久到底要不要出深度学习内容&#xff0c;毕竟在数学建模专栏里边的机器学习内容还有一大半算法没有更新&#xff0c;很多坑都没有填满&#xff0c;而且现在深度学习的文章和学习课程都十分的多&#xff0c;我考虑了很久决定还是得出神经网络系列文章&#xff0c;…

健康安全的新定义,照明舒适达到巅峰,SUKER书客护眼台灯L1震撼发售

深耕照明领域多年的SUKER书客&#xff0c;这一次给大家带来一份大惊喜。在最近正式发布新品——SUKER书客护眼台灯L1&#xff0c;这款护眼台灯承载着在照明领域的前沿技术&#xff0c;能保证照明安全健康和舒适度并带来非常优秀的护眼效果。作为书客在护眼台灯领域的颠覆式新品…

[JavaWeb]【九】web后端开发-SpringBootWeb案例(菜单)

目录 一、准备工作 1.1 需求 1.2 环境搭建 1.2.1 准备数据库&表 1.2.2 创建springboot工程 1.2.3 配置application.properties & 准备对应实体类 1.2.3.1 application.properties 1.2.3.2 实体类 1.2.3.2.1 Emp类 1.2.3.2.2 Dept类 1.2.4 准备对应的Mapper、…

vue项目,如何修改Element-Plus等UI组件库的样式,三种方式搞定!!!

前言 我们在学习和使用组件库构建页面的时候&#xff0c;时常会遇到这样的问题。 即&#xff0c;尽管组件库已经提供了较多的功能&#xff0c;来帮助我们构建自定义的效果&#xff0c;但有时仍不能使我们满意。 这个时候我们就不得不修改UI库的样式&#xff0c;来达到想要的状…

Spring MVC 四:Context层级

这一节我们来回答上篇文章中避而不谈的有关什么是RootApplicationContext的问题。 这就需要引入Spring MVC的有关Context Hierarchy的问题。Context Hierarchy意思就是Context层级&#xff0c;既然说到Context层级&#xff0c;说明在Spring MVC项目中&#xff0c;可能存在不止…

Leetcode---111双周赛

题目列表 2824. 统计和小于目标的下标对数目 2825. 循环增长使字符串子序列等于另一个字符串 2826. 将三个组排序 2827. 范围中美丽整数的数目 一、统计和小于目标的下标对数目 这题直接暴力求解&#xff0c;时间复杂度是O(n^2)&#xff0c;代码如下 class Solution { pu…

Mysql001:Mysql概述以及安装

前言&#xff1a;本课程将从头学习Mysql&#xff0c;以我的工作经验来说&#xff0c;sql语句真的太重要的&#xff0c;现在互联网所有的一切都是建立在数据上&#xff0c;因为互联网的兴起&#xff0c;现在的数据日月增多&#xff0c;每年都以翻倍的形式增长&#xff0c;对于数…

java八股文面试[多线程]——线程的生命周期

笔试题&#xff1a;画出线程的生命周期&#xff0c;各个状态的转换。 5.等待队列(本是Object里的方法&#xff0c;但影响了线程) 调用obj的wait(), notify()方法前&#xff0c;必须获得obj锁&#xff0c;也就是必须写在synchronized(obj) 代码段内。与等待队列相关的步骤和图 …

Docker容器学习:搭建ownCloud个人网盘

目录 前提环境 拉取镜像 创建容器 创建mysql容器&#xff1a; 创建OwnCloud容器&#xff0c;并连接到数据库&#xff1a; 创建Nginx容器&#xff1a; 配置nignx 前提环境 基于Centos7.9版本环境安装Docker-ce&#xff1a;24.0.5 拉取镜像 docker pull mysql:5.6 dock…

Leetcode每日一题:1267. 统计参与通信的服务器(2023.8.24 C++)

目录 1267. 统计参与通信的服务器 题目描述&#xff1a; 实现代码与解析&#xff1a; 写法一&#xff1a;两次遍历 hash 原理思路&#xff1a; 写法二&#xff1a;三次遍历 原理思路&#xff1a; 1267. 统计参与通信的服务器 题目描述&#xff1a; 这里有一幅服务器分…

Jetson Xavier NX安装torch环境

设备简介 Jetson Xavier NX是一款具有强大计算能力的AI处理器&#xff0c;它采用了NVIDIA的Turing架构和Volta GPU架构&#xff0c;可以实现高性能的深度学习和推理任务。具体性能如下&#xff1a; CPU&#xff1a;6核心ARM Cortex-A57处理器&#xff0c;最高主频1.5GHz。 GP…