Spring Cloud Gateway 网关的初步认识和基本使用

Gateway 简单介绍

Gateway 是 Spring Cloud 官方推出的第二代网关框架,用于取代 Zuul 网关,基于 Netty 和 WebFlux 由于没有使用 Sevlet 容器,故不能打成 war 包, Gateway 只支持 SpringBoot2.X 及以上版本。

Gateway 三大核心概念

  • 路由 Route : 可以理解为设置请求转发到指定服务器的过程,是构建网关的基本模块,由 ID、目标 URI、断言集合和过滤器集合组成,如果断言为 true 则匹配路由。
  • 断言 Predicate : 是 Java 8 的一个函数式接口 predicate,可以用于 lambda 表达式和方法引用,输入类型是:Spring Framework ServerWebExchange,允许开发人员使用断言来匹配来自 HTTP 请求中携带的内容,例如请求头 headers 和参数 paramers。
  • 过滤 Filter : 是使用特定工厂构建的 Spring Framework GatewayFilter 实例,GatewayFilter 通过使用过滤器,对请求进行拦截,在请求路由前后作出修改操作。

Gateway 主要功能

  • 鉴权。
  • 限流。
  • 熔断。
  • 日志监控。

Gateway 工作流程图

了解过 Gateway 的小伙伴,相信对下面这张图都不陌生,此图大概描述了请求的处理原理,以及各个组件大致的位置,各个组件的作用如下:

  • Gateway Client:发送请求到 Spring Cloud Gateway 的客户端。
  • Gateway Handler Mapping:处理请求的组件,负责将请求映射到相应的处理器,根据请求的路由规则,从而选择对应的过滤器链。
  • Gateway Web Handler:实际处理请求的组件,会依次执行过滤器链,对请求进行处理。
  • Gateway Filter:过滤器,是由一系列过滤器组成过滤器链,每个过滤器执行一些特定业务逻辑,过滤器之间用虚线分开是因为过滤器可能会在发送代理请求之前(pre)或之后(post)执行业务逻辑。
  • Proxied Service:被代理的服务,当执行完过滤器链之后会将请求转发到具体的目标服务。

Gateway 的核心逻辑是路由转发和执行过滤器链。

在这里插入图片描述

GatewayFilterFactory Gateway过滤器工厂

Spring提供了31种不同的路由过滤器工厂,具体如下:

名称作用
AddRequestHeader给当前请求添加一个请求头
AddRequestParameter为原始请求添加请求参数
AddResponseHeader给响应结果中添加一个响应头
DedupeResponseHeader去掉重复请求头
Spring Cloud CircuitBreaker断路器
FallbackHeaders添加熔断后的异常信息到请求头
MapRequestHeader将上游请求头的值赋值到下游请求头
PrefixPath匹配的路由添加前缀
Preserve Host Header保留原请求头
RequestRate Limiter限制请求的流量
RedirectTo重定向
RemoveRequestHeader移除请求中的一个请求头
RemoveRequestParameter移除请求参数
RewritePath重写路径
RewriteLocationResponseHeader重写响应头中 Location 的值
Rewrite ResponseHeader重写响应头
SaveSession向下游转发请求前前置执行 WebSession save 的操作
SecureHeaders禁用默认值
SetRequestHeader重置请求头
SetResponseHeader修改响应头
SetStatus修改响应的状态码
StripPrefix对指定数量的路径前缀进行去除
Retry重试
RequestSize请求大小大于限制时,限制请求到达下游服务
SetRequestHostHeader重置请求头值
ModifyRequestBody修改请求体内容
ModifyResponse Body修改响应体内容
Relay将OAuth2访问令牌向下游转发到它所代理的服务
CacheRequestBody在请求正文发送到下游之前缓存请求正文并从exchagne属性获取正文

Gateway 实战练习

  1. 新建 cloud-gateway 服务,引入 gateway 相关依赖,并将 cloud-gateway 注册到 Nacos,这里不在演示创建服务的过程,只展示引入的相关依赖。

pom.xml 文件如下:

	<?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>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.4.5</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.user.service</groupId>
    <artifactId>user-service</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>user-service</name>
    <description>user-service</description>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <!--引入 Nacos 支持-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
            <version>2021.1</version>
            <exclusions>
                <exclusion>
                    <groupId>org.springframework.cloud</groupId>
                    <artifactId>spring-cloud-netflix-ribbon</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
            <version>2021.1</version>
            <exclusions>
                <exclusion>
                    <groupId>org.springframework.cloud</groupId>
                    <artifactId>spring-cloud-netflix-ribbon</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

        <!--引入 sentinel 支持-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
            <version>2021.1</version>
        </dependency>

        <!--引入 OpenFeign 支持-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
            <version>3.0.1</version>
        </dependency>

        <!--引入 LoadBalancer 支持-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-loadbalancer</artifactId>
            <version>3.0.1</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-bootstrap</artifactId>
            <version>3.0.0</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-commons</artifactId>
            <version>3.0.1</version>
            <scope>compile</scope>
        </dependency>

        <dependency>
            <groupId>com.alibaba.csp</groupId>
            <artifactId>sentinel-datasource-nacos</artifactId>
            <version>1.8.0</version>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>

    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

could-gateway 服务 properties 文件如下:

#服务名
spring.application.name=cloud-gateway
#端口
server.port=8888
#开启从注册中心动态创建路由的功能,利用微服务名称进行路由
spring.cloud.gateway.discovery.locator.enabled=true
#服务路由名小写
spring.cloud.gateway.discovery.locator.lower-case-service-id=true
#路由唯一标志
spring.cloud.gateway.routes[0].id = user-service
#路由指向目标 URL 服务名 客户端请求最终被转发到的微服务 推荐使用服务名称
spring.cloud.gateway.routes[0].uri = lb://user-service
#断言 以 /api/user 开头的请求都转发到 user-service 服务
spring.cloud.gateway.routes[0].predicates[0] = Path=/api/user/**
#过滤器 过滤掉 url 里的 /api/user 例如 http://ip:port/api/user/query-order 过滤后的地址是  http://ip:port/query-order
#如果不使用这个过滤器 直接在目标微服务的所有 api 路径前加上 /api/user  也是一样的
spring.cloud.gateway.routes[0].filters[0] = RewritePath=/api/user/(?<segment>.*), /$\{segment}
  1. 新建 user-service 服务,十分简单,这里不在演示,注意需要注册到 Nacos。

user-service 服务的测试代码如下:

@Slf4j
@RestController
public class UserController {

    @GetMapping("/query-user")
    public String queryUser() {
        return "张飞";
    }

}
  1. cloud-gateway 和 user-service 注册在同一个 Nacos 的同一个 Namespace 的同一个 Group 上,如下图所示:

在这里插入图片描述

需要注意的是 cloud-gateway 和 user-service 在 Nacos 上的 Namespace、Group 必须保证一样,否则会无法调用,Gateway 会有如下日志:

 2024-08-09 20:21:36.251  WARN 22008 --- [oundedElastic-6] o.s.c.l.core.RoundRobinLoadBalancer      : No servers available for service: user-service
  1. 通过 Gateway 调用验证

在这里插入图片描述
我们通过 Gateway 的 8888 端口调用到了 user-service 服务的 queryUser 接口,并正常响应了,结果符合预期。

本篇关于 Spring Cloud Gateway 网关的初步认识和基本使用就介绍到这里,希望可以帮助到有需要的小伙伴。

如有不正确的地方请各位指出纠正。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值