[Spring Cloud] GateWay服务网关

✨✨个人主页:沫洺的主页

📚📚系列专栏: 📖 JavaWeb专栏📖 JavaSE专栏 📖 Java基础专栏📖vue3专栏 

                           📖MyBatis专栏📖Spring专栏📖SpringMVC专栏📖SpringBoot专栏

                           📖Docker专栏📖Reids专栏📖MQ专栏📖SpringCloud专栏     

💖💖如果文章对你有所帮助请留下三连✨✨

衔接上篇:  [Spring Cloud] Hystrix通过配置文件统一设置参数/与OpenFeign结合使用_沫洺的博客-CSDN博客

🍁GateWay服务网关

GateWay说明文档: Index of /spring-cloud-gateway/docs

🌾什么是服务网关

传统的单体架构中只需要开放一个服务给客户端调用,但是微服务架构中是将一个系统拆分成多个微服务,如果没有网关,客户端只能在本地记录每个微服务的调用地址,当需要调用的微服务数量很多时,它需要了解每个服务的接口,这个工作量很大。那有了网关之后,能够起到怎样的改善呢?

网关作为系统的唯一流量入口,封装内部系统的架构,所有请求都先经过网关,由网关将请求路由到合适的微服务,所以,使用网关的好处在于:

(1)简化客户端的工作。网关将微服务封装起来后,客户端只需同网关交互,而不必调用各个不同服务;

(2)降低函数间的耦合度。 一旦服务接口修改,只需修改网关的路由策略,不必修改每个调用该函数的客户端,从而减少了程序间的耦合性

(3)解放开发人员把精力专注于业务逻辑的实现。由网关统一实现服务路由(灰度与ABTest)、负载均衡、访问控制、流控熔断降级等非业务相关功能,而不需要每个服务 API 实现时都去考虑

但是 API 网关也存在不足之处,在微服务这种去中心化的架构中,网关又成了一个中心点或瓶颈点,它增加了一个我们必须开发、部署和维护的高可用组件。正是由于这个原因,在网关设计时必须考虑即使 API 网关宕机也不要影响到服务的调用和运行,所以需要对网关的响应结果有数据缓存能力,通过返回缓存数据或默认数据屏蔽后端服务的失败。

在服务的调用方式上面,网关也有一定的要求,API 网关最好是支持 I/O 异步、同步非阻塞的,如果服务是同步阻塞调用,可以理解为微服务模块之间是没有彻底解耦的,即如果A依赖B提供的API,如果B提供的服务不可用将直接影响到A不可用,除非同步服务调用在API网关层或客户端做了相应的缓存。因此为了彻底解耦,在微服务调用上更建议选择异步方式进行。而对于 API 网关需要通过底层多个细粒度的 API 组合的场景,推荐采用响应式编程模型进行而不是传统的异步回调方法组合代码,其原因除了采用回调方式导致的代码混乱外,还有就是对于 API 组合本身可能存在并行或先后调用,对于采用回调方式往往很难控制。

🌿服务网关的基本功能 

🍃流量网关与服务网关的区别 

流量网关和服务网关在系统整体架构中所处的位置如上图所示,

流量网关(如Nignx)是指提供全局性的、与后端业务应用无关的策略,例如 HTTPS证书卸载、Web防火墙、全局流量监控等。

微服务网关(如Spring Cloud Gateway)是指与业务紧耦合的、提供单个业务域级别的策略,如服务治理、身份认证等。也就是说,流量网关负责南北向流量调度及安全防护,微服务网关负责东西向流量调度及服务治理。

🍂服务网关的部署

🌲主流网关的对比与选型 

(1)Kong 网关:Kong 的性能非常好,非常适合做流量网关,但是对于复杂系统不建议业务网关用 Kong,主要是工程性方面的考虑

