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

零壹技術棧發表於2018-06-20

前言

前面幾篇部落格,著重對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

總結

本文簡單地介紹瞭如何利用 starterApache Thrift 整合進入 Spring Cloud 中,關於更復雜的應用場景和starter內部的設計、實現原理,後續會一步步的給出具體的介紹!


歡迎關注技術公眾號: 零壹技術棧

零壹技術棧

本帳號將持續分享後端技術乾貨,包括虛擬機器基礎,多執行緒程式設計,高效能框架,非同步、快取和訊息中介軟體,分散式和微服務,架構學習和進階等學習資料和文章。

相關文章