2. Spring Cloud Gateway入门

入门概念

客户端向 Spring Cloud Gateway 发出请求。如果Gateway Handler Mapping确定请求与路由匹配,则将其发送到Gateway Web Handler 处理程序。此处理程序通过特定于请求的Fliter链运行请求。在过滤器链上线执行pre部分逻辑,然后执行代理服务,然后支线post部分逻辑。 所以在执行一个过滤器时流程是这样的 pre→proxied service→post,如下图所示:

过滤器作用

  • Filter在pre类型的过滤器可以做参数效验、权限效验、流量监控、日志输出、协议转换等。
  • Filter在post类型的过滤器可以做响应内容、响应头的修改、日志输出、流量监控等
  • 这两种类型的过滤器有着非常重要的作用。

网关核心点

  • Route(路由) 路由是构建网关的基础模块,它由ID,目标URI,包括一些列的断言predicates和过滤器filter组成,如果断言为true则匹配该路由
  • Predicate(断言) 参考的是Java8的java.util.function.Predicate,开发人员可以匹配HTTP请求中的所有内容(例如请求头或请求参数),请求与断言匹配则进行路由
  • Filter(过滤) 指的是Spring框架中GateWayFilter的实例,使用过滤器,可以在请求被路由前或者之后对请求进行修改。
  • 三个核心点连起来: 当用户发出请求到达Gateway,Gateway会通过一些匹配条件,定位到真正的服务节点,并在这个转发过程前后,进行一些及细化控制。其中Predicate就是我们匹配的条件,而Filter可以理解为一个过滤器,有了这两个点,再加上目标URI,就可以实现一个具体的路由了。
  • 总结核心流程为:执行过滤器链pre逻辑→路由转发→执行过滤器链post逻辑

IDEA项目搭建

1. 新建网关模块gateway-app

2. 确定版本对应关系

因为GateWay属于SpringCloud的,所以我们要导入对应依赖,一定要注意版本关系:

版本对应地址:Spring Cloud

我这里使用的是SpringBoot 2.3.12.RELEASE的版本所以配合的是SpringCloud的Hoxton.SR5版本

注意:引入GateWay一定要删除spring-boot-starter-web依赖,因为gateway 使用的是webflux 使用spring-boot-starter-web会导致无法启动