(2)Zuul1.x 网关:Zuul 1.0 的落地经验丰富,但是性能差、基于同步阻塞IO,适合中小架构,不适合并发流量高的场景,因为容易产生线程耗尽,导致请求被拒绝的情况

(3)gateway 网关:功能强大丰富,性能好,官方基准测试 RPS (每秒请求数)是Zuul的1.6倍,能与 SpringCloud 生态很好兼容,单从流式编程+支持异步上也足以让开发者选择它了。

(4)Zuul 2.x:性能与 gateway 差不多,基于非阻塞的,支持长连接,但 SpringCloud 没有集成 zuul2 的计划,并且 Netflix 相关组件都宣布进入维护期,前景未知。

综上,gateway 网关更加适合 SpringCloud 项目,而从发展趋势上看,gateway 替代 zuul 也是必然的。

🌳Spring Cloud Gateway 网关的搭建

父模块pom声明

        <module>spring-cloud-gateway</module>

           <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring.cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>

创建子模块spring-cloud-gateway

添加依赖

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

pom.xml

注意:一定要排除掉 spring-boot-starter-web 依赖,否则启动报错

使用spring-boot-starter-webflux功能和web一样,但是webflux异步框架

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>com.moming</groupId>
        <artifactId>spring-cloud-root</artifactId>
        <version>0.0.1-SNAPSHOT</version>
        <relativePath>../pom.xml</relativePath>
    </parent>

    <artifactId>spring-cloud-gateway</artifactId>

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

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <excludes>
                        <exclude>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                        </exclude>
                    </excludes>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>

添加配置

