本文以包含服务提供者和服务消费者的 Spring Cloud 应用为例,让您快速体验如何在本地开发、调试 Spring Cloud 应用并部署到 SAE 中,实现应用的服务注册与发现,以及消费者对提供者的调用。

背景信息

  • 如果您对 Spring Cloud 很陌生,仅了解 Spring 和 Maven 基础知识,那么阅读本文后,您将掌握如何通过 Spring Cloud Alibaba Nacos Discovery 实现 Spring Cloud 应用的服务注册与发现,以及实现消费者对提供者的调用。
  • 如果您熟悉 Spring Cloud 中的 Eureka、Consul 和 ZooKeeper 等服务注册组件,但未使用过 Spring Cloud Alibaba 的服务注册组件 Nacos Discovery,那么您仅需将服务注册组件的服务依赖关系和服务配置替换成 Spring Cloud Alibaba Nacos Discovery,无需修改任何代码。

    Spring Cloud Alibaba Nacos Discovery 同样实现了 Spring Cloud Registry 的标准接口与规范,与您之前使用 Spring Cloud 接入服务注册与发现的方式基本一致。

  • 如果您熟悉如何使用开源版本的 Spring Cloud Alibaba Nacos Discovery 实现 Spring Cloud 应用的服务注册与发现,那么您可以将应用直接部署到 SAE,即可使用到 SAE 提供的商业版服务注册与发现的能力,详情请参见应用部署概述

为什么使用 SAE 服务注册中心

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

SAE 服务注册中心与 Nacos、Eureka 和 Consul 相比,具有以下优势:

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

您在 SAE 部署应用时,SAE服务注册中心以高优先级自动设置Nacos Server服务端地址和服务端口,以及 namespace、access-key、secret-key、context-path 等信息,无需进行任何额外的配置。

视频教程

本视频仅介绍如何使用 Spring Cloud 开发微服务应用,部署部分请参见在SAE控制台部署应用

准备工作

本地开发中主要描述开发中涉及的关键信息,如果您想了解完整的 Spring Cloud 应用程序,可下载 service-providerservice-consumer

在开始开发前,请确保您已经完成以下工作:

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

创建服务提供者

在本地创建服务提供者应用工程,添加依赖,开启服务注册与发现功能,并将注册中心指定为 Nacos Server。

  1. 创建命名为nacos-service-provider的 Maven 工程。
  2. pom.xml 文件中添加依赖。

    以 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>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
            <version>2.1.1.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </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>                  

    示例中使用的版本为 Spring Cloud Greenwich ,对应 Spring Cloud Alibaba 版本为 2.1.1.RELEASE。

    • 如果使用 Spring Cloud Finchley 版本,对应 Spring Cloud Alibaba 版本为 2.0.1.RELEASE。
    • 如果使用 Spring Cloud Edgware 版本,对应 Spring Cloud Alibaba 版本为 1.5.1.RELEASE。
    说明 Spring Cloud Edgware 版本的生命周期已结束,不推荐使用这个版本开发应用。
  3. src\main\java下创建 Packagecom.aliware.edas
  4. 在 Packagecom.aliware.edas中创建服务提供者的启动类ProviderApplication,并添加如下代码。

    其中@EnableDiscoveryClient注解表明此应用需开启服务注册与发现功能。

        package com.aliware.edas;
    
        import org.springframework.boot.SpringApplication;
        import org.springframework.boot.autoconfigure.SpringBootApplication;
        import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
    
        @SpringBootApplication
        @EnableDiscoveryClient
        public class ProviderApplication {
    
            public static void main(String[] args) {
                SpringApplication.run(ProviderApplication.class, args);
            }
        }             
  5. 在 Packagecom.aliware.edas中创建EchoController,指定 URL mapping 为 {/echo/{String}},指定 HTTP 方法为 GET,方法参数从 URL 路径中获得,回显收到的参数。
        package com.aliware.edas;
    
        import org.springframework.web.bind.annotation.PathVariable;
        import org.springframework.web.bind.annotation.RequestMapping;
        import org.springframework.web.bind.annotation.RequestMethod;
        import org.springframework.web.bind.annotation.RestController;
    
        @RestController
        public class EchoController {
            @RequestMapping(value = "/echo/{string}", method = RequestMethod.GET)
            public String echo(@PathVariable String string) {
                return string;
            }
        }              
  6. src\main\resources路径下创建文件application.properties,在application.properties中添加如下配置,指定 Nacos Server 的地址。

    其中127.0.0.1为 Nacos Server 的地址。如果您的 Nacos Server 部署在其他设备,则需要修改成对应的 IP 地址。如果有其它需求,可以参考配置项参考application.properties文件中增加配置。

    spring.application.name=service-provider
    server.port=18081
    spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848               
  7. 验证结果。
    1. 执行nacos-service-providerProviderApplicationmain函数,启动应用。
    2. 登录本地启动的 Nacos Server 控制台http://127.0.0.1:8848/nacos(本地 Nacos 控制台的默认用户名和密码同为 nacos)。
    3. 在左侧导航栏中选择服务管理 > 服务列表
      可以看到服务列表中已经包含了service-provider,且在详情中可以查询该服务的详情。

