转载

Spring Cloud整合Thrift RPC(一) - 使用指南

前面几篇博客,着重对 Apache Thrift 的使用和原理做了介绍。在微服架构流行的今天,自然而然就会想到 Spring BootSpring Cloud 作为 微服务 的基础框架。然而, Spring Cloud 从诞生以来,就基于 HTTP 协议的 轻量级 Restful API 作为服务之间的通信方式。

在微服务架构设计中,可以分为 外部服务内部服务 。两者主要区别是:

  • 外部服务 :基于 Restful 风格的 HTTP 协议,通过 外网 向外部提供服务,相对来说 简单并且通用
  • 内部服务 :基于 RPC 消息通信的 TCP/IP 协议,提供 内网 服务与服务之间的调用,以达到 减少带宽降低延迟率提高性能

一些应用场景,尤其是 内部服务 需要高频地调用,就需要考虑是否需要改造为 RPC 实现,来 提高吞吐量系统性能 ,比如说 鉴权服务 一类。

正文

简述

下载 spring-cloud-starter-thrift 并导入 IDEA 开发环境,项目地址: github.com/ostenant/sp…

Spring Cloud整合Thrift RPC(一) - 使用指南
spring-cloud-starter-thrift 提供 Spring Cloud可伸缩跨语言 服务调用框架 Apache Thrift

的封装和集成。

spring-cloud-starter-thrift 包括 客户端 spring-cloud-starter-thrift-client服务端 spring-cloud-starter-thrift-server 两个模块。而 spring-cloud-starter-thrift-examples 子模块提供了 3 个示例项目: calculatordeposittest

  • calculator :简单上手项目示例。
  • deposit :复杂业务场景项目示例。
  • test :性能测试项目示例。

服务端

  1. 支持 Apache Thrift 的各种原生 线程服务模型 ,包括 单线程阻塞模型 ( simple )、 单线程非阻塞模型 ( nonBlocking )、 线程池阻塞模型 ( threadPool )、 半同步半异步模型 ( hsHa )和 线程选择器模型 ( threadedSelector )。
  2. 支持 Apache Thrift 0.10.0 版本后提供的 多路复用处理器 ,提供服务的统一注册管理功能。
  3. 支持由 服务签名 (服务 ID + 客户端 Stub 接口名称 + 服务版本号) 唯一标识服务 Stub具体实现类 ,支持服务版本的 平滑升级
  4. 支持 Server Group 形式的启动方式,每个 服务实例 可以开启多台 Thrift Server ,通过不同的 端口号 暴露给客户端。

客户端

  1. 支持由 服务签名 (服务 ID + 客户端 Stub 接口名称 + 服务版本号) 唯一标识和调用服务端的 Stub 具体实现类
  2. 支持 Apache ThriftTransport 层的 连接池管理减少 了客户端与服务端之间 连接 的频繁 创建销毁
  3. 支持与 Spring Cloud Consul无缝集成 ,客户端通过 心跳检测服务注册中心 Consul 保持连接,动态定时的 刷新服务列表监测 服务的 启用关闭健康状态
  4. 支持 客户端负载均衡 ,包括 随机轮询 的负载均衡策略,客户端的 Thrift 程序通过本地的 服务缓存列表 实现调用的动态转发。

快速上手

项目结构:

Spring Cloud整合Thrift RPC(一) - 使用指南
  • calculator
    • calculator-client
    • calculator-iface
    • calculator-server

spring-cloud-starter-thrift 使用的是 0.10.0 版本的 thrift 。以 calculator 项目入手,首先,通过 Thrift IDL (接口描述语言) 编写 客户端桩 Stub服务端骨架 Skeleton ,通过 .thrift 文件定义接口规范。

首先进入 spring-cloud-starter-thrift 根目录, pom.xml 定义如下:

pom.xml

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>1.5.8.RELEASE</version>
    <relativePath/> <!-- lookup parent from repository -->
</parent>

