Thrift快速入门和简单示例

2023-11-16

Thrift介绍

Thrift是一个轻量级、跨语言的RPC框架,主要用于各个服务之间的RPC通信,它通过自身的IDL中间语言, 并借助代码生成引擎生成各种主流语言的RPC服务端/客户端模板代码。Thrift支持多种不同的编程语言,包括C++, Java, Python, PHP等。

Thrift官网地址,以下内容基于Apache Thrift v0.15.0。

RPC 全称 Remote Procedure Call——远程过程调用。RPC技术简单说就是为了解决远程调用服务的一种技术,使得调用者像调用本地服务一样方便透明

Thrift是一个典型的CS(客户端/服务端)结构,客户端和服务端可以使用不同的语言开发。既然客户端和服务端能使用不同的语言开发,那么一定就要有一种中间语言来关联客户端和服务端的语言,这种语言就是IDL (InterfaceDescription Language)

Thrift的架构

在这里插入图片描述
Thrift技术栈分层从下向上分别为:传输层(Transport Layer)、协议层(Protocol Layer)、处理层(Processor Layer)和服务层(Server Layer)。最底层是IO层,如通过socket进行网络通信。

  • 传输层(Transport Layer):传输层负责直接从网络中读取和写入数据,它定义了具体的网络传输协议。thrift传输层支持阻塞式IO和非阻塞式IO。
  • 协议层(Protocol Layer):协议层定义了数据传输格式,负责网络传输数据的序列化和反序列化;比如说JSON、XML、二进制数据等。
  • 处理层(Processor Layer):处理层是由具体的IDL(接口描述语言)生成的,封装了具体的底层网络传输和序列化方式,并委托给用户实现的Handler进行处理。
  • 服务层(Server Layer):整合上述组件,提供具体的网络IO模型(单线程/多线程/事件驱动),形成最终的服务。即业务逻辑代码。

Thrift的特性

开发速度快

通过编写RPC接口Thrift IDL文件,利用编译生成器自动生成服务端骨架(Skeletons)和客户端桩(Stubs)。从而省去开发者自定义和维护接口编解码、消息传输、服务器多线程模型等基础工作。

服务端:只需要按照服务骨架即接口,编写好具体的业务处理程序(Handler)即实现类即可。

客户端:只需要拷贝IDL定义好的客户端桩和服务对象,然后就像调用本地对象的方法一样调用远端服务。

接口维护简单

通过维护Thrift格式的IDL(接口描述语言)文件(注意写好注释),即可作为给Client使用的接口文档使用,也自动生成接口代码,始终保持代码和文档的一致性。且Thrift协议可灵活支持接口的可扩展性。

学习成本低

因为其来自Google Protobuf开发团队,所以其IDL文件风格类似Google Protobuf,且更加易读易懂;特别是RPC服务接口的风格就像写一个面向对象的Class一样简单。
初学者只需参照:http://thrift.apache.org/,一个多小时就可以理解Thrift IDL文件的语法使用。

多语言/跨语言支持

Thrift支持C++、 Java、Python、PHP、Ruby、Erlang、Perl、Haskell、C#、Cocoa、JavaScript、Node.js、Smalltalk等多种语言,即可生成上述语言的服务器端和客户端程序。

稳定/广泛使用

Thrift在很多开源项目中已经被验证是稳定和高效的,例如Cassandra、Hadoop、HBase等;国外在Facebook中有广泛使用,国内包括百度、美团小米、和饿了么等公司。

快速入门例子

编写user.thrift,通过IDL中间语言生成java代码,python代码,结合生成的代码,编写java服务端和python客户端,实现python跨语言调用java服务端接口代码。

编译安装

thrift编译器的安装
参考文档:https://thrift.apache.org/docs/install/
windows 安装
下载地址:https://thrift.apache.org/download
centos 安装
参考文档:https://thrift.apache.org/docs/install/centos.html

安装好后,配置好环境变量,测试安装是否成功:

#可以通过以下命令查看生成命令的格式
thrift -help

创建Thrift IDL文件

namespace java com.test
namespace py com.test

