Nacos 2.x 入门系列【8】集成 Spring Cloud Gateway

57 阅读3分钟

1. 概述

1.1 API 网关

API网关已经成为了微服务架构的一个标配组件,是系统对外的唯一入口。所有的客户端都通过统一的网关接入微服务,在网关层处理所有非业务功能。

API网关的主要作用包括如下几点:

  1. 统一对外接口
  2. 增加系统安全性
  3. 统一鉴权
  4. 服务注册与授权
  5. 服务限流
  6. 提升预发能力
  7. 全链路跟踪

常用网关解决方案:

  1. Netflix Zuul(已被淘汰)
  2. Spring Cloud Gateway
  3. Nginx + Lua
  4. Kong
  5. Traefik
  6. Orange

1.1 Spring Cloud Gateway

官方文档

Spring Cloud Gateway是基于Spring生态系统之上构建的API网关,包括Spring 6Spring Boot 3Project Reactor

Netflix Zuul的替代方案,不仅提供统一的路由方式,还提供安全、指标度量、限流等方面的功能。 依托于Spring Cloud生态,Spring Cloud Gateway已经成为微服务架构中最流行的API网关。

Spring Cloud Gateway三大核心概念:

  • Route:路由,网关的基本构建块。它由一个ID、一个目标URI、一组谓词和一组过滤器定义。
  • PredicateJava 8中的函数谓词,输入类型为Spring Framework ServerWebExchange,允许匹配HTTP请求中的任何内容,例如标头或参数。如果聚合谓词为true,则匹配路由。
  • Filter:过滤器,Gateway Filter的实例,由特定工厂构建,可以在发送下游请求之前或之后修改请求和响应。

2. 集成案例

2.1 入门案例

在之前的测试工程中创建一个网关模块gateway-demoimage.png

引入spring-cloud-starter-gateway依赖:

<?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.pearl</groupId>
        <artifactId>nacos-demo</artifactId>
        <version>0.0.1-SNAPSHOT</version>
    </parent>

    <artifactId>gateway-demo</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>gateway-demo</name>
    <description>gateway-demo</description>

    <properties>
        <java.version>17</java.version>
    </properties>

    <dependencies>
        <!--API 网关-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-gateway</artifactId>
        </dependency>
    </dependencies>

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

</project>

spring-cloud-starter-gateway依赖中包含了网关以及WebFluximage.png

启动类:

@SpringBootApplication
public class GatewayDemoApplication {

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

application.yml添加端口、服务名、路由规则配置:

server:
  port: 80
spring:
  application:
    name: gateway-demo
  cloud:
    gateway:
      routes:
        - id: order-demo                # 路由唯一ID
          uri: http://localhost:9001    # 目标URI
          predicates:                   # 断言,为真则匹配成功
            - Path=/order/**            # 配置规则Path,如果是order开头的请求,则会将该请求转发到目标URI 

启动项目查看日志,可以看到底层使用的是Nettyimage.png 首先,我们直接访问订单服务中的接口: image.png

然后通过网关地址访问,可以看到网关根据路由配置进行了转发: image.png

2.2 动态路由

在上面的案例中,我们的路由都是写在配置文件中的,在微服务架构中,后台有很多个,地址也是动态的,这么配置肯定是不现实的,所以Spring Cloud Gateway提供了基于注册中心服务发现机制的动态路由。

Spring Cloud Gateway支持与EurekaNacosConsul等进行整合,根据service ld自动从注册中心获取服务地址并转发请求,这样做的好处不仅可以通过单个端点来访问应用的所有服务,而且在添加或移除服务实例时不用修改网关的路由配置。

首先添加NacosLoad Balancer依赖:

        <!-- Nacos 服务发现客户端-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>
        <!--客户端负载均衡器-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-loadbalancer</artifactId>
        </dependency>

application.yml添加Nacos地址以及动态路由配置:

server:
  port: 80
spring:
  application:
    name: gateway-demo
  cloud:
    nacos:
      # 服务发现
      discovery:
        username: nacos
        password: nacos
        # 命名空间
        namespace: 0faa0970-1179-4143-8aa2-cac3ee6b42ec
        # 服务端地址,默认:127.0.0.1:8848
        server-addr: 127.0.0.1:8848
    gateway:
      discovery:
        locator:
          # 开启服务发现动态路由
          enabled: true
          # 是否将服务名称小写
          lower-case-service-id: true

通过以下方式访问:

# 网关地址/服务注册名/目标请求路径  
http://localhost/app-service001/app1/test

成功通过服务名,转发到具体的后台应用: image.png