创建服务消费者

本内容除介绍服务注册的功能,还将介绍 Nacos 服务发现与 RestTemplate 和 FeignClient 两个客户端如何配合使用。

  1. 创建命名为nacos-service-consumer的 Maven 工程。
  2. pom.xml中添加依赖。
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.4.RELEASE</version>
        <relativePath/>
    </parent>
    
    <dependencies>
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
            <version>2.1.1.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </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. src\main\java下创建 Packagecom.aliware.edas
  4. 在 Packagecom.aliware.edas中配置 RestTemplate 和 FeignClient。
    1. 在 Packagecom.aliware.edas 中创建一个接口类EchoService,添加@FeignClient注解,并配置对应的 HTTP URL 地址及 HTTP 方法。
      package com.aliware.edas;
      
      import org.springframework.cloud.openfeign.FeignClient;
      import org.springframework.web.bind.annotation.PathVariable;
      import org.springframework.web.bind.annotation.RequestMapping;
      import org.springframework.web.bind.annotation.RequestMethod;
      
      @FeignClient(name = "service-provider")
      public interface EchoService {
          @RequestMapping(value = "/echo/{str}", method = RequestMethod.GET)
          String echo(@PathVariable("str") String str);
      }                   
    2. 在 Packagecom.aliware.edas 中创建启动类ConsumerApplication并添加相关配置。
      • 使用@EnableDiscoveryClient注解启用服务注册与发现。
      • 使用@EnableFeignClients注解激活 FeignClient。
      • 添加@LoadBalanced注解将 RestTemplate 与服务发现集成。
      package com.aliware.edas;
      
      import org.springframework.boot.SpringApplication;
      import org.springframework.boot.autoconfigure.SpringBootApplication;
      import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
      import org.springframework.cloud.client.loadbalancer.LoadBalanced;
      import org.springframework.cloud.openfeign.EnableFeignClients;
      import org.springframework.context.annotation.Bean;
      import org.springframework.web.client.RestTemplate;
      
      @SpringBootApplication
      @EnableDiscoveryClient
      @EnableFeignClients
      public class ConsumerApplication {
      
          @LoadBalanced
          @Bean
          public RestTemplate restTemplate() {
              return new RestTemplate();
          }
      
          public static void main(String[] args) {
              SpringApplication.run(ConsumerApplication.class, args);
          }
      }
  5. 在 Packagecom.aliware.edas 中创建类TestController以演示和验证服务发现功能。
        package com.aliware.edas;
    
        import org.springframework.beans.factory.annotation.Autowired;
        import org.springframework.web.bind.annotation.PathVariable;
        import org.springframework.web.bind.annotation.RequestMapping;
        import org.springframework.web.bind.annotation.RequestMethod;
        import org.springframework.web.bind.annotation.RestController;
        import org.springframework.web.client.RestTemplate;
    
        @RestController
        public class TestController {
    
            @Autowired
            private RestTemplate restTemplate;
            @Autowired
            private EchoService echoService;
    
            @RequestMapping(value = "/echo-rest/{str}", method = RequestMethod.GET)
            public String rest(@PathVariable String str) {
                return restTemplate.getForObject("http://service-provider/echo/" + str,
                        String.class);
            }
    
            @RequestMapping(value = "/echo-feign/{str}", method = RequestMethod.GET)
            public String feign(@PathVariable String str) {
                return echoService.echo(str);
            }
    
        }           
  6. src\main\resources 路径下创建文件 application.properties,在 application.properties 中添加如下配置,指定 Nacos Server 的地址。

    其中 127.0.0.1:8848 为 Nacos Server 的 IP 地址。如果您的 Nacos Server 部署在其他设备,则需要修改成对应的地址。如果有其它需求,可以参考配置项参考application.properties 文件中增加配置。

    spring.application.name=service-consumer
    server.port=18082
    spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848
  7. 验证结果。
    1. 执行nacos-service-consumerConsumerApplicationmain 函数,启动应用。
    2. 登录本地启动的 Nacos Server 控制台 http://127.0.0.1:8848/nacos(本地 Nacos 控制台的默认用户名和密码同为 nacos)。
    3. 在左侧导航栏中选择服务管理 > 服务列表,可以看到服务列表中已经包含了service-consumer,且在详情中可以查询该服务的详情。