<modelVersion>4.0.0</modelVersion>
<groupId>com.icekredit.rpc.thrift.examples</groupId>
<version>1.0-SNAPSHOT</version>
<modules>
    <module>calculator-client</module>
    <module>calculator-server</module>
    <module>calculator-iface</module>
</modules>
<artifactId>calculator</artifactId>
<packaging>pom</packaging>

<properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
    <java.version>1.8</java.version>
    <spring-cloud.version>Dalston.SR4</spring-cloud.version>
</properties>

<build>
    <plugins>
        <plugin>
            <artifactId>maven-compiler-plugin</artifactId>
            <configuration>
                <source>1.8</source>
                <target>1.8</target>
                <encoding>UTF-8</encoding>
            </configuration>
        </plugin>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-jar-plugin</artifactId>
            <version>2.6</version>
        </plugin>
    </plugins>
</build>

将项目打包并 安装 到本地 Maven 仓库:

mvn clean install

Thrift IDL编写

namespace java com.icekredit.rpc.thrift.example
service CalculatorService {
    i32 add(1: i32 arg1, 2: i32 arg2)
    i32 subtract(1: i32 arg1, 2: i32 arg2)
    i32 multiply(1: i32 arg1, 2: i32 arg2)
    i32 division(1: i32 arg1, 2: i32 arg2)
}

下载并安装 0.10.0Thrift IDL 编译生成器 ,下载地址: thrift.apache.org/docs/instal… 。通过 编译器 生成 .javaStub 类文件。

thrift -gen java ./CalculatorService.thrift

编译器生成的 CalculatorService.java 文件。 CalculatorService.java 有成千上万行代码。对于开发人员而言,只需要关注以下 四个核心接口/类IfaceAsyncIfaceClientAsyncClient

  • Iface服务端 通过实现 HelloWorldService.Iface 接口,向 客户端 的提供具体的 同步 业务逻辑。
  • AsyncIface服务端 通过实现 HelloWorldService.Iface 接口,向 客户端 的提供具体的 异步 业务逻辑。
  • Client客户端 通过 HelloWorldService.Client 的实例对象,以 同步 的方式 访问服务端 提供的服务方法。
  • AsyncClient客户端 通过 HelloWorldService.AsyncClient 的实例对象,以 异步 的方式 访问服务端 提供的服务方法。

中间契约(calculator-iface)

中间契约模块 引入 thriftmaven 依赖,拷贝上一步 thrift 编译生成器生成的 CalculatorService 源文件到此模块。

pom.xml

<parent>
    <artifactId>calculator</artifactId>
    <groupId>com.icekredit.rpc.thrift.examples</groupId>
    <version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>calculator-iface</artifactId>

<dependencies>
    <dependency>
        <groupId>org.apache.thrift</groupId>
        <artifactId>libthrift</artifactId>
        <version>0.10.0</version>
    </dependency>
</dependencies>

服务端(calculator-server)

在服务端模块引入:

  • spring-cloud-starter-thrift-serverthrift 服务端的 starter 程序。
  • calculator-iface :中间契约模块,这里作为服务端骨架( Skeleton )程序。

pom.xml

<parent>
    <artifactId>calculator</artifactId>
    <groupId>com.icekredit.rpc.thrift.examples</groupId>
    <version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>calculator-server</artifactId>
<packaging>jar</packaging>

<dependencies>
    <dependency>
        <groupId>com.icekredit.rpc.thrift</groupId>
        <artifactId>spring-cloud-starter-thrift-server</artifactId>
        <version>1.0-SNAPSHOT</version>
    </dependency>
    <dependency>
        <groupId>com.icekredit.rpc.thrift.examples</groupId>
        <artifactId>calculator-iface</artifactId>
        <version>1.0-SNAPSHOT</version>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
</dependencies>

<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>
    </plugins>
</build>

application.yml 中配置 thrift 服务端的运行参数:

application.yml

