聊聊Spring Cloud Gateway
网关概述
整体来看,网关有点类似于门面,所有的外部请求都会先经过网关这一层。
网关不仅只是做一个请求的转发及服务的整合,有了网关这个统一的入口之后,它还能提供以下功能。
- 针对所有请求进行统一鉴权、限流、熔断、日志。
- 协议转化。针对后端多种不同的协议,在网关层统一处理后以HTTP对外提供服务。譬如针对Dubbo服务还需要提供一个Web应用来进行协议转化,此时可以在API网关层转换协议。
- 统一错误码处理。
- 灰度发布
- 请求转发,并且可以基于网关实现内、外网隔离。
常用的解决方案场景如下:



Spring Cloud Gateway
Spring Cloud Gateway是基于Spring Boot 2.0、Spring WebFlux和Project Reactor等技术开发的网关,它不仅提供了统一的路由请求的方式,还基于过滤链的方式提供了网关最基本的功能;解决了Spring Cloud Zuul的性能问题:
Zuul 1.x采用的是传统的thread per connection方式来处理请求,也就是针对每一个请求,会为这个请求专门分配一个线程来进行处理,直到这个请求完成之后才会释放线程,一旦后台服务器响应较慢,就会使得该线程被阻塞,所以它的性能不是很好。
Zuul 1.x采用的是传统的thread per connection方式来处理请求,也就是针对每一个请求,会为这个请求专门分配一个线程来进行处理,直到这个请求完成之后才会释放线程,一旦后台服务器响应较慢,就会使得该线程被阻塞,所以它的性能不是很好。
Spring WebFlux基于Project Reactor响应式框架实现了完全无阻塞的、响应式的、高并发性能的、网络请求响应;解决了如上的Zuul性能问题。
个人觉得,其实就是类似Nginx、Redis等基于Reactor模式的实现;也是非阻塞IO(Epoll)的另一种体现。
请求过程及关键概念
Spring Cloud Gateway的请求处理过程如图所示,其中有几个非常重要的概念。
路由(Route):它是网关的基本组件,由ID、目标URI、Predicate集合、Filter集合组成。
谓语(Predicate):它是Java 8中引入的函数式接口,提供了断言的功能。它可以匹配HTTP请求中的任何内容。如果Predicate的聚合判断结果为true,则意味着该请求会被当前Router进行转发。
谓语(Predicate):它是Java 8中引入的函数式接口,提供了断言的功能。它可以匹配HTTP请求中的任何内容。如果Predicate的聚合判断结果为true,则意味着该请求会被当前Router进行转发。

Spring Cloud Gateway启动时基于Netty Server监听一个指定的端口(该端口可以通过server.port属性自定义)。当客户端发送一个请求到网关时,网关会根据一系列Predicate的匹配结果来决定访问哪个Route路由,然后根据过滤器链进行请求的处理。过滤器链可以在请求发送到后端服务器之前和之后执行,也就是首先执行Pre过滤器链,然后将请求转发到后端的微服务执行具体的业务,最后执行Post过滤器链。
Route Predicate Factories
Predicate是Java 8提供的一个函数式接口,它允许接收一个参数并返回一个布尔值,可以用于条件过滤、请求参数的校验。

在Spring Cloud Gateway中,Predicate提供了路由规则的匹配机制。比如:

意思是通过Path属性来匹配URL前缀是/gateway/的请求。
如下,Spring Cloud Gateway默认提供了很多Route Predicate Factory,这些Predicate会分别匹配HTTP请求的不同属性,并且多个Predicate可以通过and逻辑进行组合。

Gateway Filter Factories
Filter分为Pre类型的过滤器和Post类型的过滤器。
Pre类型的过滤器在请求转发到后端微服务之前执行,在Pre类型过滤器链中可以做鉴权、限流等操作。
Post类型的过滤器在请求执行完之后、将结果返回给客户端之前执行。
在Spring Cloud Gateway中内置了很多Filter,Filter有两种实现,分别是GatewayFilter和GlobalFilter。GlobalFilter会应用到所有的路由上,而GatewayFilter只会应用到单个路由或者一个分组的路由上。
GatewayFilter
Spring提供了一些内置的GatewayFilter,如:
AddRequestParameter GatewayFilter Factory:该过滤器的功能是对所有匹配的请求添加一个查询参数。

