全部产品
云市场

将 Spring Cloud 应用托管到 EDAS

更新时间:2019-08-05 22:02:26

本文档将以一个服务提供者和一个服务消费者为例,介绍如何在本地开发(添加依赖和所需配置)、测试,并部署到 EDAS 中。实现应用的服务注册与发现,以及消费者对提供者的调用。

说明:如果您熟悉 Spring Cloud,阅读本文档后,可以发现,使用 ANS 与之前使用 Eureka 或者 Consul 实现服务注册与发现的使用方式没有任何差别。从 Eureka 和 Consul 迁移到 ANS 无需修改任何代码。

注意:EDAS 目前支持 Spring Cloud Greenwich、Spring Cloud Finchley 和 Spring Cloud Edgware 版本中的所有小版本。对应 Spring Boot 版本请参考 Spring 官网。

  • 与 Greenwich 对应的 Spring Cloud Alibaba 版本为 0.9.0.RELEASE。
  • 与 Finchley 对应的 Spring Cloud Alibaba 版本为 0.2.2.RELEASE。
  • 与 Edgware 对应的 Spring Cloud Alibaba 版本为 0.1.2.RELEASE。

为什么使用 ANS

应用名字服务 ANS(Application Naming Service)是 EDAS 提供的服务发现组件,是开源 Nacos 的商业化版本。

Spring Cloud Alibaba Ans 实现了 Spring Cloud Registry 的标准接口与规范,可以完全地替代 Spring Cloud Eureka 和 Spring Cloud Consul 提供的服务发现功能。

同时,与 Eureka 和 Consul 相比,还具有以下优势:

  • ANS 为共享组件,节省了你部署、运维 Eureka 或 Consul 的成本。
  • ANS 在注册和发现的调用中都进行了链路加密,保护您的服务,无需再担心服务被其他人发现。
  • ANS 与 EDAS 其他组件紧密结合,为您提供一整套的微服务解决方案。

本地开发

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

准备工作

  • 下载?Maven?并设置环境变量。
  • 下载、启动及配置轻量级配置中心。

    为了便于本地开发,EDAS 提供了一个包含了 EDAS 服务注册中心基本功能的轻量级配置中心。基于轻量级配置中心开发的应用无需修改任何代码和配置就可以部署到云端的 EDAS 中。

    请您参考配置轻量级配置中心进行下载、启动及配置。推荐使用最新版本。

- 【推荐】使用 IDE 插件连接 EDAS 云端环境

为了免于搭建本地配置中心和微服务环境,EDAS 向开发者提供了 IDE 插件。通过一键开启 IDE 插件的端云联调功能,即可将本地应用注册到 EDAS 云端注册中心,与云端服务进行通信。

请您参考 Eclipse 联调插件Intellij IDEA 联调插件进行安装使用。

创建服务提供者

在本地创建一个提供者应用工程,添加依赖,开启服务注册与发现功能,并将注册中心指定为 EDAS 轻量级配置中心。

  1. 创建一个应用工程,命名为service-provider

  2. pom.xml文件中添加依赖。

    这里以 Spring Boot 2.0.6.RELEASE 和 Spring Cloud Finchley.SR1 为例说明。

    1. <parent>
    2. <groupId>org.springframework.boot</groupId>
    3. <artifactId>spring-boot-starter-parent</artifactId>
    4. <version>2.0.6.RELEASE</version>
    5. <relativePath/>
    6. </parent>
    7. <dependencies>
    8. <dependency>
    9. <groupId>org.springframework.cloud</groupId>
    10. <artifactId>spring-cloud-starter-alicloud-ans</artifactId>
    11. <version>0.2.1.RELEASE</version>
    12. </dependency>
    13. <dependency>
    14. <groupId>org.springframework.boot</groupId>
    15. <artifactId>spring-boot-starter-web</artifactId>
    16. </dependency>
    17. </dependencies>
    18. <dependencyManagement>
    19. <dependencies>
    20. <dependency>
    21. <groupId>org.springframework.cloud</groupId>
    22. <artifactId>spring-cloud-dependencies</artifactId>
    23. <version>Finchley.SR1</version>
    24. <type>pom</type>
    25. <scope>import</scope>
    26. </dependency>
    27. </dependencies>
    28. </dependencyManagement>

    示例中为 Spring Boot 2.x 的版本。如果要使用 Spring Boot 1.x 的版本,请使用 Spring Boot 1.5.xSpring Cloud Edgware,对应的 Spring Cloud Alibaba 版本为 0.1.0.RELEASE

    说明:Spring Boot 1.x 版本的生命周期即将在 2019 年 8 月 结束,推荐使用新版本开发应用。

  3. 开发服务提供者的启动类,其中@EnableDiscoveryClient注解表明此应用需开启服务注册与发现功能。

    1. @SpringBootApplication
    2. @EnableDiscoveryClient
    3. public class ServerApplication {
    4. public static void main(String[] args) {
    5. SpringApplication.run(ServerApplication.class, args);
    6. }
    7. }
  4. 创建一个简单的Controller,指定 URL mapping 为 {/echo/{String}},指定 HTTP 方法为 GET,方法参数从 URL 路径中获得,回显收到的参数。

    1. @RestController
    2. public class EchoController {
    3. @RequestMapping(value = "/echo/{string}", method = RequestMethod.GET)
    4. public String echo(@PathVariable String string) {
    5. return string;
    6. }
    7. }
  5. application.properties中添加如下配置,将注册中心指定为 EDAS 轻量级配置中心。

    其中 127.0.0.1 为轻量级配置中心的地址,如果您的轻量级配置中心部署在另外一台机器,则需要修改成对应的 IP 地址。由于轻量级配置中心不支持修改端口,所以端口必须使用 8080。

    1. spring.application.name=service-provider
    2. server.port=18081
    3. spring.cloud.alicloud.ans.server-list=127.0.0.1
    4. spring.cloud.alicloud.ans.server-port=8080

    注意spring.cloud.alicloud.ans.server-list=127.0.0.1spring.cloud.alicloud.ans.server-port=8080 仅在本地开发使用轻量级配置中心作为服务注册的时使用。当应用部署到 EDAS 中时,这两个参数可以去掉,也可以保留,不影响服务注册和使用。

  6. 执行service-provider中的main函数,启动服务。

  7. 登录轻量级配置中心控制台界面 http://127.0.0.1:8080,在左侧导航栏中单击服务列表 ,查看提供者列表。可以看到服务提供者里已经包含了 service-provider,且可以查询该服务的分组和地址。