#标识
spring.cloud.gateway.routes[0].id = route1
#配置路由规则
spring.cloud.gateway.routes[0].predicates[0] = Path=/test/**
#转发时过滤test,若路由为/test/api/**,StripPrefix=2代表过滤/test/api
spring.cloud.gateway.routes[0].filters[0] = StripPrefix=1
#如果符合上面的规则,流量就打到这个网址
spring.cloud.gateway.routes[0].uri = http://httpbin.org

介绍一个网址: httpbin.org(为开发者提供的公开的域名,可以有效测试http协议相关内容)

调试http请求时,能直接看出来响应内容

简单使用一下,如下图get请求

 直接启动

访问

🌸Spring Cloud Gateway 配置项的说明

参考文章: Spring Cloud Gateway夺命连环10问?

在介绍 Spring Cloud Gateway 的配置项之前,我们先了解几个 Spring Cloud Gateway 的核心术语:

断言(Predicate):参照 Java8 的新特性Predicate,允许开发人员匹配 HTTP 请求中的任何内容,比如请求头或请求参数或请求路径,最后根据匹配结果返回一个布尔值。

路由(route):由ID、目标URI、断言集合和过滤器集合组成。如果聚合断言结果为真,则转发到该路由。

过滤器(filter):可以在返回请求之前或之后修改请求和响应的内容。

🌹路由 Route

Route 主要由 路由id、目标uri、断言集合和过滤器集合组成,这些属性到底有什么作用。

(1)id:路由标识,要求唯一,名称任意(默认值 uuid,一般不用,需要自定义)

(2)uri:请求最终被转发到的目标地址

(3)order: 路由优先级,数字越小,优先级越高

(4)predicates:断言数组,即判断条件,如果返回值是boolean,则转发请求到 uri 属性指定的服务中

(5)filters:过滤器数组,在请求传递过程中,对请求做一些修改

🌷断言 Predicate

官方断言使用说明

Predicate 来自于 Java8 的接口。Predicate 接受一个输入参数,返回一个布尔值结果。该接口包含多种默认方法来将 Predicate 组合成其他复杂的逻辑(比如:与,或,非)。

Predicate 可以用于接口请求参数校验、判断新老数据是否有变化需要进行更新操作。Spring Cloud Gateway 内置了许多 Predict,这些 Predict 的源码在 org.springframework.cloud.gateway.handler.predicate 包中,有兴趣可以阅读一下。内置的一些断言如下图:

上面我们已经使用过Path(请求path校验条件断言:Path=/test/**)

接下来使用一下Query请求参数校验条件断言

#标识
spring.cloud.gateway.routes[0].id = route1
#配置路由规则
spring.cloud.gateway.routes[0].predicates[0] = Path=/test/**
#匹配请求参数的断言,url后一定要有color参数 ?color=red
spring.cloud.gateway.routes[0].predicates[1] = Query=color
#转发时过滤test,若路由为/test/api/**,StripPrefix=2代表过滤/test/api
spring.cloud.gateway.routes[0].filters[0] = StripPrefix=1
#如果符合上面的规则,流量就打到这个网址
spring.cloud.gateway.routes[0].uri = http://httpbin.org

可以看到url传参必须要有color

若是指定color必须为red配置如下

spring.cloud.gateway.routes[0].predicates[1] = Query=color,red

支持正则,指定re前缀,通过"."代表一个字符

spring.cloud.gateway.routes[0].predicates[1] = Query=color,re.

Header(请求header校验条件断言)

spring.cloud.gateway.routes[0].predicates[1] = Header=tokenId,123

官方案例,必须为数字

spring.cloud.gateway.routes[0].predicates[1] = Header=X-Request-Id,\\d+

其他断言规则使用同理

🌻过滤器 filter

内置局部过滤器

StripPrefixGatewayFilterFactory(用于截断原始请求的路径)

spring.cloud.gateway.routes[0].filters[0] = StripPrefix=1

官网过滤器使用说明

 Gateway 过滤器的生命周期:

  • PRE:这种过滤器在请求被路由之前调用。我们可利用这种过滤器实现身份验证、在集群中选择请求的微服务、记录调试信息等。
  • POST:这种过滤器在路由到微服务以后执行。这种过滤器可用来为响应添加标准的 HTTP Header、收集统计信息和指标、将响应从微服务发送给客户端等。

Gateway 过滤器从作用范围可分为两种:

  • GatewayFilter:应用到单个路由或者一个分组的路由上(需要在配置文件中配置)
  • GlobalFilter:应用到所有的路由上(无需配置,全局生效)

(1)局部过滤器 GatewayFilter:

Spring Cloud Gateway 中内置了许多的局部过滤器,如下图

局部过滤器需要在指定路由配置才能生效,默认是不生效的。

接下来例举几个常用的

 AddResponseParameterGatewayFilterFactory(前置过滤器)

spring.cloud.gateway.routes[0].id = route1
spring.cloud.gateway.routes[0].predicates[0] = Path=/test/**
spring.cloud.gateway.routes[0].filters[0] = StripPrefix=1
#前置过滤器,会在请求后端服务接口之前增加一个参数,url会多出来参数color=red
spring.cloud.gateway.routes[0].filters[1] = AddRequestParameter=color,red
spring.cloud.gateway.routes[0].uri = http://httpbin.org

 AddRequestHeaderGatewayFilterFactory(前置过滤器)

spring.cloud.gateway.routes[0].filters[2] = AddRequestHeader=name,moming

 AddResponseHeaderGatewayFilterFactory(后置过滤器)

spring.cloud.gateway.routes[0].filters[3] = AddResponseHeader=recruitment,moming@qq.com

(2)全局过滤器

全局过滤器应用到全部路由上,无需开发者配置,Spring Cloud Gateway也内置了一些全局过滤器

 

GlobalFilter的功能其实和GatewayFilter是相同的,只是GlobalFilter的作用域是所有的路由配置,而不是绑定在指定的路由配置上。多个GlobalFilter可以通过@Order或者getOrder()方法指定每个GlobalFilter的执行顺序,order值越小,GlobalFilter执行的优先级越高。

#全局过滤器
spring.cloud.gateway.default-filters[0]=AddRequestHeader=vsersion,1.0

  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

沫洺

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值