## 服务端Restful服务所在的HTTP端口号
server:
  port: 8080

## 用于Consul健康检查
endpoints:
  actuator:
    sensitive: false
    enabled: true
management:
  security:
    enabled: false

## Spring Thrift服务端配置
spring:
  thrift:
    server:
      service-id: thrift-rpc-calculator ##
      service-model: hsHa  ## 半同步/半异步服务模型
      port: 25000  ## 服务端RPC服务所在的TCP端口号
      worker-queue-capacity: 1000
      ## 半同步/半异步服务模型参数配置
      hs-ha:
        min-worker-threads: 5  ## 最少工作线程数
        max-worker-threads: 20  ## 最大工作线程数
        keep-alived-time: 3  ## 空闲线程存活时间

实现 Thrift IDL 生成的骨架( Skeleton )类 CalculatorService 的内部接口 Iface ,编写具体的业务逻辑:

这里需要注意几点:

  • 实现 CalculatorService.Iface 接口。
  • 实现类标记 @ThriftService 注解,包含以下属性:
    • name :通过 name 标识 服务名称 ,缺省时默认为 类名称首字母小写
    • version :通过 version 标识 服务版本 ,缺省值为 1.0 ,也就是说同一个 服务名称 可以拥有 多个版本实现

RpcCalculatorService.java

@ThriftService(name = "rpcCalculatorService", version = 2.0)
public class RpcCalculatorService implements CalculatorService.Iface {
    @Override
    public int add(int arg1, int arg2) {
        BigDecimal arg1Decimal = new BigDecimal(arg1);
        BigDecimal arg2Decimal = new BigDecimal(arg2);
        return arg1Decimal.add(arg2Decimal).intValue();
    }

    @Override
    public int subtract(int arg1, int arg2) {
        BigDecimal arg1Decimal = new BigDecimal(arg1);
        BigDecimal arg2Decimal = new BigDecimal(arg2);
        return arg1Decimal.subtract(arg2Decimal).intValue();
    }

    @Override
    public int multiply(int arg1, int arg2) {
        BigDecimal arg1Decimal = new BigDecimal(arg1);
        BigDecimal arg2Decimal = new BigDecimal(arg2);
        return arg1Decimal.multiply(arg2Decimal).intValue();
    }

    @Override
    public int division(int arg1, int arg2) {
        BigDecimal arg1Decimal = new BigDecimal(arg1);
        BigDecimal arg2Decimal = new BigDecimal(arg2);
        return arg1Decimal.divide(arg2Decimal).intValue();
    }
}

对服务端程序进行打包:

mvn clean package -Dmaven.test.skip=true

编写 Dockerfile 文件:

FROM openjdk:8-jdk-alpine
ADD target/spring-boot-thrift-server-0.0.1-SNAPSHOT.jar calculator-server.jar
ENTRYPOINT ["java", "-jar", "calculator-server.jar"]

Dockerfiletarget/spring-boot-thrift-server-0.0.1-SNAPSHOT.jar 拷贝到服务器上,构建 Thrift Server 的服务镜像:

docker build . -t icekredit/calculator-server

客户端(calculator-client)

在客户端模块引入:

  • spring-cloud-starter-thrift-clientthrift 客户端的 starter 程序。
  • calculator-iface :中间契约模块,这里作为客户端桩( Stub )程序。

pom.xml

<parent>
    <artifactId>calculator</artifactId>
    <groupId>com.icekredit.rpc.thrift.examples</groupId>
    <version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>calculator-client</artifactId>

<dependencies>
    <dependency>
        <groupId>com.icekredit.rpc.thrift</groupId>
        <artifactId>spring-cloud-starter-thrift-client</artifactId>
        <version>1.0-SNAPSHOT</version>
    </dependency>
    <dependency>
        <groupId>com.icekredit.rpc.thrift.examples</groupId>
        <artifactId>calculator-iface</artifactId>
        <version>1.0-SNAPSHOT</version>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-consul-discovery</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-feign</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-ribbon</artifactId>
    </dependency>
