服务注册与发现

最近更新时间:2019-08-14 12:16:35

准备工作

开始实践服务注册发现功能前,请确保已完成了 SDK 下载

实现服务注册和发现

通过一个简单的示例说明如何实践服务的注册和发现。创建 tsf-demo 工程,文件结构如下:

|- consumer-demo
|- provider-demo
|- pom.xml

其中pom.xml文件参考 Demo 工程概述 中的pom.xml内容。

创建服务提供者

此服务提供者提供一个简单的 echo 服务,并将自身注册到服务注册中心。

1. 创建 provider 工程

创建一个 Spring Cloud 工程,命名为provider-demo

2. 修改 pom 依赖

pom.xml中引入需要的依赖内容:

<parent>
    <groupId>com.tencent.tsf</groupId>
    <artifactId>tsf-demo</artifactId>
    <version><!-- 关联 parent version 属性--></version>
</parent>

<artifactId>provider-demo</artifactId>
<packaging>jar</packaging>
<name>provider-demo</name>

<dependencies>
    <dependency>
        <groupId>com.tencent.tsf</groupId>
        <artifactId>spring-cloud-tsf-consul-discovery</artifactId>
    </dependency>
    <dependency>
        <groupId>com.tencent.tsf</groupId>
        <artifactId>spring-cloud-tsf-consul-config</artifactId>
    </dependency>
    <!-- 使用分布式配置自动刷新功能,需要显示添加actuator的依赖包 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>
    <dependency>
        <groupId>com.tencent.tsf</groupId>
        <artifactId>spring-cloud-tsf-sleuth</artifactId>
    </dependency>
    <dependency>
        <groupId>com.tencent.tsf</groupId>
        <artifactId>spring-cloud-tsf-auth</artifactId>
    </dependency>
    <dependency>
        <groupId>com.tencent.tsf</groupId>
        <artifactId>spring-cloud-tsf-route</artifactId>
    </dependency>
    <dependency>
        <groupId>com.tencent.tsf</groupId>
        <artifactId>spring-cloud-tsf-swagger</artifactId>
    </dependency>
    <dependency>
        <groupId>com.tencent.tsf</groupId>
        <artifactId>spring-cloud-tsf-ratelimit</artifactId>
    </dependency>
    <dependency>
        <groupId>com.tencent.tsf</groupId>
        <artifactId>spring-cloud-tsf-encrypt</artifactId>
    </dependency>
    <!-- Finchley 版本 SDK 无须添加 monitor 依赖包 
    <dependency>
        <groupId>com.tencent.tsf</groupId>
        <artifactId>spring-cloud-tsf-monitor</artifactId>
    </dependency>
    -->
</dependencies>
注意:

Finchley 版本 SDK 无须添加 monitor 依赖包,具体请参考 服务监控

3. 开启服务注册发现

添加服务提供端的代码,其中@EnableDiscoveryClient注解表明此应用需开启服务注册与发现功能。

import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.netflix.feign.EnableFeignClients;

@SpringBootApplication
@EnableDiscoveryClient
 public class ProviderApplication {
     public static void main(String[] args) {
         SpringApplication.run(ProviderApplication.class, args);
     }
 }

4. 提供 echo 服务

创建一个EchoController,提供简单的echo服务。

 @RestController
 public class EchoController {
     @RequestMapping(value = "/echo/{string}", method = RequestMethod.GET)
     public String echo(@PathVariable String string) {
         return string;
     }
 }

5. 修改配置

resource目录下的application.yml文件中配置应用名与监听端口号。

server:
  port: 18081
spring:
  application:
    name: provider-demo
注意:

运行在 TSF 平台上的应用无须配置服务注册中心地址,SDK 会通过环境变量自动获取注册中心地址。

创建服务消费者

本示例中,我们将创建一个服务消费者,消费者通过RestTemplateAsyncRestTemplateFeignClient这三个客户端去调用服务提供者。

1. 创建 consumer 工程

创建一个 Spring Cloud 工程,命名为consumer-demo

2. 修改 pom 依赖

pom.xml中引入需要的依赖内容:

<parent>
        <groupId>com.tencent.tsf</groupId>
        <artifactId>tsf-demo</artifactId>
        <version>1.12.1-Edgware-RELEASE</version>