AddResponseHeader GatewayFilter Factory:该过滤器会对所有匹配的请求,在返回结果给客户端之前,在Header中添加相应的数据。
在上面这段配置中,会在Response中添加Header头,

在上面这段配置中,会在Response中添加Header头,key=X-Response-Foo,Value=Bar。RequestRateLimiter GatewayFilter Factory:该过滤器会对访问到当前网关的所有请求执行限流过滤,如果被限流,默认情况下会响应HTTP 429-Too Many Requests。
RequestRateLimiterGatewayFilterFactory默认提供了RedisRateLimiter的限流实现,它采用令牌桶算法来实现限流功能。

redis-rate-limiter过滤器有两个配置属性:

Retry GatewayFilter Factory:Retry GatewayFilter Factory为请求重试过滤器,当后端服务不可用时,网关会根据配置参数来发起重试请求。

RetryGatewayFilter提供4个参数来控制重试请求,参数说明如下。

GlobalFilter
GlobalFilter和GatewayFilter的作用是相同的,只是GlobalFilter针对所有的路由配置生效。Spring Cloud Gateway内置的全局过滤器也有很多,比如:

全局过滤链的执行顺序是,当Gateway接收到请求时,Filtering Web Handler处理器会将所有的GlobalFilter实例及所有路由上所配置的GatewayFilter实例添加到一条过滤器链中。该过滤器链里的所有过滤器都会按照@Order注解所指定的数字大小进行排序。
LoadBalancerClientFilter:LoadBalancerClientFilter是用于实现请求负载均衡的全局过滤器,配置如下。

如果URI配置的是lb://example_service,那么这个过滤器会识别到lb://,并且使用Spring Cloud LoadBalancerClient将example_service名称解析成实际访问的主机和端口地址。GatewayMetricsFilter:GatewayMetricsFilter是网关指标过滤器,这个过滤器会添加name=gateway.requests的timer metrics,其中包含以下数据。