</dependencies>

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-dependencies</artifactId>
            <version>${spring-cloud.version}</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>

application.yml 中配置 thrift 客户端 的运行参数,需要与 服务端 配置保持一致:

## 客户端Restful服务所在的HTTP端口号
server:
  port: 8080

## 用于Consul健康检查
endpoints:
  actuator:
    sensitive: false
    enabled: true
management:
  security:
    enabled: false

## Spring Thrift客户端配置(Thrift Client的自动配置取决于Spring Cloud Consul的正确配置)
spring:
  application:
    name: thrift-calculator-client
  cloud:
    consul:
      host: 192.168.91.128  ## Consul的IP地址
      port: 8500  ## Consul的HTTP端口号
      discovery:
        register: false  ## 不使用SpringCloud提供的基于服务的程序注册方式
        register-health-check: false  ## 不使用Spring Cloud进行健康检查
      retry:
        max-attempts: 3
        max-interval: 2000
  ## Thrift Client配置
  thrift:
    client:
      package-to-scan: com.icekredit.rpc.thrift.example.rpc  ## 标记由有注解@ThriftClient接口的包路径
      service-model: hsHa  ##服务线程模型(这里必须与服务端保持一致, 默认都是hsHa)
      ## 客户端连接池配置
      pool:
        retry-times: 3  ## 异常失败,连接超时后的重试次数
        ## key由IP + Port组成,唯一标识一个服务实例
        pool-max-total-per-key: 200 ## 客户端保持的最大连接数,包含不同的服务和服务实例
        pool-min-idle-per-key: 10  ## 每个服务实例最小的空闲连接数
        pool-max-idle-per-key: 40  ## 每个服务实例最大的空闲连接数
        pool-max-wait: 30000  ## 空闲连接最大存活时间
        connect-timeout: 2000  ## 连接超时时间

编写 Thrift Client客户端代理接口 ,这里有两点注意事项:

  • 接口需要继承于 父接口 ThriftClientAware ,且 ThriftClientAware 里的 泛型参数 填写为 Thrift IDL 生成的 StubCalculatorService 中的 Client 内部类。
  • 接口需要标识 @ThriftClient 注解, @ThriftClient 包含如下属性:
    • serviceId :此客户端代理接口绑定的 Thrift 服务端服务注册ID (与服务端 保持一致 )。
    • refer :客户端桩 Stub 的类型,例如这里是 CalculatorService.class
    • version :具体业务实现类的 版本号 (不填写默认为 1.0 ),需要与服务端 保持一致

CalculatorThriftClient.java

@ThriftClient(serviceId = "thrift-rpc-calculator", refer = CalculatorService.class, version = 2.0)
public interface CalculatorThriftClient extends ThriftClientAware<CalculatorService.Client> {
}

使用注解 @ThriftReferer ,在客户端的 Controller 中注入 CalculatorThriftClient 。 使用时,通过 CalculatorThriftClient.thriftClient() 方法,即可调用 Thrift Server 的服务方法。

RpcCalculatorController.java

@RestController
@RequestMapping("/rpc")
public class RpcCalculatorController {
    @ThriftReferer
    private CalculatorThriftClient calculators;

    @GetMapping("/add")
    public int add(@RequestParam("arg1") int arg1, @RequestParam("arg2") int arg2) throws Exception {
        return calculators.client().add(arg1, arg2);
    }

    @GetMapping("/subtract")
    public int subtract(@RequestParam("arg1") int arg1, @RequestParam("arg2") int arg2) throws Exception {
        return calculators.client().subtract(arg1, arg2);
    }

    @GetMapping("/multiply")
    public int multiply(@RequestParam("arg1") int arg1, @RequestParam("arg2") int arg2) throws Exception {
        return calculators.client().multiply(arg1, arg2);
    }

