Spring Cloud Alibaba学习笔记(15) - 整合Spring Cloud Gateway

Spring Cloud Gateway

概述

Spring Cloud Gateway 是 Spring Cloud 的一个全新项目,该项目是基于Netty、Reactor以及WEbFlux构建,它旨在为微服务架构提供一种简单有效的统一的 API 路由管理方式。
Spring Cloud Gateway 作为 Spring Cloud 生态系统中的网关,目标是替代 Netflix Zuul,其不仅提供统一的路由方式,并且基于 Filter 链的方式提供了网关基本的功能,例如:安全、监控、埋点和限流等。

优点

  • 性能强劲,是Zuul的1.6倍
  • 功能强大,内置了很多实用的功能,例如转发、监控、限流等
  • 设计优雅,容易扩展

缺点

  • 依赖Netty与WebFlux,不是传统的Servlet编程模型,有一定的学习成本
  • 不能在Servlet容器下工作,也不能构建成WAR包,即不能将其部署在Tomcat、Jetty等Servlet容器里,只能打成jar包执行
  • 不支持Spring Boot 1.x,需2.0及更高的版本

核心概念

Route(路由)

这是Spring Cloud Gateway的基本构建块,可简单理解成一条转发规则。包含:ID、目标URL、一组断言和一组过滤器

Predicate(断言)

这是一个 Java 8 的 Predicate,即java.util.function.Predicate这个接口,Gateway使用Predicate实现路由的匹配条件。

Filter(过滤器)

这是 org.springframework.cloud.gateway.filter.GatewayFilter 的实例,我们可以使用它修改请求和响应

Gateway路由配置示例

spring:
  cloud:
    gateway:
      routes:
      - id: study01  # 唯一标识,通常使用服务id
        uri: lb://study01  # 目标URL,lb代表从注册中心获取服务,lb是Load Balance的缩写
        predicates:
        # Predicate集合
        - Path=/findBy  # 匹配转发路径
        filters:
        # Filter集合
        - StripPrefix=4  # 从第几级开始转发

工作流程

客户端向 Spring Cloud Gateway 发出请求。然后在 Gateway Handler Mapping 中找到与请求相匹配的路由,将其发送到 Gateway Web Handler。Handler 再通过指定的过滤器链来将请求发送到我们实际的服务执行业务逻辑,然后返回。
过滤器之间用虚线分开是因为过滤器可能会在发送代理请求之前(“pre”)或之后(“post”)执行业务逻辑。

特征

  • 基于 Spring Framework 5,Project Reactor 和 Spring Boot 2.0
  • 动态路由
  • Predicates 和 Filters 作用于特定路由
  • 集成 Hystrix 断路器
  • 集成 Spring Cloud DiscoveryClient
  • 易于编写的 Predicates 和 Filters
  • 限流
  • 路径重写

整合Spring Cloud Gateway

新建一个标准的Spring Boot项目,命名为gateway。

添加依赖

整合Spring Cloud Alibaba,添加Gateway和Nacos的依赖,示例如下:

<?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.2.0.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.example</groupId>
    <artifactId>gateway</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>gateway</name>
    <description>小程序网关</description>

    <properties>
        <java.version>1.8</java.version>
        <spring-cloud-alibaba.version>2.1.0.RELEASE</spring-cloud-alibaba.version>
        <spring-cloud.version>Greenwich.SR3</spring-cloud.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-gateway</artifactId>
        </dependency>
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
    </dependencies>

    <dependencyManagement>
        <dependencies>
            <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-alibaba-->
            <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>

        </dependencies>
    </dependencyManagement>

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

    <repositories>
        <repository>
            <id>spring-milestones</id>
            <name>Spring Milestones</name>
            <url>https://repo.spring.io/milestone</url>
        </repository>
    </repositories>

</project>

修改配置

添加nacos和gateway的配置,代码如下:

server:
  port: 8040
spring:
  application:
    name: gateway
  cloud:
    nacos:
      discovery:
        server-addr: localhost:8848
        namespace: 888ac051-ae5f-44f1-940a-30c7824a0e91
        cluster-name: HZ
    gateway:
      discovery:
        locator:
          # 让gateway通过服务发现组件找到其他的微服务
          enabled: true

management:
  endpoints:
    web:
      exposure:
        include: '*'
  endpoint:
    health:
      show-details: always

测试

依次启动之前就写好的项目【study01和study02】,然后启动gateway项目,打开任意浏览器。
PS:上述三个项目的nacos配置要一致。

我在study01项目中有一个findBy请求:http://localhost:8881/findById

在启动了gateway之后,可以这样输入浏览器地址:http://localhost:8040/study01/findById ,我们发现返回的结果是相同的

这就是Spring Cloud Gateway的作用之一 - 转发。
转发规律

  • ${GATEWAY_URL}/{微服务名}/
posted @ 2019-10-28 12:47  夜的那种黑丶  阅读(4642)  评论(0编辑  收藏  举报