Thrift快速入门

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的同步处理。该方式是引入了线程池的。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值