前言
前面幾篇部落格,著重對Apache Thrift
的使用和原理做了介紹。在微服架構流行的今天,自然而然就會想到Spring Boot
和Spring Cloud
作為微服務的基礎框架。然而,Spring Cloud
從誕生以來,就基於HTTP
協議的輕量級Restful API
作為服務之間的通訊方式。
在微服務架構設計中,可以分為外部服務和內部服務。兩者主要區別是:
- 外部服務:基於
Restful
風格的HTTP
協議,通過外網向外部提供服務,相對來說簡單並且通用。 - 內部服務:基於
RPC
訊息通訊的TCP/IP
協議,提供內網服務與服務之間的呼叫,以達到減少頻寬、降低延遲率、提高效能。
一些應用場景,尤其是內部服務需要高頻地呼叫,就需要考慮是否需要改造為RPC
實現,來提高吞吐量和系統效能,比如說鑑權服務一類。
正文
簡述
下載 spring-cloud-starter-thrift
並匯入IDEA
開發環境,專案地址:github.com/ostenant/sp…
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
個示例專案:calculator
、deposit
和test
。
- calculator:簡單上手專案示例。
- deposit:複雜業務場景專案示例。
- test:效能測試專案示例。
服務端
- 支援
Apache Thrift
的各種原生執行緒服務模型,包括單執行緒阻塞模型(simple
)、單執行緒非阻塞模型(nonBlocking
)、執行緒池阻塞模型(threadPool
)、半同步半非同步模型(hsHa
)和執行緒選擇器模型(threadedSelector
)。 - 支援
Apache Thrift 0.10.0
版本後提供的多路複用處理器,提供服務的統一註冊管理功能。 - 支援由服務簽名 (服務
ID
+ 客戶端Stub
介面名稱 + 服務版本號) 唯一標識服務Stub
的具體實現類,支援服務版本的平滑升級。 - 支援
Server Group
形式的啟動方式,每個服務例項可以開啟多臺Thrift Server
,通過不同的埠號暴露給客戶端。
客戶端
- 支援由服務簽名 (服務
ID
+ 客戶端Stub
介面名稱 + 服務版本號) 唯一標識和呼叫服務端的Stub
具體實現類。 - 支援
Apache Thrift
的Transport
層的連線池管理,減少了客戶端與服務端之間連線的頻繁建立和銷燬。 - 支援與
Spring Cloud Consul
的無縫整合,客戶端通過心跳檢測與服務註冊中心Consul
保持連線,動態定時的重新整理服務列表、監測服務的啟用、關閉和健康狀態。 - 支援客戶端負載均衡,包括隨機、輪詢的負載均衡策略,客戶端的
Thrift
程式通過本地的服務快取列表實現呼叫的動態轉發。
快速上手
專案結構:
- 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.0
的 Thrift IDL
編譯生成器,下載地址:thrift.apache.org/docs/instal…。通過編譯器生成.java
的Stub
類檔案。
thrift -gen java ./CalculatorService.thrift
複製程式碼
編譯器生成的CalculatorService.java
檔案。CalculatorService.java
有成千上萬行程式碼。對於開發人員而言,只需要關注以下四個核心介面/類:Iface
、AsyncIface
、Client
和AsyncClient
。
- Iface:服務端通過實現
HelloWorldService.Iface
介面,向客戶端的提供具體的同步業務邏輯。 - AsyncIface:服務端通過實現
HelloWorldService.Iface
介面,向客戶端的提供具體的非同步業務邏輯。 - Client:客戶端通過
HelloWorldService.Client
的例項物件,以同步的方式訪問服務端提供的服務方法。 - AsyncClient:客戶端通過
HelloWorldService.AsyncClient
的例項物件,以非同步的方式訪問服務端提供的服務方法。
中間契約(calculator-iface)
在中間契約模組引入thrift
的maven
依賴,拷貝上一步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-server:
thrift
服務端的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
,也就是說同一個服務名稱可以擁有多個版本實現。
- name:通過
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"]
複製程式碼
將Dockerfile
和 target/spring-boot-thrift-server-0.0.1-SNAPSHOT.jar
拷貝到伺服器上,構建 Thrift Server
的服務映象:
docker build . -t icekredit/calculator-server
複製程式碼
客戶端(calculator-client)
在客戶端模組引入:
- spring-cloud-starter-thrift-client:
thrift
客戶端的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
生成的Stub
類CalculatorService
中的Client
內部類。 - 介面需要標識
@ThriftClient
註解,@ThriftClient
包含如下屬性:- serviceId:此客戶端代理介面繫結的
Thrift
服務端的服務註冊ID (與服務端保持一致)。 - refer:客戶端樁
Stub
的型別,例如這裡是CalculatorService.class
。 - version:具體業務實現類的版本號(不填寫預設為
1.0
),需要與服務端保持一致。
- serviceId:此客戶端代理介面繫結的
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"]
複製程式碼
將Dockerfile
和 target/spring-boot-thrift-client-0.0.1-SNAPSHOT.jar
拷貝到伺服器上,構建 Thrift Client
的服務映象:
docker build . -t icekredit/calculator-client
複製程式碼
簡單測試
釋出服務端程式
為了方便測試,在一臺主機上啟動三個 Thrift Server
的 docker
容器,以不同的埠區分,分別指定對應的埠號和 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
複製程式碼
啟動 Consul
和Registrator
容器,Thrift Server
的三個服務例項成功註冊到Consul
服務列表:
有關 Consul
和 Registrator
的安裝配置以及使用,請參考: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 |
總結
本文簡單地介紹瞭如何利用 starter
將 Apache Thrift
整合進入 Spring Cloud
中,關於更復雜的應用場景和starter
內部的設計、實現原理,後續會一步步的給出具體的介紹!
歡迎關注技術公眾號: 零壹技術棧
本帳號將持續分享後端技術乾貨,包括虛擬機器基礎,多執行緒程式設計,高效能框架,非同步、快取和訊息中介軟體,分散式和微服務,架構學習和進階等學習資料和文章。