Spring Cloud 微服务应用开发

本地开发应用

准备工作

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

TIP

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 为例:
  1. <parent>
  2. <groupId>org.springframework.boot</groupId>
  3. <artifactId>spring-boot-starter-parent</artifactId>
  4. <version>2.1.4.RELEASE</version>
  5. <relativePath/>
  6. </parent>
  7. <dependencies>
  8. <dependency>
  9. <groupId>com.alibaba.cloud</groupId>
  10. <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
  11. <version>2.1.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>Greenwich.SR1</version>
  24. <type>pom</type>
  25. <scope>import</scope>
  26. </dependency>
  27. </dependencies>
  28. </dependencyManagement>

示例中使用的版本为 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。

TIP

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

  1. 在 src/main/java 下创建 package: io.terminus.erda.trial.demo.hellospringcloud

在 package: io.terminus.erda.trial.demo.hellospringcloud 中创建服务提供者的启动类 ProviderApplication,并添加如下代码。其中 @EnableDiscoveryClient 注解表明此应用需开启服务注册与发现功能。

  1. package io.terminus.erda.trial.demo.hellospringcloud;
  2. import org.springframework.boot.SpringApplication;
  3. import org.springframework.boot.autoconfigure.SpringBootApplication;
  4. import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
  5. /**
  6. * @author erda
  7. */
  8. @SpringBootApplication
  9. @EnableDiscoveryClient
  10. public class ProviderApplication {
  11. public static void main(String[] args) {
  12. SpringApplication.run(ProviderApplication.class, args);
  13. }
  14. }

在 package: io.terminus.erda.trial.demo.hellospringcloud 中创建 EchoController,指定 URL mapping 为 {/echo/{String}},指定 HTTP 方法为 GET,方法参数从 URL 路径中获得,回显收到的参数。

  1. package io.terminus.erda.trial.demo.hellospringcloud;
  2. import org.springframework.web.bind.annotation.PathVariable;
  3. import org.springframework.web.bind.annotation.RequestMapping;
  4. import org.springframework.web.bind.annotation.RequestMethod;
  5. import org.springframework.web.bind.annotation.RestController;
  6. /**
  7. * @author erda
  8. */
  9. @RestController
  10. public class EchoController {
  11. @RequestMapping(value = "/echo/{string}", method = RequestMethod.GET)
  12. public String echo(@PathVariable String string) {
  13. return string;
  14. }
  15. }
  1. 在 src/main/resources 路径下创建文件 application.yml ,在 application.yml 中添加如下配置,指定 Nacos Server 的地址。

TIP

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

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

创建服务消费者

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

  1. 创建命名为 nacos-service-consumer 的 Maven 工程。
  2. 在 pom.xml 中添加依赖。
  1. <parent>
  2. <groupId>org.springframework.boot</groupId>
  3. <artifactId>spring-boot-starter-parent</artifactId>
  4. <version>2.1.4.RELEASE</version>
  5. <relativePath/>
  6. </parent>
  7. <dependencies>
  8. <dependency>
  9. <groupId>com.alibaba.cloud</groupId>
  10. <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
  11. <version>2.1.0.RELEASE</version>
  12. </dependency>
  13. <dependency>
  14. <groupId>org.springframework.boot</groupId>
  15. <artifactId>spring-boot-starter-web</artifactId>
  16. </dependency>
  17. <dependency>
  18. <groupId>org.springframework.cloud</groupId>
  19. <artifactId>spring-cloud-starter-openfeign</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>Greenwich.SR1</version>
  28. <type>pom</type>
  29. <scope>import</scope>
  30. </dependency>
  31. </dependencies>
  32. </dependencyManagement>
  1. 在 src/main/java 下创建 package: io.terminus.erda.trial.demo.hellospringcloud
  2. 在 package: io.terminus.erda.trial.demo.hellospringcloud 中配置 RestTemplate 和 FeignClient。

在 package: io.terminus.erda.trial.demo.hellospringcloud 中创建一个接口类 EchoService ,添加 @FeignClient 注解,并配置对应的 HTTP URL 地址及 HTTP 方法。

  1. package io.terminus.erda.trial.demo.hellospringcloud;
  2. import org.springframework.cloud.openfeign.FeignClient;
  3. import org.springframework.web.bind.annotation.PathVariable;
  4. import org.springframework.web.bind.annotation.RequestMapping;
  5. import org.springframework.web.bind.annotation.RequestMethod;
  6. /**
  7. * @author erda
  8. */
  9. @FeignClient(name = "service-provider")
  10. public interface EchoService {
  11. @RequestMapping(value = "/echo/{str}", method = RequestMethod.GET)
  12. String echo(@PathVariable("str") String str);
  13. }