    @GetMapping("/division")
    public int division(@RequestParam("arg1") int arg1, @RequestParam("arg2") int arg2) throws Exception {
        return calculators.client().division(arg1, arg2);
    }
}

测试方便,在 本地开发环境 配置 Consul 的地址,运行 客户端程序 即可。对于 容器环境 测试,配置对客户端程序进行打包:

mvn clean package -Dmaven.test.skip=true

编写 Dockerfile 文件:

FROM openjdk:8-jdk-alpine
ADD target/spring-boot-thrift-client-0.0.1-SNAPSHOT.jar calculator-client.jar
ENTRYPOINT ["java", "-jar", "calculator-client.jar"]

Dockerfiletarget/spring-boot-thrift-client-0.0.1-SNAPSHOT.jar 拷贝到服务器上,构建 Thrift Client 的服务镜像:

docker build . -t icekredit/calculator-client

简单测试

发布服务端程序

为了方便测试,在一台主机上启动三个 Thrift Serverdocker 容器,以不同的 端口 区分,分别指定对应的 端口号Consul 注册信息:

Thrift Server 实例1( 25001 端口):

docker run -d -p 8081:8080 -p 25001:25000 --name calculator-server-01 /
    -e "SERVICE_25000_NAME=thrift-rpc-calculator" /
	  -e "SERVICE_25000_CHECK_TCP=/" /
	  -e "SERVICE_25000_CHECK_INTERVAL=30s" /
	  -e "SERVICE_25000_CHECK_TIMEOUT=3s" /
	  -e "SERVICE_25000_TAGS=thrift-rpc-calculator-25001" /
	  icekredit/calculator-server

Thrift Server 实例2( 25002 端口):

docker run -d -p 8081:8080 -p 25002:25000 --name calculator-server-01 /
    -e "SERVICE_25000_NAME=thrift-rpc-calculator" /
	  -e "SERVICE_25000_CHECK_TCP=/" /
	  -e "SERVICE_25000_CHECK_INTERVAL=30s" /
	  -e "SERVICE_25000_CHECK_TIMEOUT=3s" /
	  -e "SERVICE_25000_TAGS=thrift-rpc-calculator-25002" /
	  icekredit/calculator-server

Thrift Server 实例3( 25003 端口):

docker run -d -p 8081:8080 -p 25003:25000 --name calculator-server-01 /
    -e "SERVICE_25000_NAME=thrift-rpc-calculator" /
	  -e "SERVICE_25000_CHECK_TCP=/" /
	  -e "SERVICE_25000_CHECK_INTERVAL=30s" /
	  -e "SERVICE_25000_CHECK_TIMEOUT=3s" /
	  -e "SERVICE_25000_TAGS=thrift-rpc-calculator-25003" /
	    icekredit/calculator-server

观察各个容器的启动日志,如果包含以下 几行输出信息 ,则表明 Thrift Server 成功启动并正常提供 RPC 服务。

2017-11-19 22:28:47.779  INFO 12960 --- [           main] c.i.r.t.s.context.ThriftServerContext    : Build thrift server from HsHaServerContext
2017-11-19 22:28:47.820  INFO 12960 --- [           main] c.i.r.t.s.p.TRegisterProcessorFactory    : Processor bean org.ostenant.springboot.learning.examples.CalculatorService$Processor@445bce9a with signature [thrift-rpc-calculator$org.ostenant.springboot.learning.examples.CalculatorService$2.0] is instantiated
2017-11-19 22:28:47.822  INFO 12960 --- [           main] c.i.r.t.s.p.TRegisterProcessorFactory    : Single processor org.ostenant.springboot.learning.examples.CalculatorService$Processor@445bce9a register onto multiplexed processor with signature [thrift-rpc-calculator$org.ostenant.springboot.learning.examples.CalculatorService$2.0]
2017-11-19 22:28:47.822  INFO 12960 --- [           main] c.i.r.t.s.p.TRegisterProcessorFactory    : Multiplexed processor totally owns 1 service processors

