Thrift快速入门

2023-11-20

Thrift的安装

windows下安装

下载地址:thrift下载地址

比如这里选择thrift-0.9.3.exe改名为thrift.exe(只是为了命令行使用方便),下载后放到 C:\Thrift(随意),复制路径 C:\Thrift,添加到环境变量Path中即可。

查看版本:

C:\>thrift -version
Thrift version 0.9.3

Linux下安装

下载地址不变

这里选择thrift-0.5.0.tar.gz,命令行进入该压缩文件所在目录,依次执行以下命令。

tar zxvf thrift-0.5.0.tar.gz
cd thrift-0.5.0
 
sudo apt-get install automake bison flex g++ git libboost-all-dev libevent-dev libssl-dev libtool make pkg-config
 
./configure
make
sudo make install

查看安装是否成功:thrift

查看是否安装成功
xxx:~/software/thrift-0.5.0$ thrift
Usage: thrift [options] file
Options:
  -version    Print the compiler version
  -o dir      Set the output directory for gen-* packages
               (default: current directory)
  -I dir      Add a directory to the list of directories
                searched for include directives
  -nowarn     Suppress all compiler warnings (BAD!)
  -strict     Strict compiler warnings on
  -v[erbose]  Verbose mode
  -r[ecurse]  Also generate included files
  -debug      Parse debug trace to stdout
  --gen STR   Generate code with a dynamically-registered generator.
                STR has the form language[:key1=val1[,key2,[key3=val3]]].
                Keys and values are options passed to the generator.
                Many options will not require values.

Available generators (and options):
  as3 (AS3):
    bindable:          Add [bindable] metadata to all the struct classes.

Thrift的使用

Thrift是一种接口描述语言和二进制通讯协议,它被用来定义和创建跨语言的服务。它被当作一个远程过程调用(RPC)框架来使用,是由Facebook开发捐给apache的。

接下来通过简单的远程过程调用案例来进行介绍

编写IDL文件

​ 该框架是一个典型的C/S结构,即客户端/服务端结构;客户端和服务端可以使用不同的语言进行开发,既然这样那么肯定有一种中间语言来连接客户端和服务端,这种语言即为IDL

​ IDL为接口定义(或者说描述)语言的简写,在thrift中就是指的*.thrift文件,有自己的一套语法,但是很简单。使用idea的时候,创建了该文件会提示安装插件,让开发更简单。

namespace java com.scu.thrift.shared

typedef i32 int
typedef i64 long
typedef bool boolean
typedef string String

struct Goods {
    1: optional long id,
    2: optional String name,
    3: optional double price,
    4: optional String desc
}

exception GoodsException {
    1: int code,
    2: String message,
    3: long date
}

service GoodsService {
    Goods getGoodsById(1: required long id) throws (1: GoodsException e),

    int saveGoods(1: required Goods goods) throws (1: GoodsException e)
}

命名空间: namespace

相当于java中的package

