thrift 原理浅析

简介: thrift 原理浅析

RPC 原理

RPC( Remote Procedure Call ) 远程调用过程。

1. 定义了一个接口文件,描述了对象,对象成员,接口方法等一系列信息。
2.通过RPC 框架提供的编译器,将接口说明文件编译成对应的语言文件。
2. 在客户端和服务端分别引用 RPC 编译器生成的文件,即可像调用本地方法一样远程调用。

RPC 通信过程如下:

image.png

1.客户端以正常方式调用客户桩(client stub)
2. 客户桩生成一个消息,然后调用本地操作系统。
3. 客户端操作系统将消息发送给原程操作系统。
4. 远程操作系统将消息交给服务器桩
5. 服务器桩将参数提取出来,然后调用服务过程
6. 服务器执行要求的操作,操作完成后将结果返回给服务器桩,
7. 服务器桩将结果打包成一个消息, 然后调用本地操作系统。
8. 服务器操作系统将含有结果的消息发送给客户端操作系统
9. 客户端操作系统将消息交给客户桩
10. 客户桩将结果提取出来,返回给他的调用方 
  • 资源粒度, RPC 调用类似于本地调用,RESTful API 每一次添加接口都可能需要额外开发接口的数据,这相当于应用视图中再写一次方法调用。
  • 流量消耗,RestFull API 在应用层和使用 HTTP 协议, 即使是传输高效的 JSON 也会消耗较大流量, RPC 可以使用 TCP,也可以使用 UDP , 而且可以编码,降低数据大小和减少流量消耗。


Thrift 架构


Thrift 作用于各个服务之间的 RPC 通信,支持跨语言,thrift 是一个典型的 CS 框架,客户端服务端可以使用不同的语言开发, thrift  通过 IDL (Interface Description Language) 来关联客户端和服务器。

Thrift 整体架构

image.png

  • your code 是业务逻辑代码
  • FooService.Client /Foo.Processor() + Foo.Write() Foo.Read是 thrift 根据 IDL  生成的客户端和服务端代码,对应的是 RPC 中的 Client Stub 和 Server Stub
  • TProtocol 是用来对数据进行序列化和反序列化。
  • TTransport 提供传输数据功能,使用 Apache Thrift 可以方便的定义一个服务并选择不同的传输协议。


Thrift 网络栈架构


image.png

TTransport 层


  • TSocket :阻塞 Socket
  • TFrametransport :以 frame 为单位进行传输, 非阻塞式服务中使用
  • TFileTransport : 以文件形式进行传输

TProtocol 层


代表 thrift 客户端和服务端之间的传输数据的协议,指的是客户端和服务端传输数据的格式,比如 Json,  thrift 中有如下格式:

  • TBinaryProtocol:二进制格式
  • TCompactProtocol:压缩格式
  • TJSONProtocol : Json 格式
  • TSimpleJsonProtocol:提供只写的 JSON 协议

Thrift 支持的 Server 模型

  • TSimpleServer :用于简单的单线程模型,常用于测试
  • TThreadPoolServer :多线程模型,使用标准的阻塞 IO
  • TNoBlockingServer: 多线程服务模型,使用非阻塞 IO,需要使用TFramedTransport 数据传输方式。
  • THsHaServer : THsHa 引入了线程池去处理,其模型读写任务放到线程池去处理,Half-sync/Half-async处理模式,Half-async是在处理IO事件上(accept/read/write io),Half-sync用于handler对rpc的同步处理;


Thrift  支持的基本数据类型


  • byte: 有符号字节
  • i16: 16 位有符号整数
  • i32 : 32 位有符号整数
  • i64: 64 位有符号整数
  • double : 64 位浮点数
  • string : 字符串

Thrift 支持的容器类型


  • list:一系列由 T 类型的数据组成的有序列表, 元素可以重复
  • set : 一系列由 T 类型组成的无序集合,元素不可以重复
  • map: 一个字典结构,Key 为 K 类型, Value 为 V 类型,和 Java 中的 HashMap 类似

thrift 支持 struct 类型,可以将一些数据类型聚合到一块。


struct People {
    1:string name;
    2:i32 age;
    3:string gender;
}


thrift 支持枚举类型


enum Gender {
    MALE,
    FEMALE
}


thrift 支持异常类型


exception RequestException {
    1:i32 code;
    2:string reason;
}


thrift 定义 Service. 格式如下:


service HelloWorldService {
    // service中可以定义若干个服务,相当于Java Interface中定义的方法
    string doAction(1:string name, 2:i32 age);
}


thrift 支持给类型定义别名


typedef i32 int
typedef i64 long


thrift. 支持常量的定义


const i32 MAX_RETRIES_TIME = 10;
const string MY_WEBSITE = "http://facebook.com";


thrift 支持命名空间,相当于 Java 中的package.


namespace java com.test.thrift.demo


#、//、/**/都可以作为thrift文件中的注释。

thrift提供两个关键字required和optional,分别用于表示对应的字段是必填的还是可选的(推荐尽量使用optional),如下


struct People {
    1:required string name;
    2:optional i32 age;
}


thrift也支持文件包含,相当于CPP中的include,Java中的import,使用关键字include:


include "global.thrift"


thrift IDL 例子