创建服务消费者

该部分文档我们不仅演示了服务发现的功能,还说明了 ANS 服务发现与 RestTemplate、AsyncRestTemplate 和 FeignClient 这三个客户端是如何结合的。

  1. 创建一个应用工程,命名为service-consumer

  2. pom.xml中添加需要的依赖。

    1. <parent>
    2. <groupId>org.springframework.boot</groupId>
    3. <artifactId>spring-boot-starter-parent</artifactId>
    4. <version>2.0.6.RELEASE</version>
    5. <relativePath/>
    6. </parent>
    7. <dependencies>
    8. <dependency>
    9. <groupId>org.springframework.cloud</groupId>
    10. <artifactId>spring-cloud-starter-alicloud-ans</artifactId>
    11. <version>0.2.1.RELEASE</version>
    12. </dependency>
    13. <dependency>
    14. <groupId>org.springframework.cloud</groupId>
    15. <artifactId>spring-cloud-starter-openfeign</artifactId>
    16. </dependency>
    17. <dependency>
    18. <groupId>org.springframework.boot</groupId>
    19. <artifactId>spring-boot-starter-web</artifactId>
    20. </dependency>
    21. </dependencies>
    22. <dependencyManagement>
    23. <dependencies>
    24. <dependency>
    25. <groupId>org.springframework.cloud</groupId>
    26. <artifactId>spring-cloud-dependencies</artifactId>
    27. <version>Finchley.SR1</version>
    28. <type>pom</type>
    29. <scope>import</scope>
    30. </dependency>
    31. </dependencies>
    32. </dependencyManagement>
  3. 配置 RestTemplate、AsyncRestTemplate 和 FeignClient。

    1. 创建一个接口,添加@FeignClient注解,并配置对应的 HTTP URL 地址及 HTTP 方法。

      FeignClient 是一个将 HTTP 转为 RPC 格式调用的客户端。

      1. @FeignClient(name = "service-provider")
      2. public interface EchoService{
      3. @RequestMapping(value = "/echo/{str}", method = RequestMethod.GET)
      4. String echo(@PathVariable("str") String str);
      5. }
    2. 创建启动类并添加配置。

      1. 使用@EnableDiscoveryClient注解启用服务注册与发现。

      2. 使用@EnableFeignClients注解激活 FeignClient。

      3. 添加@LoadBalanced注解将 RestTemplate 与 AsyncRestTemplate 与服务发现集成。

        1. @SpringBootApplication
        2. @EnableDiscoveryClient
        3. @EnableFeignClients
        4. public class ConsumerApplication {
        5. @LoadBalanced
        6. @Bean
        7. public RestTemplate restTemplate() {
        8. return new RestTemplate();
        9. }
        10. @LoadBalanced
        11. @Bean
        12. public AsyncRestTemplate asyncRestTemplate(){
        13. return new AsyncRestTemplate();
        14. }
        15. public static void main(String[] args) {
        16. SpringApplication.run(ConsumerApplication.class, args);
        17. }
        18. }
  4. 创建Controller以演示和验证服务发现功能。

    1. @RestController
    2. public class TestController {
    3. @Autowired
    4. private RestTemplate restTemplate;
    5. @Autowired
    6. private AsyncRestTemplate asyncRestTemplate;
    7. @Autowired
    8. private EchoService echoService;
    9. @RequestMapping(value = "/echo-rest/{str}", method = RequestMethod.GET)
    10. public String rest(@PathVariable String str) {
    11. return restTemplate.getForObject("http://service-provider/echo/" + str, String.class);
    12. }
    13. @RequestMapping(value = "/echo-async-rest/{str}", method = RequestMethod.GET)
    14. public String asyncRest(@PathVariable String str) throws Exception{
    15. ListenableFuture<ResponseEntity<String>> future = asyncRestTemplate.
    16. getForEntity("http://service-provider/echo/"+str, String.class);
    17. return future.get().getBody();
    18. }
    19. @RequestMapping(value = "/echo-feign/{str}", method = RequestMethod.GET)
    20. public String feign(@PathVariable String str) {
    21. return echoService.echo(str);
    22. }
    23. }
  5. application.properties中添加如下配置,将注册中心指定为 EDAS 轻量级配置中心。

    其中 127.0.0.1 为轻量级配置中心的地址,如果您的轻量级配置中心部署在另外一台机器,则需要修改成对应的 IP 地址。由于轻量级配置中心不支持修改端口,所以端口必须使用 8080。

    1. spring.application.name=service-consumer
    2. server.port=18081
    3. spring.cloud.alicloud.ans.server-list=127.0.0.1
    4. spring.cloud.alicloud.ans.server-port=8080
  6. 执行service-consumer中的main函数,启动服务。

  7. 登录轻量级配置中心控制台界面 http://127.0.0.1:8080,在左侧导航栏中单击服务列表 ,查看提供者列表。可以看到服务提供者里已经包含了 service-consumer,且可以查询该服务的分组和地址。