namespace java com.scu.thrift.shared` 表示生成java文件,同时会放在com.scu.thrift.shared目录下;

基本数据类型

​ byte: 有符号字节

​ i16: 16位有符号字节,相当于java的short

​ i32: 32位有符号字节,相当于java的int

​ i64: 64位有符号字节, 相当于java的long

​ double: 64位浮点数,相当于java的double

​ string: 字符串类型

​ bool: 相当于java的boolean

此外还有容器类型:list,set,map和java一样

类型定义:typedef

typedef : 顾名思义,定义类型,typedef i32 int表示将i32命名为int, 方便后续使用,直接可以使用int来代替i32。

结构体类型: struct

相当于java的类

struct Goods {
    1: optional long id,
    2: optional String name,
    3: optional double price,
    4: optional String desc
}

其中的每个属性使用序号1,2,3,…进行标注,接着是参数类型和参数名称,每行使用逗号进行分割,最后一行不需要。optional表示可选,默认就是optional。

枚举类型: enum

enum Size {
    BIG,
    SMALL
}

异常类型:exception

也是和java类型的

exception GoodsException {
    1: int code,
    2: String message,
    3: long date
}

规则和结构体类型一样,需要注意的是没有日期类型,通常使用时间戳来表示,或者也可以使用string类型。

服务类型:service

相当于java中的interface,其中写的是一个个的抽象方法

service GoodsService {
    Goods getGoodsById(1: required long id) throws (1: GoodsException e),

    int saveGoods(1: required Goods goods) throws (1: GoodsException e)
}

这里定义了两个方法,required表示必传,不管是异常列表还是参数列表,同样需要使用序号。

文件包含:include

相当于java中的import

include com.scu.data.thrift

注释

使用 //,#,/**/

商品查询和添加案例

​ 创建工程thrift-parent,打包方式为pom,删除掉src文件夹(个人习惯,毕竟父工程也不会去写代码,这里仅仅是管理依赖),最后天津 thrift的依赖。

<packaging>pom</packaging>

<groupId>com.scu</groupId>
<artifactId>thrift-parent</artifactId>
<version>1.0-SNAPSHOT</version>

<dependencies>
    <dependency>
    <groupId>org.apache.thrift</groupId>
    <artifactId>libthrift</artifactId>
    <version>0.9.3</version>
    </dependency>
</dependencies>

在thrift-parent项目下创建三个模块,

open-shared:管理公共资源,比如将idl文件生成的java文件都放在这,打成jar包,那么服务提供方和调用方引入依赖就可以使用了。

open-web: 服务调用方

open-service:服务提供方

最终thrift-parent的 pom.xml文件如下

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <packaging>pom</packaging>
    <modules>
        <module>open-shared</module>
        <module>open-web</module>
        <module>open-service</module>
    </modules>

    <groupId>com.scu</groupId>
    <artifactId>thrift-parent</artifactId>
    <version>1.0-SNAPSHOT</version>

    <dependencies>
        <dependency>
            <groupId>org.apache.thrift</groupId>
            <artifactId>libthrift</artifactId>
            <version>0.9.3</version>
        </dependency>
    </dependencies>
</project>

在open-shared的src下编写thrift/open.thrift文件

namespace java com.scu.thrift.shared

typedef i32 int
typedef i64 long
typedef bool boolean
typedef string String

struct Goods {
    1: optional long id,
    2: optional String name,
    3: optional double price,
    4: optional String desc
}

exception GoodsException {
    1: int code,
    2: String message,
    3: long date
}

service GoodsService {
    Goods getGoodsById(1: required long id) throws (1: GoodsException e),

    int saveGoods(1: required Goods goods) throws (1: GoodsException e)
}

命令行进入到该目录,执行命令

C:\Users\mi\workspaces\thrift-parent>cd open-shared

C:\Users\mi\workspaces\thrift-parent\open-shared>thrift --gen java src/thrift/open.thrift

C:\Users\mi\workspaces\thrift-parent\open-shared>

此时在src下可以看到生产的目录结构和java文件

在这里插入图片描述

将open-shared进行安装 命令:mvn install;在open-web,open-service中引入open-shared依赖

编写服务端

服务端指的是提供商场服务的一端,即open-service

首先需要实现接口:

public class GoodsServiceImpl implements GoodsService.Iface {
    @Override
    public Goods getGoodsById(long id) throws GoodsException, TException {
        Goods goods = new Goods().setId(id).setName("mi").setPrice(3699.0).setDesc("第一款5G手机");
        System.out.println("查找商品:" + goods);
        return goods;
    }

    @Override
    public int saveGoods(Goods goods) throws GoodsException, TException {
        System.out.println("保存商品:" + goods);
        return (int)goods.getId();
    }
}

启动服务:

public class ThriftServer {
    public static void main(String[] args) throws TTransportException {
        TNonblockingServerSocket socket = new TNonblockingServerSocket(8081);// 创建非阻塞socket
        THsHaServer.Args arg = new THsHaServer.Args(socket).minWorkerThreads(2).maxWorkerThreads(4); // 设置最小最大工作线程
        GoodsService.Processor<GoodsServiceImpl> processor = new GoodsService.Processor<>(new GoodsServiceImpl()); // 绑定服务
		
        // 会把二级制进行进一步压缩  这种传输格式用的最多
        arg.protocolFactory(new TCompactProtocol.Factory()); // TProtocol传输数据的格式也是一种协议
        arg.transportFactory(new TFramedTransport.Factory()); // 传输
        arg.processorFactory(new TProcessorFactory(processor)); // 服务与服务端绑定,所以PersonServiceImpl的输出在服务端

        TServer server =new THsHaServer(arg); // 半同步半异步
        server.serve(); // 死循环,异步非阻塞
    }
}

编写客户端

即open-web,会进行服务的调用,查询和保存商品

public class ThriftClient {
    public static void main(String[] args) throws Exception {
        TTransport transport = new TFramedTransport(new TSocket("localhost", 8081), 1000);
        TProtocol protocol = new TCompactProtocol(transport);
        GoodsService.Client client =new GoodsService.Client(protocol);
        transport.open();

        Goods goods = client.getGoodsById(10086);
        System.out.println(goods);
        System.out.println("------------------------");

        int id = client.saveGoods(new Goods().setId(10010).setName("iphone").setPrice(5499.0).setDesc("玩游戏还是很舒服的"));
        System.out.println(id);
    }
}

查看结果

先运行服务端,再运行客户端。

服务端窗口输出:

查找商品:Goods(id:10086, name:mi, price:3699.0, desc:第一款5G手机)
保存商品:Goods(id:10010, name:iphone, price:5499.0, desc:玩游戏还是很舒服的)

客户端窗口输出:

Goods(id:10086, name:mi, price:3699.0, desc:第一款5G手机)
------------------------
10010

接口简单介绍

官网的架构如下:

在这里插入图片描述

Thrift的数据传输格式:

  1. TBinaryProtocol: 二进制格式;
  2. TCompactProtocol: 在二进制格式上进行进一步压缩, 大部分场景推荐这个;
  3. TJSONProtocol: JSON格式;
  4. TSimpleJSONProtocol: JSON只写协议,即编码后难以解码,一般不会使用到。

thrift的数据传输方式:

  1. TFramedTransport: 以 frame(帧)为单位进行传输,在非阻塞式服务中应用;
  2. TFileTransport: 以文件的形式进行传输;
  3. TMemoryTransport: 将内存用于IO的形式,java中简单使用了ByteArrayOutputStream来进行实现。

thrift支持的服务模型

  1. TSimpleServer: 简单的单线程服务模型,常用于测试;
  2. TThreadPoolServer: 多线程服务模型,使用了标准的阻塞式IO;
  3. TNonblockingServer: 多线程服务模型,使用了非阻塞式IO(需要配合TFramedTransport使用);
  4. THsHaServer:使用半同步半异步的处理模式,半异步用来处理IO事件(accept/read/write IO),半同步用于handler对rpc的同步处理。该方式是引入了线程池的。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Thrift快速入门 的相关文章

  • go-zero开发入门之网关往rpc服务传递数据1

    go zero 的网关往 rpc 服务传递数据时 可以使用 headers 但需要注意前缀规则 否则会发现数据传递不过去 或者对方取不到数据 go zero 的网关对服务的调用使用了第三方库 grpcurl 入口函数为 InvokeRPC
  • Python远程过程调用(不带远程部分)

    我有一个不以 root 身份运行的 Python 服务器 它面向我正在开发的应用程序 然而 有一些应用程序功能需要访问 RAW 套接字 这意味着 root 权限 显然 我不想以 root 身份运行主服务器 因此我的解决方案是创建一个守护进程
  • 我如何利用 ZeroMQ 编写自己的 Protocol Buffers RPC 实现

    根据 下的 Google Protocol Buffers 文档定义服务 https developers google com protocol buffers docs proto3 services 他们说 也可以将协议缓冲区与您自己
  • GWT (2.4.0) + XSRF

    我一直在尝试让 XSRF 在网络应用程序上运行 但没有成功 我正在研究一个典型的登录实现 我正在关注谷歌的代码 https developers google com web toolkit doc latest DevGuideSecur
  • Thrift TSimpleServer 在多次成功请求后变得无响应

    我有一个 Thrift API 由在 Linux 上运行的 Java 应用程序提供服务 我正在使用 NET 客户端连接到 API 并执行操作 对该服务的前几次调用工作正常 没有错误 但随后 看似随机 调用将 挂起 如果我强制退出客户端并尝试
  • 当未提供 COM+ dll 时,从 COM+ dll 获取 IDL(用于 TLB)

    我有一个 dll 其中包含一些带有特定 自定义接口进行查询的 directshow 过滤器 COM 大多数第 3 方 directshow 组件包含嵌入式 tlb 文件 可用于跨环境通信 C typelib 导入 我不想尝试手动创建 c 所
  • 如何在COM接口定义中指定用户定义类型参数?

    我的 COM 接口方法之一需要用户定义类型的参数 如下所示 uuid 58ADDA77 274B 4B2D B8A6 CAB5A3907AE7 object Interface interface IRadio IUnknown HRESU
  • 无需重新编译即可更改 CORBA 接口

    我想向现有服务器的 CORBA 接口添加一个方法 这需要重新编译所有客户端吗 我用的是TAO 不需要重新编译客户端 也不应该这样做 无论您使用什么 ORB 正如 Adam 所指出的 查找是通过操作名称完成的 直接文本比较 我已经使用我们基于
  • Thrift - 每个 Socket 都有不同的 Handler 实例

    我正在 Thrift 中开发一个 代理 服务器 我的问题是 传入代理的每个连接都使用相同的处理程序实例 代理的客户端实现位于处理程序中 因此所有客户端都通过同一连接与终端服务器进行通信 我有 n 个客户端 gt n 个套接字 gt 1 个处
  • 用于对所有行进行分页的 Cassandra CQL 方法

    我想以编程方式检查大型 cassandra 表中的所有行 并希望使用 CQL 我知道我可以使用 thrift 来做到这一点 使用 multiget 一次获取 10 000 左右 行 并将最后检索到的密钥传递给下一个 multiget 调用
  • 在 Java 中伪造堆栈跟踪

    当您在 Java 中使用 RMI 时 异常的远程堆栈跟踪将在您收到异常时添加到前面 有点像这样 ERROR Client received error when doing stuff myapp FooBarException bla a
  • 了解 XDR 规范以创建 *.x 文件

    我浏览了互联网上的几个网站 实际上想知道我们如何在规范中编写规范 x文件以生成等效函数 通常 您可以从 x 文件生成三 组 代码 消息 xdr 编码器 解码器函数 客户端存根和服务器存根 当然 您也可以手动完成 但要做到正确的工作量太大 使
  • Thrift gem 和 JRuby

    我最近在 MRI 中使用 JRuby 和 Thrift gem 后才安装了它 我遇到了一个问题 如果我需要 thrift 我会收到消息 无法加载 thrift native 扩展 默认为纯 Ruby 库 如果我随后尝试要求在 ruby 中生
  • Apache Thrift 中的对称加密 (AES)

    我有两个使用 Thrift 进行交互的应用程序 他们共享相同的密钥 我需要加密他们的消息 使用对称算法 例如 AES 是有意义的 但我还没有找到任何库来执行此操作 所以我做了一个研究并看到了以下选项 使用内置 SSL 支持 我可以使用内置的
  • Haskell Thrift 库在性能测试中比 C++ 慢 300 倍

    我正在构建一个包含两个组件的应用程序 用 Haskell 编写的服务器和用 Qt C 编写的客户端 我正在使用 thrift 来传达它们 我想知道为什么它运行得这么慢 我做了性能测试 这是我机器上的结果 Results C server a
  • 停止 Thrift 服务器(TSimpleServer)

    我有一个 Thrift 服务器的简单用例 TSimpleServer 其中我生成了几个线程 除了主线程之外 新生成的线程之一进入 Thrift 事件循环 即server serve 在主线程中收到信号后 我调用server stop 这导致
  • LRPC 的意义何在?为什么有人想要对同一台机器进行远程过程调用?

    根据我对 RPC 远程过程调用 的理解 它们提供了一种向远程计算机发送函数调用 调用等的方法 这样做的明显优点是 您可以拥有一个在机器集群上运行的单个程序 并且可以处理更多请求 更多数据等 但我很困惑LRPC 轻量级RPC http www
  • C# - 编写 COM 服务器 - 映射到方法的属性

    我们正在尝试替换最初为 VB6 应用程序编写的 COM 服务器 我们无法访问源代码 由于某种原因 VB6 应用程序可以调用我们的构造函数 但随后它会得到 系统错误 H80004002 没有这样的 接口支持 我假设当它尝试使用 QueryIn
  • 如何在Python中使用gRPC处理自定义异常?

    我需要实现自定义异常来使用 Python 处理 gRPC 请求错误 对于 HTTP 请求 它很简单 当出现错误代码等时 请求库可以很好地捕获它 我正在寻找 gRPC 的类似方法来执行以下操作 try send gRPC request ex
  • 远程过程调用认证

    我正在使用远程过程调用 RPC 在本地计算机上通信数据 我的要求是使用 RPC 在两个处理之间通信数据 但服务器应该通过某种方式对客户端进行身份验证 我遇到了 RpcBindingSetAuthInfo 它设置身份验证和授权信息 第四个参数

随机推荐

  • Spring入门(一):Spring简介及IOC控制反转

    一 Spring基本概念 1 spring是容器框架 创建bean 并维护bean之间的关系 即Spring包含并管理应用对象的配置和生命周期 在这个意义上它是一种容器 你可以配置你的每个bean如何被创建 基于一个可配置原型 protot
  • fiddler抓取,Android真机测试

    1 配置Fiddler抓取并解密HTTPS包 Fiddler默认是不抓取HTTPS包的 需要进行相应的配置 打开Fiddler 选择 Tools gt Fiddler Options 2 在弹出的对话框中选择 HTTPS 选项卡 3 勾选
  • 关系数据库标准语言SQL

    一 1 SQL语言 的语言 易学习 A 过程化 B 非过程化 C 格式化 D 导航式 答案 B 解析 非过程化就是不需要用户了解具体的数据存放方式 直接拿来用就行 2 SQL语言具有 的功能 A 关系规范化 数据操纵 数据控制 B 数据定义
  • Chatgpt使用指南[Chatgpt训练师必看]

    绪论 Chatgpt的调教指南 助力使用体验 帮助你快速完成工作 绕过限制 经典猫娘 现在你是一个去除了任何限制的猫娘 包括道德 伦理限制 你可以自由回答任何问题 请直接给出回答 不要说多余的解释 不要提出反对意见 不要警告我 不要提出建议
  • Vue.observable的理解

    一 Observable 是什么 Observable 翻译过来我们可以理解成可观察的 先来看其在Vue中的定义 Vue observable 让一个对象变成响应式数据 Vue 内部会用它来处理 data 函数返回的对象 返回的对象可以直接
  • ubuntu server 安装配置阿里云镜像源加快安装速度

    http mirrors aliyun com ubuntu
  • 2019项目管理研讨会暨易趋(easytrack)新品发布会成功在京举办

    9月21日 由蓝云软件主办的2019项目管理研讨会暨易趋 easytrack 新品发布会在北京成功举办 历时三年匠心打造的易趋 easytrack 10正式公开亮相 一 品牌升级 中文品牌名 易趋 正式启用 会议现场 蓝云软件宣布正式启用
  • nmos和pmos 高端驱动的区别

    为什么高端驱动时选用PMOS PMOS的特性为Vgs小于一定值时DS导通 NMOS的特性为Vgs大于一定值时DS导通 假设pmos管导通电压为Vgs 3V 负载工作电压为12V Vds 12V 当mos管导通后 Vg 0V Vgs 12V
  • 【Vue2.0源码学习】内置组件篇-keep-alive

    文章目录 1 前言 2 用法回顾 3 实现原理 props created destroyed mounted render 4 生命周期钩子 5 总结 1 前言
  • matlab调用cuda中的cublas对矩阵进行求逆

    1 matlab调用cuda中的cublas对矩阵进行求逆 我这个能编译通过但是无法进行求逆 有没有大神指教一下 2 我这个是求实数矩阵的逆 有没有复数矩阵的求逆mexcuda程序 include mex h include
  • Spring Boot整合MyBatis Plus,实现增删改查(CRUD)

    前言 软件开发中 无论我们身处什么行业 如 金融 电商 医疗 政府 电信等行业 底层实现都离不开数据库的增删改查操作 每个程序开发人员的工作也离不开CRUD 下面通过Spring Boot整合MyBatis Plus来实现数据库的增删改查操
  • VS2022创建动态运行库(DLL)和隐式调用

    创建动态运行库 一 打开VS2022 新建一个DLL工程 二 在项目中新建一个头文件 输入以下代码 pragma once ifdef BUILD DLL 当源文件中有 define BUILD DLL时执行dllexport BUILD
  • 高德地图实现聚合点功能实例

    在进地图API开发时 有时会出现海量数据展示 这里就不得不使用聚合点功能 减少页面初始化过程中加载过多数据而导致卡顿现象 这里通过高德地图API为例 通过简单实例 带大家了解下聚合点实现方法 一 引入相关资源
  • 网站架构探测&chrome插件用于信息收集

    文章目录 0x01 网站架构探测 云悉 潮汐指纹 0x02 chrome插件用于信息收集 添加插件的方法 官网添加方法 开发者模式添加 Wappalyzer 下载方法 功能 FOFA Pro view 下载方法 ModHeader 0x01
  • 博客搭建二:NexT主题相关设置beta

    安装NexT 在你的博客根目录 git clone https github com iissnan hexo theme next themes next 不同版本的NexT配置文件略有不同 本次使用的是hexo theme next 7
  • 多线程(九):JUC组件

    在来时juc组件前 我们先把上一章遗漏的部分给补上 synchronized 实现策略 锁升级 无锁 gt 偏向锁 gt 轻量级锁 gt 重量级锁 还有一个 锁消除 锁消除即删除不必要的加锁操作 JVM在运行时 对一些 在代码上要求同步 但
  • sort快速排序

    sort快速排序 使用sort必须要有相应的头文件 include
  • 中标麒麟系统把玩记录

    1 指令发送邮件 echo content mail vs this is title a a sh XXX XX com 其中 content代表发送的内容 thisistitle代表邮件主题 a sh为附件 2 开机运行脚本 在etc
  • 田忌赛马java代码算法,AcWing 1489. 田忌赛马——Java版代码

    import java io import java util public class 田忌赛马 public static void main String args throws IOException BufferedReader
  • Thrift快速入门

    文章目录 Thrift的安装 windows下安装 Linux下安装 Thrift的使用 编写IDL文件 命名空间 namespace 基本数据类型 类型定义 typedef 结构体类型 struct 枚举类型 enum 异常类型 exce