在 package: io.terminus.erda.trial.demo.hellospringcloud 中创建启动类 ConsumerApplication 并添加相关配置。使用 @EnableDiscoveryClient 注解启用服务注册与发现;使用 @EnableFeignClients 注解激活 FeignClient;添加 @LoadBalanced 注解将 RestTemplate 与服务发现集成。

  1. package io.terminus.erda.trial.demo.hellospringcloud;
  2. import org.springframework.boot.SpringApplication;
  3. import org.springframework.boot.autoconfigure.SpringBootApplication;
  4. import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
  5. import org.springframework.cloud.client.loadbalancer.LoadBalanced;
  6. import org.springframework.cloud.openfeign.EnableFeignClients;
  7. import org.springframework.context.annotation.Bean;
  8. import org.springframework.web.client.RestTemplate;
  9. /**
  10. * @author erda
  11. */
  12. @SpringBootApplication
  13. @EnableDiscoveryClient
  14. @EnableFeignClients
  15. public class ConsumerApplication {
  16. @LoadBalanced
  17. @Bean
  18. public RestTemplate restTemplate() {
  19. return new RestTemplate();
  20. }
  21. public static void main(String[] args) {
  22. SpringApplication.run(ConsumerApplication.class, args);
  23. }
  24. }
  1. 在 package: io.terminus.erda.trial.demo.hellospringcloud 中创建类 TestController 以演示和验证服务发现功能。
  1. package io.terminus.erda.trial.demo.hellospringcloud;
  2. import org.springframework.beans.factory.annotation.Autowired;
  3. import org.springframework.web.bind.annotation.PathVariable;
  4. import org.springframework.web.bind.annotation.RequestMapping;
  5. import org.springframework.web.bind.annotation.RequestMethod;
  6. import org.springframework.web.bind.annotation.RestController;
  7. import org.springframework.web.client.RestTemplate;
  8. /**
  9. * @author edas
  10. */
  11. @RestController
  12. public class TestController {
  13. @Autowired
  14. private RestTemplate restTemplate;
  15. @Autowired
  16. private EchoService echoService;
  17. @RequestMapping(value = "/echo-rest/{str}", method = RequestMethod.GET)
  18. public String rest(@PathVariable String str) {
  19. return restTemplate.getForObject("http://service-provider/echo/" + str,
  20. String.class);
  21. }
  22. @RequestMapping(value = "/echo-feign/{str}", method = RequestMethod.GET)
  23. public String feign(@PathVariable String str) {
  24. return echoService.echo(str);
  25. }
  26. }
  1. 在 src/main/resources 路径下创建文件 application.yml ,在 application.yml 中添加如下配置,指定 Nacos Server 的地址。

TIP

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

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

本地测试

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

  • Linux/Unix/Mac 系统,运行以下命令
  1. curl http://127.0.0.1:18082/echo-rest/rest-rest
  2. curl http://127.0.0.1:18082/echo-feign/feign-rest

将应用部署到 Erda

要将应用部署到 Erda,注意如下配置中的环境变量会被自动注入

  1. spring:
  2. application.name: service-provider
  3. cloud:
  4. nacos:
  5. discovery:
  6. server-addr: ${NACOS_ADDRESS:127.0.0.1:8848}
  7. namespace: ${NACOS_TENANT_ID:}
  1. spring:
  2. application.name: service-consumer
  3. cloud:
  4. nacos:
  5. discovery:
  6. server-addr: ${NACOS_ADDRESS:127.0.0.1:8848}
  7. namespace: ${NACOS_TENANT_ID:}

修改 dice.yml,添加注册中心 v2.0 的依赖:

Spring Cloud 微服务应用开发 - 图3

服务部署成功后,Erda 会自动注入两个环境变量:

  • NACOS_ADDRESS
  • NACOS_TENANT_ID

Spring Cloud 微服务应用开发 - 图4

点击注册中心,可以看到注册上来的服务