// data.thrift
namespace java thrift.generated
namespace py py.thrift.generated
typedef i16 short
typedef i32 int
typedef i64 long
typedef bool boolean
typedef string String
// struct关键字用于定义结构体,相当于面向对象编程语言中的类
struct Person {
    // 相当于定义类中的成员,并生成相应的get和set方法,optional表示username这个成员可以没有
    1: optional String username,
    2: optional int age,
    3: optional boolean married
}
// 定义一个异常类型,用于接口中可能抛出的异常
exception DataException {
    1: optional String message,
    2: optional String callStack,
    3: optional String date
}
// 定义服务接口
service PersonService {
    Person getPersonByUsername(1: required String username) throws (1: DataException data),
    void savePerson(1: required Person person)
}

执行 thrift --gen java src/thrift/data.thrift  生成代码.

thrift 如何安装,可参考 https://wangxiaoming.blog.csdn.net/article/details/114317905

客户端可以像调用本地的方法一样调用服务端的方法

生成代码结构如下:

image.png

相关文章
|
Kubernetes 容器 Perl
使用kube-proxy让外部网络访问K8S service的ClusterIP
配置方式 kubernetes版本大于或者等于1.2时,外部网络(即非K8S集群内的网络)访问cluster IP的办法是: 修改master的/etc/kubernetes/proxy,把KUBE_PROXY_ARGS=”“改为KUBE_PROXY_ARGS=”–proxy-mode=userspace” 重启kube-proxy服务 在核心路由设备或者源主机上添加一条路由,访问cluster IP段的路由指向到master上。
4817 0
|
2月前
|
存储 弹性计算 应用服务中间件
阿里云轻量应用服务器与云服务器ECS有何区别?轻量应用服务器性能、优势与收费价格参考
2025年,阿里云轻量应用服务器2核2G3M带宽搭配40GB ESSD云盘的配置,每天10点和15点开启的抢购价只要38元1年,新用户非抢购专属优惠价也只要68元1年。对于一些初次接触阿里云轻量应用服务器的用户来说,可能不是很清楚它与云服务器ECS有什么不同?选择轻量应用服务器有哪些优势,本文为大家介绍轻量应用服务器的性能、适用场景、优势、收费标准以及与云服务器ECS之间的区别,以供参考。
|
Android开发 Java
Android Studio 解决 Error:Unable to start the daemon process.
异常 Error:Unable to start the daemon process. This problem might be caused by incorrect configuration of the daemon.
2949 0
|
11月前
|
设计模式 前端开发 搜索推荐
前端必须掌握的设计模式——模板模式
模板模式(Template Pattern)是一种行为型设计模式,父类定义固定流程和步骤顺序,子类通过继承并重写特定方法实现具体步骤。适用于具有固定结构或流程的场景,如组装汽车、包装礼物等。举例来说,公司年会节目征集时,蜘蛛侠定义了歌曲的四个步骤:前奏、主歌、副歌、结尾。金刚狼和绿巨人根据此模板设计各自的表演内容。通过抽象类定义通用逻辑,子类实现个性化行为,从而减少重复代码。模板模式还支持钩子方法,允许跳过某些步骤,增加灵活性。
631 11
|
SQL 算法 关系型数据库
Mysql Online DDL
Mysql Online DDL
174 2
|
消息中间件 Dubbo 应用服务中间件
微服务调用中TraceId是如何传递的?
由于网络原因,我暂时无法解析提供的网页链接。请检查链接是否有效,或稍后再试。如果您有其他问题或需要帮助,请随时告诉我。
微服务调用中TraceId是如何传递的?
|
人工智能 算法
AI 写歌词,会让歌词创作变得更容易吗?
在科技迅猛发展的今天,AI已渗透至多个领域,包括歌词创作。《妙笔生词智能写歌词软件》通过强大算法与海量数据,为新手提供创作指导,快速生成多风格歌词片段,降低创作门槛,节省时间。尽管如此,优秀作品仍需创作者的情感与思考,AI辅助下的歌词创作正逐渐变得更为便捷。
|
canal 缓存 NoSQL
Redis常见面试题(一):Redis使用场景,缓存、分布式锁;缓存穿透、缓存击穿、缓存雪崩;双写一致,Canal,Redis持久化,数据过期策略,数据淘汰策略
Redis使用场景,缓存、分布式锁;缓存穿透、缓存击穿、缓存雪崩;先删除缓存还是先修改数据库,双写一致,Canal,Redis持久化,数据过期策略,数据淘汰策略
Redis常见面试题(一):Redis使用场景,缓存、分布式锁;缓存穿透、缓存击穿、缓存雪崩;双写一致,Canal,Redis持久化,数据过期策略,数据淘汰策略
|
负载均衡
alb负载均衡按量降价了,资源包抵扣已经比按量付费的贵了,结果还是在走资源包抵扣。
ALB实例按量付费已降价,1万LCU资源包单价现为0.0485,3LCU可抵一小时标准版实例费用(原0.147现降至0.125),单LCU价格也下调至0.042。资源包价格保持不变,旧购资源包仍在抵扣中,建议调整为降价时不进行抵扣。同时,附上与不太了解情况的客服交流记录供参考。
|
网络协议 定位技术 网络虚拟化
Trunk扩展及单臂路由
Trunk扩展及单臂路由
496 0