这些指标通过http://ip:port/actuator/metrics/gateway.requests获得,前提是需要添加Spring Boot Actuator依赖。
自定义过滤器
Spring Cloud Gateway提供了过滤器的扩展功能,开发者可以根据实际业务需求来自定义过滤器。同样,自定义过滤器也支持GlobalFilter和GatewayFilter两种。
自定义GatewayFilter:自定义过滤器类GpDefineGatewayFilterFactory,继承AbstractGatewayFilterFactory。
自定义GlobalFilter:GlobalFilter的实现比较简单,它不需要额外的配置,只需要实现GlobalFilter接口,自动会过滤所有的Route。
集成
Spring Cloud Gateway支持与其他解决方案集成,实现更强大的功能,比如Spring Cloud Alibaba系列。
聊聊Spring Cloud Gateway的更多相关文章
- 跟我学SpringCloud | 第十二篇:Spring Cloud Gateway初探
SpringCloud系列教程 | 第十二篇:Spring Cloud Gateway初探 Springboot: 2.1.6.RELEASE SpringCloud: Greenwich.SR1 如 ...
- Spring Cloud gateway 网关服务 一
之前我们介绍了 zuul网关服务,今天聊聊spring cloud gateway 作为spring cloud的亲儿子网关服务.很多的想法都是参照zuul,为了考虑zuul 迁移到gateway 提 ...
- 从架构演进的角度聊聊Spring Cloud都做了些什么?
Spring Cloud作为一套微服务治理的框架,几乎考虑到了微服务治理的方方面面,之前也写过一些关于Spring Cloud文章,主要偏重各组件的使用,本次分享主要解答这两个问题:Spring Cl ...
- Spring Cloud Gateway、并发编程等等
2019年 JUC线程池服务ExecutorService接口实现源码分析 Github Page:http://www.throwable.club/2019/07/27/java-concurre ...
- Dubbo想要个网关怎么办?试试整合Spring Cloud Gateway
一.背景 在微服务架构中 API网关 非常重要,网关作为全局流量入口并不单单是一个反向路由,更多的是把各个边缘服务(Web层)的各种共性需求抽取出来放在一个公共的"服务"(网关)中 ...
- Spring Cloud Gateway 扩展支持动态限流
之前分享过 一篇 <Spring Cloud Gateway 原生的接口限流该怎么玩>, 核心是依赖Spring Cloud Gateway 默认提供的限流过滤器来实现 原生Request ...
- Spring Cloud Gateway的断路器(CircuitBreaker)功能
欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:所有原创文章分类汇总及配套源码,涉及Java.Docker.Kubernetes.DevOPS ...
- Spring Cloud Gateway修改请求和响应body的内容
欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:所有原创文章分类汇总及配套源码,涉及Java.Docker.Kubernetes.DevOPS ...
- 从0开始构建你的api网关--Spring Cloud Gateway网关实战及原理解析
API 网关 API 网关出现的原因是微服务架构的出现,不同的微服务一般会有不同的网络地址,而外部客户端可能需要调用多个服务的接口才能完成一个业务需求,如果让客户端直接与各个微服务通信,会有以下的问题 ...
- Spring cloud gateway
==================================为什么需要API gateway?==================================企业后台微服务互联互通, 因为 ...
随机推荐
- Bitcask — 日志结构的快速 KV 存储引擎
Bitcask 介绍 Bitcask 是一种高性能的键值存储引擎,基于日志结构和哈希索引来提供高速的读写操作和数据持久性,适用于处理大量写入请求和快速查找键值对的应用场景. 核心概念 Bitcask ...
- C++ 用户输入验证
在编写程序时,请考虑用户将如何滥用您的程序,尤其是在文本输入方面.对于每个文本输入点,请考虑: 会不会提取失败? 用户可以输入比预期更多的输入吗? 用户可以输入无意义的输入吗 用户可以溢出输入吗? 以 ...
- 一次Feign使用的案例
项目名称 projectName Maven架构 l ProjectName-项目名称,项目父工程 projectName-api-提供给外部组件使用的接口 common-一些基本共用的类.枚举常量 ...
- 集合-LinkedHashMap 源码详细分析(JDK1.8)
1. 概述 LinkedHashMap 继承自 HashMap,在 HashMap 基础上,通过维护一条双向链表,解决了 HashMap 不能随时保持遍历顺序和插入顺序一致的问题.除此之外,Linke ...
- 垃圾回收之三色标记法(Tri-color Marking)
关于垃圾回收算法,基本就是那么几种:标记-清除.标记-复制.标记-整理.在此基础上可以增加分代(新生代/老年代),每代采取不同的回收算法,以提高整体的分配和回收效率. 无论使用哪种算法,标记总是必要的 ...
- 二进制安装Kubernetes(k8s) v1.24.2 IPv4/IPv6双栈
二进制安装Kubernetes(k8s) v1.24.2 IPv4/IPv6双栈 Kubernetes 开源不易,帮忙点个star,谢谢了 介绍 kubernetes二进制安装 强烈建议在Github ...
- [Linux]常用命令之【mkdir/touch/cp/rm/ls/mv】
cp 将来源文件夹packageA下的所有目录及文件复制到新文件夹packageB下,形成: /packageB/... # cp -r /home/packageA/* /home/cp/packa ...
- AtCoder Beginner Contest 061 - D Score Attack
给定一张边带权的有向图.从节点\(1\)出发,每经过一条边一次,得分加上这条边的边权.(可以多次经过,多次累加 必须在点\(n\)结束游戏 判断是否能使得分无限大,如果否,求最大得分. sol 题目所 ...
- sms-activate操作简便易上手且好用的接码工具【保姆级教程】
前言 有些国外应用在使用应用上的功能时需要注册账号,由于某种不可抗因素,我们的手机号一般不支持注册,接收不到信息验证码,于是我们可以使用SmS-Activate提供的服务,使用$实现我们的需求(大概一 ...
- 一天吃透MySQL面试八股文
什么是MySQL MySQL是一个关系型数据库,它采用表的形式来存储数据.你可以理解成是Excel表格,既然是表的形式存储数据,就有表结构(行和列).行代表每一行数据,列代表该行中的每个值.列上的值是 ...