全部产品
阿里云办公

Spring Cloud 服务接入 EDAS

更新时间:2019-01-15 20:28:06

本文介绍如何使用 ANS 将您的 Spring Cloud 应用接入 EDAS,并使用 EDAS 服务注册中心实现服务发现。

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

EDAS 目前只支持 Spring Cloud Finchley 和 Spring Cloud Edgware 两个版本中的所有小版本。对应 Spring Boot 版本请参考 Spring 官网。其中与 Finchley 对应的版本为 0.2.0.RELEASE, 与 Spring Cloud Edgware 对应的版本为 0.1.0.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 其他组件紧密结合,为您提供一整套的微服务解决方案。

本地开发

本文档将以一个提供者和一个消费者为例,向您介绍如何如何在本地开发服务提供者、消费者,如何部署到 EDAS 中,在 EDAS 服务注册中心完成服务注册,以及实现消费者对提供者的调用。

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

准备工作

  • 下载、启动及配置轻量级配置中心。

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

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

  • 下载 Maven 并设置环境变量。

创建服务提供者

  1. 创建一个 Spring Cloud 工程,命名为 service-provider。

    这里我们以 Spring Boot 2.0.6.RELEASE 和 Spring Cloud Finchley.SR1 为例,在 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.0.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 1.x 的版本,请使用 Spring Boot 1.5.x 和 Spring Cloud Edgware 版本,对应的 Spring Cloud Alibaba 版本为 0.1.0.RELEASE。

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

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

    1. @SpringBootApplication
    2. @EnableDiscoveryClient
    3. public class ServerApplication {
    4. public static void main(String[] args) {
    5. SpringApplication.run(ServerApplication.class, args);
    6. }
    7. }
  3. 创建一个简单的 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. }
  4. 在 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.1 和 spring.cloud.alicloud.ans.server-port=8080这两个参数仅在本地开发环境使用轻量级配置中心作为服务注册的场景下使用,当应用部署到 EDAS 中时,这两个参数可以去掉,也可以保留,不影响服务注册和使用。

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

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

创建服务消费者

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

  1. 创建一个 Spring Cloud 工程,命名为 service-consumer。在 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.0.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>
  2. 配置 RestTemplate、AsyncRestTemplate 和 FeignClient。

    1. FeignClient 是一个将HTTP 转为 RPC 格式调用的客户端。在使用他之前,我们需完成两项配置:

      1. @EnableFeignClient注解。

      2. 配置对应的 HTTP URL 地址及 HTTP 方法。

        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. }
  3. 创建 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. }
  4. 在 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
  5. 执行 service-consumer 中的 main 函数,启动服务。

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

结果验证

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

服务调用

部署到 EDAS

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

注意:各类型集群都支持 Spring Cloud 应用(使用 ANS 进行服务注册和发现),在 Swarm 集群和容器服务 Kubernetes 集群部署时需要添加额外配置。详情见下表:

集群类型 额外配置
ECS 集群
Swarm 集群 需要在应用详情页 > 应用设置 > 配置 JVM 参数时添加 -Dalicloud.deployment.mode=EDAS_MANAGED
容器服务 Kubernetes 集群 需要应用制作镜像时在命令行参数中添加 JVM 参数 -Dalicloud.deployment.mode=EDAS_MANAGED

发布单流程会通过优先级更高的方式去设置所有中间件相关的服务端地址、服务端口,以及中间件通信时的鉴权信息,您都无需关心。比如以下的配置可以继续保留或者不填写。

  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. 根据您想部署的集群类型,参考对应的部署应用文档部署应用。

配置项参考

配置项 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

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

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

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

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

后续操作

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