本地测试

在本地测试消费者对提供者的服务调用结果。

  • Linux/Unix/Mac 系统:运行以下命令。

    curl http://127.0.0.1:18082/echo-rest/rest-rest
    curl http://127.0.0.1:18082/echo-feign/feign-rest
  • Windows系统:在浏览器中输入 http://127.0.0.1:18082/echo-rest/rest-resthttp://127.0.0.1:18082/echo-feign/feign-rest

将应用部署到 SAE

在本地完成应用的开发和测试后,便可将应用打包并部署到 SAE。详细步骤请参见部署应用概述
注意
  • SAE 暂不支持创建空应用,因此第一次部署需在控制台完成。
  • 如果使用 JAR 包部署,在应用部署配置时选择应用运行环境标准 Java 应用运行环境
  • 如果使用 WAR 包部署,在应用部署配置时应用运行环境apache-tomcat-XXX

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

说明
  • 使用自建 Nacos 时请确保 SAE 的网络与自建 Nacos 的网络互通。
  • 使用自建 Nacos 为服务注册中心,在部署应用时建议使用镜像方式或者 JAR 包方式,并配置启动参数-Dnacos.use.endpoint.parsing.rule=false-Dnacos.use.cloud.namespace.parsing=false
    • 如采用镜像方式,请将-Dnacos.use.endpoint.parsing.rule=false-Dnacos.use.cloud.namespace.parsing=false配置在镜像文件中。
    • 如果 JAR 包方式,请在部署时启动命令中设置。SAE自建Nacos部署应用之启动命令

如何制作镜像,具体请参见制作应用容器 Docker 镜像

结果验证

  1. 为部署到 SAE 的应用绑定 SLB,具体操作请见绑定公网 SLB
  2. 在浏览器输入配置好的公网访问地址,并在应用首页发起调用请求。
  3. 登录 SAE 控制台,进入消费者应用详情页面,在左侧导航栏选择应用监控 > 应用总览,查看服务调用数据总览。
    如果能够监测到调用数据,则说明服务调用成功。

配置项参考

配置项 Key 默认值 说明
服务端地址 spring.cloud.nacos.discovery.server-addr Nacos Server 启动监听的 IP 地址和端口。
服务名 spring.cloud.nacos.discovery.service ${spring.application.name} 给当前的服务命名。
网卡名 spring.cloud.nacos.discovery.network-interface 当 IP 未配置时,注册的 IP 为此网卡所对应的 IP 地址。如果此项也未配置,则默认取第一块网卡的地址。
注册的 IP 地址 spring.cloud.nacos.discovery.ip 优先级最高
注册的端口 spring.cloud.nacos.discovery.port -1 默认情况下不用配置,系统会自动探测。
命名空间 spring.cloud.nacos.discovery.namespace 常用场景之一是不同环境的注册的区分隔离,例如开发测试环境和生产环境的资源(如配置、服务)隔离等。
Metadata spring.cloud.nacos.discovery.metadata 使用 Map 格式配置,用户可以根据自己的需要自定义一些和服务相关的元数据信息。
集群 spring.cloud.nacos.discovery.cluster-name DEFAULT 配置成 Nacos 集群名称。
接入点 spring.cloud.nacos.discovery.enpoint UTF-8 地域的某个服务的入口域名,通过此域名可以动态地拿到服务端地址,此配置在部署到 EDAS 时无需填写。
是否集成 Ribbon ribbon.nacos.enabled true 一般不需要修改

更多关于 Spring Cloud Alibaba Nacos Discovery 的信息请参见开源版本的 Spring Cloud Alibaba Nacos Discovery 文档

常见问题

示例中使用的 Spring Cloud 版本为 Greenwich,对应的 Spring Cloud Alibaba 版本为 2.1.1.RELEASE。Spring Cloud Finchley 对应的 Spring Cloud Alibaba 版本为 2.0.1.RELEASE,Spring Cloud Edgware 对应的 Spring Cloud Alibaba 版本为 1.5.1.RELEASE。

说明 Spring Cloud Edgware 版本的生命周期已结束,不推荐使用这个版本开发应用。

更多信息

问题反馈

如果您在使用 SAE 过程中有任何疑问,欢迎您扫描下面的二维码加入钉钉群进行反馈。问题反馈