3. 在父项目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 http://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>
        <!--这里需要注意:要使用2.4以下的版本,目前(2022.3.20)以上的版本会报错-->
        <!--java.lang.NoClassDefFoundError: org/springframework/boot/context/properties/ConfigurationBeanFactory-->
        <!--参考链接:https://blog.csdn.net/qq_36448800/article/details/119225687-->
        <version>2.3.12.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>org.example</groupId>
    <artifactId>AlibabaNacos</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>pom</packaging>
    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
        <java.version>1.8</java.version>
        <spring-cloud-alibaba-version>2.2.7.RELEASE</spring-cloud-alibaba-version>
        <spring-cloud-openfeign-version>2.2.7.RELEASE</spring-cloud-openfeign-version>
        <spring-cloud-version>Hoxton.SR5</spring-cloud-version>
    </properties>
    <dependencies>
        <!--公共引入依赖的地方-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.22</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
            <version>${spring-cloud-openfeign-version}</version>
        </dependency>
    </dependencies>

    <!--使用alibaba nacos需要在父项目中添加如下行-->
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>com.alibaba.cloud</groupId>
                <artifactId>spring-cloud-alibaba-dependencies</artifactId>
                <version>${spring-cloud-alibaba-version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <!--spring cloud Hoxton.SR5-->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud-version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <!--子模块引入-->
    <modules>
        <module>nacos-provider</module>
        <module>gateway-app</module>
    </modules>
  </project>

4. 子模块gateway-app 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.example</groupId>
        <artifactId>AlibabaNacos</artifactId>
        <version>1.0-SNAPSHOT</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.example</groupId>
    <artifactId>gateway-app</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>gateway-app</name>
    <description>gateway-app</description>
    <dependencies>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <!--注入阿里巴巴nacos服务注册发现相关包-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>
        <!-- spring cloud gateway依赖 -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-gateway</artifactId>
        </dependency>
    </dependencies>
</project>

5. 创建服务提供者子模块nacos-provider

该模块支持多实例部署,以测试负载均衡

服务需要注册到注册中心nacos

服务名称:nacos-provider

端口:8081/8083

提供访问接口

@RestController
public class TestController {
    @Value("${server.port}")
    private String serverPort;

    @GetMapping("/test/getServerPort")
    public String getServerPort() {
        return "Hello Nacos Discovery Port:" + serverPort;
    }
}

配置如下:

spring.application.name=nacos-provider
spring.cloud.nacos.discovery.server-addr=192.168.43.11:8848
management.endpoints.web.exposure.include=*

6. 在网关子项目gateway-app中配置properties

server.port=8888
spring.application.name=gateway-app
# 注册发现服务nacos
spring.cloud.nacos.discovery.server-addr=192.168.43.11:8848
# 配置发现的服务自动配置路由转发
spring.cloud.gateway.discovery.locator.enabled=true
# 配置自定义路由转发id,不能重复
spring.cloud.gateway.routes[0].id=nacos-provider
# 配置路由转发地址,http://开头代表转发的服务地址。 如果是lb://服务名称,则是负载均衡转发
spring.cloud.gateway.routes[0].uri=http://localhost:8081

# 断言的第一种写法
#spring.cloud.gateway.routes[0].predicates[0].name=Path
#spring.cloud.gateway.routes[0].predicates[0].args.pattern=/test/**

# 断言的第二种写法
spring.cloud.gateway.routes[0].predicates[0]=Path=/test/**

7. 启动服务提供者类,先提供8081服务

从访问地址可以看出,服务提供者已正常

8. 启动网关服务测试

从图上可以看出通过8888端口,也就是网关也能正常访问服务,说明服务以通过网关转发成功了。

9. 负载均衡测试

服务提供者和网关服务都通过注册中心注册服务,然后网关通过拉取注册中心服务实例,进行负载均衡调用,所以这里需要有注册中心支持。

需要修改网关服务配置文件

# 配置路由转发地址,http://开头代表转发的服务地址。 如果是lb://服务名称,则是负载均衡转发
spring.cloud.gateway.routes[0].uri=lb://nacos-provider

需要修改网关服务器启动类加服务注册发现支持

@SpringBootApplication
//启用服务注册发现客户端,这样才能通过nacos获取和注册服务
@EnableDiscoveryClient
public class GatewayAppApplication {

    public static void main(String[] args) {
        SpringApplication.run(GatewayAppApplication.class, args);
    }
}

然后启动服务提供者8081和8083服务,保证能正常访问

注意:服务提供者也需要服务注册发现支持

然后启动网关服务测试从网关访问,多访问几次看看返回端口是否有变化,如果有,则说明负载均衡以生效

10. 代码方式配置路由

除了上述我们使用了配置文件的方式配置路由,spring cloud gateway 还支持以代码的方式配置路由,这种方式可以实现动态的路由方式。 当然如果是静态的配置,推荐还是通过配置文件来配置, 这样就可以通过配置中心来实现热加载。

要用代码的方式来配置路由,我们需要创建一个Configuration类,并且返回一个RouteLocator类实例的Bean给SpringBean工厂。 如下:

@Configuration
public class GatewayRouteConfig {
    /*
     * 配置了一个id为path_msb1的路由规则
     * 当访问地址http://localhost:8888/test/**
     * 就会转发到lb://nacos-provider/  的任何地址
     */
    @Bean
    public RouteLocator customRouteLocator(RouteLocatorBuilder routeLocatorBuilder) {
        // 构建多个路由routes
        RouteLocatorBuilder.Builder routes = routeLocatorBuilder.routes();
        // 具体路由地址
        routes.route("code-route", predicateSpec -> predicateSpec.path("/**").uri("lb://nacos-provider")).build();
        // 返回所有路由规则
        return routes.build();
    }
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值