</parent>

<artifactId>consumer-demo</artifactId>
<packaging>jar</packaging>
<name>consumer-demo</name>

<dependencies>
    <dependency>
        <groupId>com.tencent.tsf</groupId>
        <artifactId>spring-cloud-tsf-consul-discovery</artifactId>
    </dependency>
    <dependency>
        <groupId>com.tencent.tsf</groupId>
        <artifactId>spring-cloud-tsf-consul-config</artifactId>
    </dependency>
    <!-- 使用分布式配置自动刷新功能,需要显示添加actuator的依赖包 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-feign</artifactId>
    </dependency>
    <dependency>
        <groupId>com.tencent.tsf</groupId>
        <artifactId>spring-cloud-tsf-sleuth</artifactId>
    </dependency>
    <dependency>
        <groupId>com.tencent.tsf</groupId>
        <artifactId>spring-cloud-tsf-auth</artifactId>
    </dependency>
    <dependency>
        <groupId>com.tencent.tsf</groupId>
        <artifactId>spring-cloud-tsf-route</artifactId>
    </dependency>
    <dependency>
        <groupId>com.tencent.tsf</groupId>
        <artifactId>spring-cloud-tsf-swagger</artifactId>
    </dependency>
    <dependency>
        <groupId>com.tencent.tsf</groupId>
        <artifactId>spring-cloud-tsf-ratelimit</artifactId>
    </dependency>
    <dependency>
        <groupId>com.tencent.tsf</groupId>
        <artifactId>spring-cloud-tsf-encrypt</artifactId>
    </dependency>
    <!-- Finchley 版本 SDK 无须添加 monitor 依赖包 
    <dependency>
        <groupId>com.tencent.tsf</groupId>
        <artifactId>spring-cloud-tsf-monitor</artifactId>
    </dependency>
    -->
</dependencies>

因为此处需要演示FeignClient的使用,所以与provider-demo相比,pom.xml文件中的依赖增加了一个spring-cloud-starter-feign

3. 开启服务注册发现

与服务提供者provider-demo相比,除了开启服务与注册外,还需要添加两项配置才能使用RestTemplateAsyncRestTemplateFeignClient这三个客户端:

  • 添加@LoadBalanced注解将RestTemplateAsyncRestTemplate与服务发现结合。
  • 使用@EnableFeignClients注解激活FeignClients
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.netflix.feign.EnableFeignClients;

@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients
public class ConsumerApplication {
   @LoadBalanced
   @Bean
   public RestTemplate restTemplate() {
       return new RestTemplate();
   }

   @LoadBalanced
   @Bean
   public AsyncRestTemplate asyncRestTemplate(){
       return new AsyncRestTemplate();
   }

   public static void main(String[] args) {
       SpringApplication.run(ConsumerApplication.class, args);
   }
}

4. 设置调用信息

在使用EchoServiceFeignClient之前,还需要完善它的配置。配置服务名以及方法对应的 HTTP 请求,服务名为provider-demo工程中配置的服务名provider-demo,代码如下:

 @FeignClient(name = "provider-demo")
 public interface EchoService {
     @RequestMapping(value = "/echo/{str}", method = RequestMethod.GET)
     String echo(@PathVariable("str") String str);
 }

5. 创建 Controller