struct User{
    1:i32 id
    2:string name
    3:i32 age=0
}

service  UserService {
  User getById(1:i32 id)
  bool isExist(1:string name)
}

通过编译器编译user.thrift文件,生成java接口类文件

# 编译user.thrift
thrift -gen java user.thrift

生成UserService.java、User.java

User.java:

@SuppressWarnings({"cast", "rawtypes", "serial", "unchecked", "unused"})
@javax.annotation.Generated(value = "Autogenerated by Thrift Compiler (0.15.0)", date = "2022-01-14")
public class User implements org.apache.thrift.TBase<User, User._Fields>, java.io.Serializable, Cloneable, Comparable<User> {
  private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("User");

  private static final org.apache.thrift.protocol.TField ID_FIELD_DESC = new org.apache.thrift.protocol.TField("id", org.apache.thrift.protocol.TType.I32, (short)1);
  private static final org.apache.thrift.protocol.TField NAME_FIELD_DESC = new org.apache.thrift.protocol.TField("name", org.apache.thrift.protocol.TType.STRING, (short)2);
  private static final org.apache.thrift.protocol.TField AGE_FIELD_DESC = new org.apache.thrift.protocol.TField("age", org.apache.thrift.protocol.TType.I32, (short)3);

  private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new UserStandardSchemeFactory();
  private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new UserTupleSchemeFactory();
  ...

UserService.java:

@SuppressWarnings({"cast", "rawtypes", "serial", "unchecked", "unused"})
@javax.annotation.Generated(value = "Autogenerated by Thrift Compiler (0.15.0)", date = "2022-01-14")
public class UserService {

  public interface Iface {

    public User getById(int id) throws org.apache.thrift.TException;

    public boolean isExist(java.lang.String name) throws org.apache.thrift.TException;

  }
...

实现UserServiceService.Iface的定义方法

将生成类的UserService.java、User.java源文件拷贝进项目源文件目录中,并实现UserServiceService.Iface的定义的getById()方法。

package com.test.service;

import org.apache.thrift.TException;

import com.test.User;
import com.test.UserService;

public class UserServiceImpl implements UserService.Iface {

    @Override
    public User getById(int id) throws TException {

        System.out.println("=====调用getById=====");
        //todo 模拟业务调用
        User user = new User();
        user.setId(id);
        user.setName("fox");
        user.setAge(30);

        return user;
    }

    @Override
    public boolean isExist(String name) throws TException {
        return false;
    }
}

服务器端程序编写

public class SimpleService {

    public static void main(String[] args) {

        try {
            TServerTransport serverTransport = new TServerSocket(9090);

            //获取processor
            UserService.Processor processor = new UserService.Processor(new UserServiceImpl());
            //指定TBinaryProtocol
            TBinaryProtocol.Factory protocolFactory = new TBinaryProtocol.Factory();

            TSimpleServer.Args targs = new TSimpleServer.Args(serverTransport);
            targs.processor(processor);
            targs.protocolFactory(protocolFactory);

            //单线程服务模型,一般用于测试
            TServer server = new TSimpleServer(targs);

            System.out.println("Starting the simple server...");
            //暴露服务
            server.serve();
        } catch (Exception e) {
            e.printStackTrace();
        }

    }
}

python客户端代码编写

  1. 通过编译器编译user.thrift文件,生成python代码然后将生成的 python 代码 和 文件,放到新建的 python 项目中
thrift -gen py user.thrift
  1. python中使用thrift需要安装thrift模块
pip install thrift
  1. 创建python客户端程序
from thrift.transport import TSocket, TTransport
from thrift.protocol import TBinaryProtocol
from com.tuling import UserService
# Make socket
transport = TSocket.TSocket('localhost', 9090)
transport.setTimeout(600)
# Buffering is critical. Raw sockets are very slow
transport = TTransport.TBufferedTransport(transport)
# Wrap in a protocol
protocol = TBinaryProtocol.TBinaryProtocol(transport)
# Create a client to use the protocol encoder
client = UserService.Client(protocol)
# Connect!
transport.open()
result = client.getById(1)
print(result)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Thrift快速入门和简单示例 的相关文章

