您可以将Spring Cloud微服务应用托管到EDAS,使用EDAS提供的共享组件、企业级安全加固和完整的微服务解决方案,帮助您节省运维成本、提升安全性和开发效率。本文将介绍如何在本地开发一个Spring Cloud微服务示例应用(包含一个服务提供者Provider和一个服务消费者Consumer)并部署到EDAS。

背景信息

本文将从不同层面为您解释如何将Spring Cloud应用托管到EDAS:

  • 如果您完全不了解Spring Cloud,只有简单的Spring和Maven基础,详细阅读本文后,您将了解如何通过Spring Cloud Alibaba Nacos Discovery实现Spring Cloud应用的服务注册与发现,以及实现消费者对提供者的调用。
  • 如果您熟悉Spring Cloud中的服务注册组件(如Eureka、Consul和ZooKeeper),可以直接将基于这些注册中心开发的应用部署到EDAS,无需修改任何代码和配置,详情请参见应用部署概述(ECS集群)应用部署概述(K8s集群)),并使用EDAS完整的微服务能力。
  • 如果您熟悉如何使用开源版本的Spring Cloud Alibaba Nacos Discovery实现Spring Cloud应用的服务注册与发现,那么您可以将应用直接部署到EDAS(详情请参见应用部署概述(ECS集群)应用部署概述(K8s集群)),即可使用到EDAS提供的商业版服务注册与发现的能力。

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

您也可以选择自建的Nacos、ZooKeeper集群、或者使用MSE托管的注册中心,详情请参见什么是微服务引擎MSE

准备工作

本地开发中主要描述开发中涉及的关键信息,如果您想了解完整的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的地址。如果您的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

将应用部署到EDAS

当在本地完成应用的开发和测试后,便可将应用程序打包并部署到EDAS。您可以根据您的实际情况选择将Spring Cloud应用可以部署到ECS集群或容器服务Kubernetes集群。部署应用的详细步骤请参见应用部署概述(ECS集群)应用部署概述(K8s集群)

说明
  • 第一次部署建议通过控制台部署,且如果使用JAR包部署,在创建应用时应用运行环境务必选择标准Java应用运行环境
  • EDAS提供了Nacos的商用版本,基于Nacos开发的应用部署到EDAS时,EDAS会自动将您本地的Nacos server地址(http://127.0.0.1:8848/nacos)替换为EDAS提供的Nacos商用版本地址,您无需修改。
EDAS应用部署方式

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

结果验证

在部署完成之后,在EDAS控制台左侧导航栏选择微服务管理 > 服务查询,在服务查询页面选择地域命名空间,然后通过搜索service-providerservice-consumer查询您部署的应用。

配置项参考

配置项 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.endpoint UTF-8 地域的某个服务的入口域名,通过此域名可以动态地拿到服务端地址,此配置在部署到EDAS时无需填写。
是否集成Ribbon ribbon.nacos.enabled true 一般不需要修改。

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