美文网首页java后台常用开发框架学习
Spring Cloud整合Thrift RPC(一) - 使用

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

作者: 零壹技术栈 | 来源:发表于2018-09-14 22:49 被阅读2077次

    前言

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

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

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

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


    正文

    简述

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

    image
    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程序通过本地的服务缓存列表实现调用的动态转发。

    快速上手

    项目结构:

    image
    • 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编译生成器,下载地址:http://thrift.apache.org/docs/install。通过编译器生成.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服务列表:

    image

    有关 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内部的设计、实现原理,后续会一步步的给出具体的介绍!


    欢迎关注技术公众号: 零壹技术栈

    零壹技术栈

    本帐号将持续分享后端技术干货,包括虚拟机基础,多线程编程,高性能框架,异步、缓存和消息中间件,分布式和微服务,架构学习和进阶等学习资料和文章。

    相关文章

      网友评论

        本文标题:Spring Cloud整合Thrift RPC(一) - 使用

        本文链接:https://www.haomeiwen.com/subject/hzwagftx.html