本文介绍如何基于 Spring Cloud Gateway 和 Spring Cloud Netflix Zuul 使用 Nacos 搭建应用的服务网关。

背景信息

SAE 服务注册中心提供了开源 Nacos Server 的正式商用版本,使用开源版本 Spring Cloud Alibaba Nacos Discovery开发的应用可以直接使用 SAE 提供的商业版服务注册中心。

商业版的 SAE 服务注册中心,与开源版本的 Nacos、Eureka 和 Consul 相比,还具有以下优势:

  • 共享组件,节省了你部署运维 Nacos、Eureka 或 Consul 的成本。
  • 在服务注册和发现的调用中都进行了链路加密,保护您的服务,无需再担心服务被未授权的应用发现。
  • SAE 服务注册中心 与 SAE 其他组件紧密结合,为您提供一整套的微服务解决方案,包括 环境隔离、平滑上下线、灰度发布等。

本文仅提供服务网关搭建过程中主要代码的改造方法,如果您想了解完整的 Spring Cloud 程序,可下载 spring-cloud-gateway-nacosspring-cloud-zuul-nacosnacos-service-provider

准备工作

  • 已下载 Maven 并设置环境变量。
  • 已下载最新版本的 Nacos Server并启动。
    说明
    启动 Nacos Server
    1. 解压已下载的 Nacos Server 压缩包。
    2. 进入nacos/bin目录,启动 Nacos Server。
      • Linux/Unix/Mac 系统:执行命令sh startup.sh -m standalone
      • Windows 系统:双击执行startup.cmd文件。