创建一个Controller供调用测试。

  • /echo-rest/*验证通过 RestTemplate 去调用服务提供者。
  • /echo-async-rest/*验证通过 AsyncRestTemplate 去调用服务提供者。
  • /echo-feign/*验证通过 FeignClient 去调用服务提供者。
@RestController
public class Controller {
   @Autowired
   private RestTemplate restTemplate;
   @Autowired
   private AsyncRestTemplate asyncRestTemplate;
   @Autowired
   private  EchoService echoService;
   @RequestMapping(value = "/echo-rest/{str}", method = RequestMethod.GET)
   public String rest(@PathVariable String str) {
       return restTemplate.getForObject("http://provider-demo/echo/" + str, String.class);
   }
   @RequestMapping(value = "/echo-async-rest/{str}", method = RequestMethod.GET)
   public String asyncRest(@PathVariable String str) throws Exception{
       ListenableFuture<ResponseEntity<String>> future = asyncRestTemplate.
               getForEntity("http://provider-demo/echo/"+str, String.class);
       return future.get().getBody();
   }
   @RequestMapping(value = "/echo-feign/{str}", method = RequestMethod.GET)
   public String feign(@PathVariable String str) {
       return echoService.echo(str);
   }
}

6. 修改配置

server:
  port: 18083
spring:
  application:
    name: consumer-demo
注意:

运行在 TSF 平台上的应用无须配置服务注册中心地址,SDK 会通过环境变量自动获取注册中心地址。

本地开发调试

启动轻量级注册中心

本地开发调试时,需要使用轻量级注册中心,轻量级注册中心包含了 TSF 服务注册发现服务端的轻量版,详请参见 轻量级服务注册中心

启动应用

本地启动应用可以通过 IDE 和 FatJar 两种方式。

IDE 中启动

在 IDE 中启动,通过 VM options 配置启动参数-Dtsf_consul_ip=127.0.0.1 -Dtsf_consul_port=8500 -Dtsf_application_id=a -Dtsf_group_id=b -Dtsf.swagger.enabled=false,通过 main 方法直接启动。其中 IP 和 port 取值为轻量级服务注册中心的地址,使用了分布式配置功能的模块,需要设置-Dtsf_application_id=a -Dtsf_group_id=b, 取值可为任意值。

FatJar 启动

1. 添加 FatJar 打包方式
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
2. 打包 FatJar 文件

添加完插件后,在工程的主目录下,使用 Maven 命令mvn clean package进行打包,及可在 target 目录下找到打包好的 FatJar 文件。

3. 通过 Java 命令启动
java -Dtsf_consul_ip=127.0.0.1 -Dtsf_consul_port=8500 -Dtsf.swagger.enabled=false -jar provider-demo-0.0.1-SNAPSHOT.jar

其中127.0.0.1和8500为轻量级服务注册中心地址,在本地调试时 tsf_application_id 和 tsf_group_id 可以填任意值。

注意:

由于轻量级服务注册中心(原生的 consul)的 metadata 只能支持512个字节,因此需要关闭 TSF 的 API 上报能力 -Dtsf.swagger.enabled=false,如果没有这个启动参数,在本地运行 Demo 时将会报错,错误信息中包含Value is too long (limit 512 characters)

演示

启动服务,分别进行调用,观察调用结果。

http://{consumer-demo-ip}:{consumer-demo-port}/echo-rest/test?user=test-tsf

http://{consumer-demo-ip}:{consumer-demo-port}/echo-async-rest/test?user=test-tsf

http://{consumer-demo-ip}:{consumer-demo-port}/test?user=test-tsf

TSF 中部署应用

将打包好的 FatJar 程序包上传到 TSF 控制台,进行部署操作,无需关心额外配置。部署相关操作可参考 虚拟机应用部署组容器应用部署组

从 Eureka 迁移

已经接入 Eureka 服务注册与发现的应用,只需要修改pom.xml依赖,就可以将服务接入 TSF 服务注册发现中心。

  1. 在工程根目录的 pom.xml 中增加spring-cloud-tsf-dependencies的 parent。参考上文中的 Demo 工程。

  2. 在单个 Spring Cloud 应用的pom.xml中,将spring-cloud-starter-eureka替换成spring-cloud-starter-consul-discovery
    替换前:

    <dependency>
      <groupId>org.springframework.cloud</groupId>
      <artifactId>spring-cloud-starter-eureka</artifactId>
    </dependency>

    替换后:

    <dependency>
     <groupId>com.tencent.tsf</groupId>
     <artifactId>spring-cloud-tsf-consul-discovery</artifactId>
    </dependency>
    <!-- consul SDK 依赖的版本控制参考 Demo 或之前 pom 说明-->
  3. 修改代码中的 Eureka 的相关注解。

    @EnableEurekaClient   => @EnableDiscoveryClient

异常检查

通过 TSF 平台部署改造后的应用,发现应用无法启动,可以在工程中检查 spring-cloud-starter-consul-discovery 的版本,如果发现版本号中没有 TSF-RELEASE ,说明没有正确依赖 TSF 相关依赖,可参考 Demo 工程中 pom.xml 文件。