启动 ConsulRegistrator 容器, Thrift Server 的三个服务实例成功注册到 Consul 服务列表:

Spring Cloud整合Thrift RPC(一) - 使用指南

有关 ConsulRegistrator 的安装配置以及使用,请参考: Docker+Consul+Registrator(一) 搭建服务发现与注册集群

服务端程序成功运行, Thrift RPC 服务正常发布!

启动客户端程序

在本地 8080 端口号启动 Thrift 客户端,正常启动后观察启动日志如下:

2017-11-20 11:00:20.025  INFO 4052 --- [           main] .r.t.c.ThriftClientBeanScannerConfigurer : Base package org.ostenant.springboot.learning.examples.rpc is to be scanned with com.icekredit.rpc.thrift.client.scanner.ThriftClientBeanScanner@37496720
2017-11-20 11:00:20.029  INFO 4052 --- [           main] c.i.r.t.c.s.ThriftClientBeanScanner      : Packages scanned by thriftClientBeanDefinitionScanner is [org.ostenant.springboot.learning.examples.rpc]
2017-11-20 11:00:20.029  INFO 4052 --- [           main] c.i.r.t.c.s.ThriftClientBeanScanner      : Scanned and found thrift client, bean calculatorThriftClient assigned from org.ostenant.springboot.learning.examples.rpc.CalculatorThriftClient
2017-11-20 11:00:20.050  INFO 4052 --- [           main] f.a.AutowiredAnnotationBeanPostProcessor : JSR-330 'javax.inject.Inject' annotation found and supported for autowiring
2017-11-20 11:00:20.134  INFO 4052 --- [           main] trationDelegate$BeanPostProcessorChecker : Bean 'org.ostenant.springboot.learning.examples.rest.CalculatorFeignClient' of type [org.springframework.cloud.netflix.feign.FeignClientFactoryBean] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2017-11-20 11:00:20.136  WARN 4052 --- [           main] c.i.r.t.c.s.ThriftClientFactoryBean      : Bean class is not found
2017-11-20 11:00:20.142  INFO 4052 --- [           main] c.i.r.t.c.s.ThriftClientFactoryBean      : Succeed to instantiate an instance of ThriftClientFactoryBean: com.icekredit.rpc.thrift.client.scanner.ThriftClientFactoryBean@7bac686b
2017-11-20 11:00:20.142  INFO 4052 --- [           main] trationDelegate$BeanPostProcessorChecker : Bean 'calculatorThriftClient' of type [com.icekredit.rpc.thrift.client.scanner.ThriftClientFactoryBean] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2017-11-20 11:00:20.411  INFO 4052 --- [           main] trationDelegate$BeanPostProcessorChecker : Bean 'org.springframework.cloud.netflix.metrics.MetricsInterceptorConfiguration$MetricsRestTemplateConfiguration' of type [org.springframework.cloud.netflix.metrics.MetricsInterceptorConfiguration$MetricsRestTemplateConfiguration$$EnhancerBySpringCGLIB$$a9ef18dc] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2017-11-20 11:00:20.423  INFO 4052 --- [           main] trationDelegate$BeanPostProcessorChecker : Bean 'org.springframework.cloud.autoconfigure.ConfigurationPropertiesRebinderAutoConfiguration' of type [org.springframework.cloud.autoconfigure.ConfigurationPropertiesRebinderAutoConfiguration$$EnhancerBySpringCGLIB$$93dc7598] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2017-11-20 11:00:21.592  INFO 4052 --- [           main] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat initialized with port(s): 8080 (http)

启动过程中,所有的标记有注解 @ThriftClient 的接口都生成了 代理对象 ,并通过注解 @ThriftReferer 注入到 Controller 中。

同时, 客户端 启动时开启了一个 ServerUpdater定时动态 的去 Consul 服务注册列表抓取 健康的服务节点信息 ,缓存到 本地服务列表 中。