  • 使用 Intellij Idea 和 gradle 在应用程序引擎上调试 localhost

    我正在使用 IntelliJ 社区添加并使用 Gradle 构建应用程序引擎标准环境应用程序 在迁移到 IntelliJ 和端点框架之前 我使用的是 Android Studio 我无法调试我的本地主机 我添加了 jvmFlags 如下所述
  • Java:扩展类并实现具有相同方法的接口

    可能无法完成以下操作 我收到编译错误 继承的方法 A doSomthing int 无法隐藏 B 中的公共抽象方法 public class A int doSomthing int x return x public interface
  • 有没有创建 Cron 表达式的 Java 代码? [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 我需要一个 Java 代码来根据用户输入创建一个 cron 表达式 用户输入是时间 频率和执行次数 只需从评论中添加 自己创建 即可
  • TreeMap 删除所有大于某个键的键

    在项目中 我需要删除键值大于某个键的所有对象 键类型为Date 如果重要的话 据我所知TreeMapJava中实现的是红黑树 它是一种二叉搜索树 所以我应该得到O n 删除子树时 但除了制作尾部视图并一一删除之外 我找不到任何方法可以做到这
  • Java Logger 未记录到 Netbeans 中的输出

    我正在 Netbeans 中使用 Maven 启动一个 Java 项目 我编写了一些代码来使用 Logger 类进行日志记录 但是 日志记录似乎不起作用 在程序开始时 我运行 Logger getLogger ProjectMainClas
  • 与 Eclipse 中的 Java Content Assist 交互

    作为我的插件项目的一部分 我正在考虑与 Eclipse 在 Java 文件上显示的内容辅助列表进行交互 我正在尝试根据一些外部数据对列表进行重新排序 我看过一些有关创建新内容辅助的教程 但没有看到有关更改现有内容辅助的教程 这可能吗 如果是
  • 如何在 JPQL 或 HQL 中进行限制查询?

    在 Hibernate 3 中 有没有办法在 HQL 中执行相当于以下 MySQL 限制的操作 select from a table order by a table column desc limit 0 20 如果可能的话 我不想使用
  • 如何检查某个元素是否存在于一组项目中?

    In an ifJava中的语句如何检查一个对象是否存在于一组项目中 例如 在这种情况下 我需要验证水果是苹果 橙子还是香蕉 if fruitname in APPLE ORANGES GRAPES Do something 这是一件非常微
  • 将非 Android 项目添加到 Android 项目

    我在 Eclipse 中有三个项目 Base Server 和 AndroidClient Base和Server是Java 1 7项目 而AndroidClient显然是一个android项目 基础项目具有在服务器和 Android 客户
  • 如何在字段值无效的情况下更改 Struts2 验证错误消息?

    我在 Web 表单上使用 Struts2 验证 如果字段假设为整数或日期 则
  • Java Applet 中的 Apache FOP - 未找到数据的 ImagePreloader

    我正在研究成熟商业产品中的一个问题 简而言之 我们使用 Apache POI 库的一部分来读取 Word DOC 或 DOCX 文件 并将其转换为 XSL FO 以便我们可以进行标记替换 然后 我们使用嵌入到 Java 程序中的 FOP 将
  • 如何使用 JMagick 转换色彩空间?

    如何使用 JMagick API 转换色彩空间 例如 CMYK gt RGB 和 RGB gt CMYK None
  • 如何在.NET中使用java.util.zip.Deflater解压缩放气流?

    之后我有一个转储java util zip Deflater 可以确认它是有效的 因为 Java 的Inflater打开它很好 并且需要在 NET中打开它 byte content ReadSample sampleName var inp
  • 提高 PostgreSQL 1 亿数据左连接查询性能

    我在用Postgresql 9 2 version Windows 7 64 bit RAM 6GB 这是一个Java企业项目 我必须在我的页面中显示订单相关信息 有三个表通过左连接连接在一起 Tables TV HD 389772 行 T
  • 使用 Elastic Beanstalk 进行 Logback

    我在使用 Elastic Beanstalk 记录应用程序日志时遇到问题 我正在 AWS Elastic Beanstalk 上的 Tomcat 8 5 with Corretto 11 running on 64bit Amazon Li
  • 将 JScrollPane 添加到 JFrame

    我有一个关于向 Java 框架添加组件的问题 我有一个带有两个按钮的 JPanel 和一个添加了 JTable 的 JScrollPane 我想将这两个添加到 JFrame 中 我可以将 JPanel 添加到 JFrame 或将 JScro
  • java XMLSerializer 避免复杂的空元素

    我有这个代码 DocumentBuilderFactory factory DocumentBuilderFactory newInstance DocumentBuilder builder factory newDocumentBuil
  • java 中的蓝牙 (J2SE)

    我是蓝牙新手 这就是我想做的事情 我想获取连接到我的电脑上的蓝牙的设备信息并将该信息写入文件中 我应该使用哪个 api 以及如何实现 我遇到了 bluecove 但经过几次搜索 我发现 bluecove 不能在 64 位电脑上运行 我现在应
  • Java 正则表达式中的逻辑 AND

    是否可以在 Java Regex 中实现逻辑 AND 如果答案是肯定的 那么如何实现呢 正则表达式中的逻辑 AND 由一系列堆叠的先行断言组成 例如 foo bar glarch 将匹配包含所有三个 foo bar 和 glarch 的任何
  • Java RMI - 客户端超时

    我正在使用 Java RMI 构建分布式系统 它必须支持服务器丢失 如果我的客户端使用 RMI 连接到服务器 如果该服务器出现故障 例如电缆问题 我的客户端应该会收到异常 以便它可以连接到其他服务器 但是当服务器出现故障时 我的客户端什么也

随机推荐

  • nodejs调用mongodb!!!

    Nodejs调用MongoDB 要在 MongoDB 中创建一个数据库 首先我们需要创建一个 MongoClient 对象 然后配置好指定的 URL 和 端口号 如果数据库不存在 MongoDB 将创建数据库并建立连接 导入MongoDB包
  • 华为VS谷歌:万物互联,谁主沉浮?

    一 一周两套操作系统发布 6月2日 华为通过直播形式举行了鸿蒙HarmonyOS 2及华为全场景新品发布会 关于该发布会的详细内容老猿在 鸿蒙最新功能及承载设备详解 HarmonyOS 2及华为全场景新品发布会全纪录 进行了详细介绍 在此不
  • 【科普】一文读懂以太网PHY芯片

    物理层器件PHY Physical Layer Interface Devices 是将各网元连接到物理介质上的关键部件 负责完成互连参考模型 OSI 第1层中的功能 即为链路层实体之间进行bit传输提供物理连接所需的机械 电气 光电转换和
  • 嵌入式中锁机制杂谈

    在之前的文章中有提到操作系统中锁机制一般依赖于硬件CPU提供的原子数据操作指令 如SWP TEST AND SET等原子原语实现 基于此 才能真正保证锁机制的有效实现 通过上面原子操作 我们比较容易实现所谓的自旋操作 原子性的原地循环判断条
  • np.random.choice用法

    np random choice a size replace p 其作用是按要求生成一个一维数组 a是生成一维数组的来源 可以是int类型 可以是数组 也可以是list size 为从a中抽取的个数 即生成数组的维度 replace 表示
  • 《数据库系统》课程之实验七 通过ODBC/JDBC转移异构数据库中数据

    注 查看全文请关注作者 或点击前往 数据库系统 课程之实验七 通过ODBC JDBC转移异构数据库中数据 数据库系统 课程之实验七 通过ODBC JDBC转移异构数据库中数据 1 实验目的 学会配置ODBC JDBC数据源 熟悉使用ODBC
  • QueryWrapper方法解释

    继承自 AbstractWrapper 自身的内部属性 entity 也用于生成 where 条件 及 LambdaQueryWrapper 可以通过 new QueryWrapper lambda 方法获取 queryWrapper lt
  • PyTorch实战——搭建PyTorch神经网络进行气温预测

    如果觉得我的分享对您的学习有帮助 可以点赞关注哈 谢谢哈 目录 编辑 一 理论部分 二 代码实战 1 导入模块 1 matplotlib inline 2 warnings filterwarnings ignore 2 读入数据 3 展示
  • 三极管电路共集、共基、共射的区别

    共集 共基 共射指的是电路 是三极管电路的连接状态而不是三极管 所谓 共 就是输入 输出回路共有的部分 其判断是在交流等效电路下进行的 共集电极电路 三极管的集电极接地 集电极是输入与输出的公共极 共基极电路 三极管的基极接地 基极是输入与
  • 安装ubuntu系统时给/home分配空间太小,导致训练模型时数据集无法存放,所以给/home增大100GGB的存储空间

    1 从Windows系统中分配出100GB的存储空间 2 制作gparted的U盘启动项 3 插入U盘 进入bios界面 选择U盘启动项 4 进入gparted软件界面进行存储空间的转移重新分配 5 Exit退出 重新进入linux系统 参
  • 微信小程序 WebSocket 端口号配置

    https blog liuguofeng com p 4630 服务端开启 WebSocket 使用 WorkerMan phpSocket io 开启的端口为 2120 访问为 ws wanaioa unetu net 2120 由于微
  • 基于 java Swing 客户端 和 Spring Boot/Spring Cloud & Alibaba 后台管理系统

    基于 java Swing 客户端 和 Spring Boot Spring Cloud Alibaba 后台管理系统 基于 java Swing 客户端 和 Spring Boot Spring Cloud Alibaba 后台管理系统
  • 【Java JDK的使用方法】

    Java JDK的使用方法 第一步 同时按住窗口键和R键 在弹出的运行框中输入cmd打开编译框 第二步 输入cd 空格 地址 可以查看桌面文本文档的属性 找到桌面地址 第三步 notepad 空格 文件名 java 新建java文件 第四步
  • 何为UNP技术?

    为了解决移动视频监控系统中的这种穿NAT型 宇视科技特意提出了UNP UniversalNetwork Passport 万能网络护照 技术 目前 针对监控系统穿越NAT设备 防火墙和安全网闸时 基本上都是使用引流方案 内部服务器 双网口方
  • C++ 调用tensorflow

    安装protobuf 3 6 安装依赖软件 sudo apt get install autoconf automake libtool curl make g unzip 克隆版本为3 6 0的protobuf源码 git clone b
  • 8.翻转子串

    题目描述 假定我们都知道非常高效的算法来检查一个单词是否为其他字符串的子串 请将这个算法编写成一个函数 给定两个字符串s1和s2 请编写代码检查s2是否为s1旋转而成 要求只能调用一次检查子串的函数 给定两个字符串s1 s2 请返回bool
  • 1-如何安装ROS

    如何安装ROS 大家好 我是如何 今天尝试在Ubantu下安装ROS Robot Operating System 测试环境 虚拟机VMware Ubantu20 04 准备步骤 添加ROS软件源 sudo sh c echo deb ht
  • C++之普通成员函数、虚函数以及纯虚函数的区别与用法要点

    C 之普通成员函数 虚函数以及纯虚函数的区别与用法要点 作者 luoweifu 字体 增加 减小 类型 转载 时间 2015 07 21 我要评论 本篇文章主要介绍了C 中的普通成员函数 虚函数以及纯虚函数 非常的详细 有需要的朋友可以参考
  • localstorage在uc无痕模式失效问题;

    做项目的时候发现localstorage在uc 无痕模式下失效 但是其他浏览器不会出现此类问题 补充 我的解决方案是使用cookie代替localstorage 但是有大神给出了解决方案我觉得非常nice 附 https www jians
  • Thrift快速入门和简单示例

    文章目录 Thrift介绍 Thrift的架构 Thrift的特性 开发速度快 接口维护简单 学习成本低 多语言 跨语言支持 稳定 广泛使用 快速入门例子 编译安装 创建Thrift IDL文件 通过编译器编译user thrift文件 生