结果验证

分别调用我们的演示 API,可以看到调用成功的结果。

服务调用

部署到 EDAS

ANS 在设计之初就考虑到了从开发环境迁移到 EDAS 的场景,您可以直接将应用部署到 EDAS 中。

注意:各类型集群(环境)都支持 Spring Cloud 应用(使用 ANS 进行服务注册和发现),详情见下表:

集群(环境)类型 额外配置
ECS 集群
Swarm 集群 需要在应用详情页 > 应用设置 > 配置 JVM 参数时添加 -Dalicloud.deployment.mode=EDAS_MANAGED (Swarm集群将在未来某个时间下线,不推荐用来部署原生 SpringCloud 应用)。
容器服务 Kubernetes 集群 无(按照文档要求制作镜像即可)
Serverless 环境

当您将应用部署到 EDAS 的时候,EDAS 会通过优先级更高的方式去设置所有中间件相关的服务端地址、服务端口,以及中间件通信时的鉴权信息。您无需进行任何配置,比如以下的配置可以继续保留或者不填写。

  1. spring.cloud.alicloud.ans.server-list=127.0.0.1
  2. spring.cloud.alicloud.ans.server-port=8080
  1. 分别在 service-roviderservice-onsumerpom.xml 文件中添加如下配置,然后执行 mvn clean package 将本地的程序打成可执行 JAR 包。

    • Provider

      1. <build>
      2. <plugins>
      3. <plugin>
      4. <groupId>org.springframework.boot</groupId>
      5. <artifactId>spring-boot-maven-plugin</artifactId>
      6. </plugin>
      7. </plugins>
      8. </build>
    • Consumer

      1. <build>
      2. <plugins>
      3. <plugin>
      4. <groupId>org.springframework.boot</groupId>
      5. <artifactId>spring-boot-maven-plugin</artifactId>
      6. </plugin>
      7. </plugins>
      8. </build>
  2. 根据您想部署的集群类型,参考对应的部署应用文档部署应用。

    当您选择使用 ECS 集群部署 Spring Cloud 应用的 JAR 包时,在创建应用时应用运行环境务必选择标准Java应用运行环境

    SC 应用运行环境选择

配置项参考

在开发过程中,您还可以根据实际需求添加以下配置项。

配置项 key 默认值 说明
服务名 spring.cloud.alicloud.ans.client-domains spring.application.name 当此项未配置时,默认从 spring.application.name 中获取。需要发布多个服务时,中间用英文的“,”号隔开。
是否注册 spring.cloud.alicloud.ans.register-enabled true 当只需要发现,不需要注册时,可以通过将值设置成 false 来关闭注册。
想要注册的 IP spring.cloud.alicloud.ans.client-ip 当需要指定本机注册的 IP 时,通过此值来配置,优先级最高。
想要注册的 IP 所属的网卡 spring.cloud.alicloud.ans.client-interface-name 当确定需要发布哪块网卡对应的 IP 地址时,通过此参数配置,值为网卡名。
想要注册的端口 spring.cloud.alicloud.ans.client-port 自定义想要注册的端口。

FAQ

  • 我看到我的服务注册成功了,如何调用呢?

    答:spring-cloud-starter-alicloud-ans 默认支持集成了 Ribbon 支持,您可以使用 RestTemplate 和 FeignClient 调用。

  • 为什么我的服务注册总是失败?

    答:如果您在确认账号信息都准确无误的情况下,但是运行此文档中的 Demo 却注册失败了。有可能是由于您本机的时间不准确,从而导致验签鉴权失败。此时您需要校正本机的时间,建议打开时间自动同步功能。

后续操作

在将 Spring Cloud 应用接入到 EDAS,实现了服务注册与发现功能后,您还可以在应用中实现以下功能,再部署到 EDAS 中。