2017-11-20 11:02:26.726  INFO 4052 --- [erListUpdater-0] t.c.l.ThriftConsulServerListLoadBalancer : Refreshed thrift serverList: [thrift-rpc-calculator: [ThriftServerNode{node='node1', serviceId='thrift-rpc-calculator', tags=[thrift-rpc-calculator-25001], host='192.168.91.128', port=25001, address='192.168.91.128', isHealth=true}, ThriftServerNode{node='node1', serviceId='thrift-rpc-calculator', tags=[thrift-rpc-calculator-25002], host='192.168.91.128', port=25002, address='192.168.91.128', isHealth=true}, ThriftServerNode{node='node1', serviceId='thrift-rpc-calculator', tags=[thrift-rpc-calculator-25003], host='192.168.91.128', port=25003, address='192.168.91.128', isHealth=true}], consul-8301: [ThriftServerNode{node='node1', serviceId='consul-8301', tags=[udp], host='192.168.91.128', port=8301, address='192.168.91.128', isHealth=true}, ThriftServerNode{node='node1', serviceId='consul-8301', tags=[udp], host='192.168.91.128', port=9301, address='192.168.91.128', isHealth=true}, ThriftServerNode{node='node1', serviceId='consul-8301', tags=[udp], host='192.168.91.128', port=10301, address='192.168.91.128', isHealth=true}], consul-8302: [ThriftServerNode{node='node1', serviceId='consul-8302', tags=[udp], host='192.168.91.128', port=8302, address='192.168.91.128', isHealth=true}, ThriftServerNode{node='node1', serviceId='consul-8302', tags=[udp], host='192.168.91.128', port=9302, address='192.168.91.128', isHealth=true}, ThriftServerNode{node='node1', serviceId='consul-8302', tags=[udp], host='192.168.91.128', port=10302, address='192.168.91.128', isHealth=true}], thrift-rest-calculator: [ThriftServerNode{node='node1', serviceId='thrift-rest-calculator', tags=[thrift-rest-calculator-8081], host='192.168.91.128', port=8081, address='192.168.91.128', isHealth=true}, ThriftServerNode{node='node1', serviceId='thrift-rest-calculator', tags=[thrift-rest-calculator-8082], host='192.168.91.128', port=8082, address='192.168.91.128', isHealth=true}, ThriftServerNode{node='node1', serviceId='thrift-rest-calculator', tags=[thrift-rest-calculator-8083], host='192.168.91.128', port=8083, address='192.168.91.128', isHealth=true}]]
2017-11-20 11:02:56.752  INFO 4052 --- [erListUpdater-0] t.c.l.ThriftConsulServerListLoadBalancer : Refreshed thrift serverList: [thrift-rpc-calculator: [ThriftServerNode{node='node1', serviceId='thrift-rpc-calculator', tags=[thrift-rpc-calculator-25001], host='192.168.91.128', port=25001, address='192.168.91.128', isHealth=true}, ThriftServerNode{node='node1', serviceId='thrift-rpc-calculator', tags=[thrift-rpc-calculator-25002], host='192.168.91.128', port=25002, address='192.168.91.128', isHealth=true}, ThriftServerNode{node='node1', serviceId='thrift-rpc-calculator', tags=[thrift-rpc-calculator-25003], host='192.168.91.128', port=25003, address='192.168.91.128', isHealth=true}], consul-8301: [ThriftServerNode{node='node1', serviceId='consul-8301', tags=[udp], host='192.168.91.128', port=8301, address='192.168.91.128', isHealth=true}, ThriftServerNode{node='node1', serviceId='consul-8301', tags=[udp], host='192.168.91.128', port=9301, address='192.168.91.128', isHealth=true}, ThriftServerNode{node='node1', serviceId='consul-8301', tags=[udp], host='192.168.91.128', port=10301, address='192.168.91.128', isHealth=true}], consul-8302: [ThriftServerNode{node='node1', serviceId='consul-8302', tags=[udp], host='192.168.91.128', port=8302, address='192.168.91.128', isHealth=true}, ThriftServerNode{node='node1', serviceId='consul-8302', tags=[udp], host='192.168.91.128', port=9302, address='192.168.91.128', isHealth=true}, ThriftServerNode{node='node1', serviceId='consul-8302', tags=[udp], host='192.168.91.128', port=10302, address='192.168.91.128', isHealth=true}], thrift-rest-calculator: [ThriftServerNode{node='node1', serviceId='thrift-rest-calculator', tags=[thrift-rest-calculator-8081], host='192.168.91.128', port=8081, address='192.168.91.128', isHealth=true}, ThriftServerNode{node='node1', serviceId='thrift-rest-calculator', tags=[thrift-rest-calculator-8082], host='192.168.91.128', port=8082, address='192.168.91.128', isHealth=true}, ThriftServerNode{node='node1', serviceId='thrift-rest-calculator', tags=[thrift-rest-calculator-8083], host='192.168.91.128', port=8083, address='192.168.91.128', isHealth=true}]]
2017-11-20 11:03:26.764  INFO 4052 --- [erListUpdater-0] t.c.l.ThriftConsulServerListLoadBalancer : Refreshed thrift serverList: [thrift-rpc-calculator: [ThriftServerNode{node='node1', serviceId='thrift-rpc-calculator', tags=[thrift-rpc-calculator-25001], host='192.168.91.128', port=25001, address='192.168.91.128', isHealth=true}, ThriftServerNode{node='node1', serviceId='thrift-rpc-calculator', tags=[thrift-rpc-calculator-25002], host='192.168.91.128', port=25002, address='192.168.91.128', isHealth=true}, ThriftServerNode{node='node1', serviceId='thrift-rpc-calculator', tags=[thrift-rpc-calculator-25003], host='192.168.91.128', port=25003, address='192.168.91.128', isHealth=true}], consul-8301: [ThriftServerNode{node='node1', serviceId='consul-8301', tags=[udp], host='192.168.91.128', port=8301, address='192.168.91.128', isHealth=true}, ThriftServerNode{node='node1', serviceId='consul-8301', tags=[udp], host='192.168.91.128', port=9301, address='192.168.91.128', isHealth=true}, ThriftServerNode{node='node1', serviceId='consul-8301', tags=[udp], host='192.168.91.128', port=10301, address='192.168.91.128', isHealth=true}], consul-8302: [ThriftServerNode{node='node1', serviceId='consul-8302', tags=[udp], host='192.168.91.128', port=8302, address='192.168.91.128', isHealth=true}, ThriftServerNode{node='node1', serviceId='consul-8302', tags=[udp], host='192.168.91.128', port=9302, address='192.168.91.128', isHealth=true}, ThriftServerNode{node='node1', serviceId='consul-8302', tags=[udp], host='192.168.91.128', port=10302, address='192.168.91.128', isHealth=true}], thrift-rest-calculator: [ThriftServerNode{node='node1', serviceId='thrift-rest-calculator', tags=[thrift-rest-calculator-8081], host='192.168.91.128', port=8081, address='192.168.91.128', isHealth=true}, ThriftServerNode{node='node1', serviceId='thrift-rest-calculator', tags=[thrift-rest-calculator-8082], host='192.168.91.128', port=8082, address='192.168.91.128', isHealth=true}, ThriftServerNode{node='node1', serviceId='thrift-rest-calculator', tags=[thrift-rest-calculator-8083], host='192.168.91.128', port=8083, address='192.168.91.128', isHealth=true}]]

访问本地 Thrift 客户端:

访问地址 参数arg1 参数arg2 页面输出结果
/rpc/add 200 100 300
/rpc/subtract 200 100 100
/rpc/multiply 200 100 20000
/rpc/division 200 100 2
原文  https://juejin.im/post/5b2a6a316fb9a00e6a620d4f
正文到此结束
Loading...