基于 Spring Cloud Gateway 搭建服务网关。

  • 创建服务网管关
    1. 创建名为spring-cloud-gateway-nacos的 Maven 工程。
    2. pom.xml文件中添加 Spring Boot 和 Spring Cloud 的依赖。

      本文以 Spring Boot 2.1.4.RELEASE 和 Spring Cloud Greenwich.SR1 版本为例。

       <parent>
           <groupId>org.springframework.boot</groupId>
           <artifactId>spring-boot-starter-parent</artifactId>
           <version>2.1.4.RELEASE</version>
           <relativePath/>
       </parent>
      
       <dependencies>
           <dependency>
               <groupId>org.springframework.cloud</groupId>
               <artifactId>spring-cloud-starter-gateway</artifactId>
           </dependency>
           <dependency>
               <groupId>org.springframework.cloud</groupId>
               <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
               <version>0.9.0.RELEASE</version>
           </dependency>
       </dependencies>
      
       <dependencyManagement>
           <dependencies>
               <dependency>
                   <groupId>org.springframework.cloud</groupId>
                   <artifactId>spring-cloud-dependencies</artifactId>
                   <version>Greenwich.SR1</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>
      							
    3. 创建服务网关启动类GatewayApplication
          @SpringBootApplication
          @EnableDiscoveryClient
          public class GatewayApplication {
              public static void main(String[] args) {
                  SpringApplication.run(GatewayApplication.class, args);
              }
          }
      							
    4. application.yaml中添加如下配置,将注册中心指定为 Nacos Server 的地址。

      其中127.0.0.1:8848为 Nacos Server 的IP地址。如果您的 Nacos Server 部署在另外一台机器,则需要修改成对应的地址。

      其中 routes 配置了 Gateway 的路由转发策略,本示例中此处将所有前缀为/provider1/的请求,全部由路由器分配到服务名为service-provider的后端服务中。

          server:
       port: 15012
      
          spring:
       application:
              name: spring-cloud-gateway-nacos
       cloud:
              gateway: # config the routes for gateway
                routes:
                - id: service-provider          # 将 /provider1/ 开头的请求转发到 provider1
                  uri: lb://service-provider
                  predicates:
                  - Path=/provider1/**
                  filters:
                  - StripPrefix=1               # 表明前缀 /provider1 需要截取掉
              nacos:
                discovery:
                  server-addr: 127.0.0.1:8848
      							
    5. 执行启动类GatewayApplication中的 main 函数,启动 Gateway。
    6. 登录本地已启动的本地 Nacos Server 控制台 http://127.0.0.1:8848/nacos (本地 Nacos 控制台的默认用户名和密码同为 nacos)。在左侧导航栏中选择服务管理 > 服务列表 ,可以看到服务列表中已经包含了 spring-cloud-gateway-nacos,且在详情页中可以查询该服务的详细信息。表示服务网关已经启动并注册成功,成功后需要通过创建下游服务验证网关的请求转发功能。
  • 创建服务提供者

    创建服务提供者应用,如何创建具体请参考将 Spring Cloud 应用托管到 SAE

    服务提供者示例:
    @SpringBootApplication
    @EnableDiscoveryClient
    public class ProviderApplication {
    
        public static void main(String[] args) {
    
            SpringApplication.run(ProviderApplication, args);
        }
    
        @RestController
        public class EchoController {
            @RequestMapping(value = "/echo/{string}", method = RequestMethod.GET)
            public String echo(@PathVariable String string) {
                return string;
            }
        }
    }
    						
  • 结果验证
    • 本地验证

      本地启动已经开发好的服务网关和服务提供者,访问 Spring Cloud Gateway 将请求转发给后端服务,可以看到调用成功后返回的结果。

    • 在 SAE 中验证

      请参考应用部署概述将您的应用部署到 SAE,并进行验证。

      SAE 服务注册中心提供了正式商用版本 Nacos Server。当您将应用部署到 SAE 的时候,SAE 会通过优先级更高的方式去设置 Nacos Server 服务端地址和服务端口,以及 namespace、access-key、secret-key、context-path 信息。您无需进行任何额外的配置,原有的配置内容可以选择保留或删除。

基于 Zuul 搭建服务网关

介绍如何基于 Zuul 使用 Nacos 作为服务注册中心搭建应用的服务网关。

  • 创建服务网关
    1. 创建名为spring-cloud-zuul-nacos的Maven 工程。
    2. pom.xml文件中添加 Spring Boot、Spring Cloud 和 Spring Cloud Alibaba 的依赖。

      Spring Boot :2.1.4.RELEASE、Spring Cloud :Greenwich.SR1 和 Spring Cloud :Alibaba 0.9.0 。

       <parent>
           <groupId>org.springframework.boot</groupId>
           <artifactId>spring-boot-starter-parent</artifactId>
           <version>2.1.4.RELEASE</version>
           <relativePath/>
       </parent>
      
       <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.springframework.cloud</groupId>
               <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
               <version>0.9.0.RELEASE</version>
           </dependency>
       </dependencies>
      
       <dependencyManagement>
           <dependencies>
               <dependency>
                   <groupId>org.springframework.cloud</groupId>
                   <artifactId>spring-cloud-dependencies</artifactId>
                   <version>Greenwich.SR1</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>    
      							
    3. 创建服务网关启动类ZuulApplication
          @SpringBootApplication
          @EnableZuulProxy
          @EnableDiscoveryClient
          public class ZuulApplication {
              public static void main(String[] args) {
                  SpringApplication.run(ZuulApplication.class, args);
              }
          }
      							
    4. application.properties中添加如下配置,将注册中心指定为 Nacos Server 的IP地址。
       spring.application.name=spring-cloud-zuul-nacos
       server.port=18022
      
       spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848
      
       zuul.routes.opensource-provider1.path=/provider1/**
       zuul.routes.opensource-provider1.serviceId=service-provider
      							

      127.0.0.1:8848为 Nacos Server 的IP地址。如果您的 Nacos Server 部署在另外一台机器,则需要修改成对应的IP地址。

      代码中 routes 配置了 Zuul 的路由转发策略,本示例中此处将所有前缀为/provider1/的请求,全部通过路由分配到服务名为service-provider的后端服务中。

    5. 执行 spring-cloud-zuul-nacos 中的 main 函数ZuulApplication,启动服务。
    6. 登录本地已启动的 Nacos Server 控制台 http://127.0.0.1:8848/nacos (本地 Nacos 控制台的默认用户名和密码同为 nacos),在左侧导航栏中选择服务管理 > 服务列表 ,可以看到服务列表中已经包含了 spring-cloud-zuul-nacos,且在详情页中可以查询该服务的详细信息。表示服务网关已经启动并注册成功,成功后需要通过创建下游服务验证网关的请求转发功能。
  • 创建服务提供者

    如何快速创建服务提供者,具体操作请参见将 Spring Cloud 应用托管到 SAE

    服务提供者启动类示例:
    @SpringBootApplication
    @EnableDiscoveryClient
    public class ProviderApplication {
    
        public static void main(String[] args) {
    
            SpringApplication.run(ProviderApplication, args);
        }
    
        @RestController
        public class EchoController {
            @RequestMapping(value = "/echo/{string}", method = RequestMethod.GET)
            public String echo(@PathVariable String string) {
                return string;
            }
        }
    }
    						
  • 结果验证
    1. 本地验证。

      本地启动已开发好的服务网关 Zuul 和服务提供者,访问 Spring Cloud Netflix Zuul 将请求转发给后端服务,可以看到调用成功后返回的结果。

    2. 在 SAE 中验证。

      您可以参考应用部署概述将您的应用部署到 SAE,并进行验证。

      SAE 服务注册中心提供了正式商用版本 Nacos Server。当您将应用部署到 SAE 的时候,SAE 会通过优先级更高的方式去设置 Nacos Server 服务端地址和服务端口,以及 namespace、access-key、secret-key、context-path 信息。您无需进行任何额外的配置,原有的配置内容可以选择保留或删除。

FAQ

  1. 使用其他版本

    示例中使用的 Spring Cloud 版本为 Greenwich,对应的 Spring Cloud Alibaba 版本为 0.9.0.RELEASE。Spring Cloud Finchley 对应的 Spring Cloud Alibaba 版本为 0.2.2.RELEASE,Spring Cloud Edgware 对应的 Spring Cloud Alibaba 版本为 0.1.2.RELEASE。

    说明 Spring Cloud Edgware 版本的生命周期即将在 2019 年 8 月结束,不推荐使用这个版本开发应用。
  2. 从 ANS 迁移

    SAE 注册中心在服务端对 ANS 和 Nacos 的数据结构做了兼容,在同一个命名空间下,且 Nacos 未设置 group 时,Nacos 和 ANS 客户端可以互相发现对方注册的服务。