Thrift入门及Java实例演示

目录:

  • 概述
  • 下载配置
  • 基本概念
    1. 数据类型
    2. 服务端编码基本步骤
    3. 客户端编码基本步骤
    4. 数据传输协议
  • 实例演示(java)
    1.  thrift生成代码
    2.  实现接口Iface
    3. TSimpleServer服务模型
    4. TThreadPoolServer 服务模型
    5. TNonblockingServer 服务模型
    6. THsHaServer服务模型
    7. 异步客户端

[一]、概述

Thrift是一个软件框架,用来进行可扩展且跨语言的服务的开发。它结合了功能强大的软件堆栈和代码生成引擎,以构建在 C++, Java, Python, PHP, Ruby, Erlang, Perl, Haskell, C#, Cocoa, JavaScript, Node.js, Smalltalk, and OCaml 等等编程语言间无缝结合的、高效的服务。

Thrift最初由facebook开发,07年四月开放源码,08年5月进入apache孵化器。thrift允许你定义一个简单的定义文件中的数据类型和服务接口。以作为输入文件,编译器生成代码用来方便地生成RPC客户端和服务器通信的无缝跨编程语言。

官网地址:thrift.apache.org

推荐值得一看的文章:

[二]、下载配置

到官网下载最新版本,截止今日(2012-06-11)最新版本为0.8.0.

1. 如果是Maven构建项目的,直接在pom.xml 中添加如下内容:

2.如果自己编译lib包,把下载的压缩包解压到X:盘,然后在X:\thrift-0.8.0\lib\java 目录下运行ant进行自动编译,会在X:\thrift-0.8.0\lib\java\build\ 目录下看到编译好的lib包:libthrift-0.8.0.jar

[三]、基本概念

1.数据类型

  • 基本类型:
    • bool:布尔值,true 或 false,对应 Java 的 boolean
    • byte:8 位有符号整数,对应 Java 的 byte
    • i16:16 位有符号整数,对应 Java 的 short
    • i32:32 位有符号整数,对应 Java 的 int
    • i64:64 位有符号整数,对应 Java 的 long
    • double:64 位浮点数,对应 Java 的 double
    • string:utf-8编码的字符串,对应 Java 的 String
  • 结构体类型:
    • struct:定义公共的对象,类似于 C 语言中的结构体定义,在 Java 中是一个 JavaBean
  • 容器类型:
    • list:对应 Java 的 ArrayList
    • set:对应 Java 的 HashSet
    • map:对应 Java 的 HashMap
  • 异常类型:
    • exception:对应 Java 的 Exception
  • 服务类型:
    • service:对应服务的类

2.服务端编码基本步骤:

  • 实现服务处理接口impl
  • 创建TProcessor
  • 创建TServerTransport
  • 创建TProtocol
  • 创建TServer
  • 启动Server

3.客户端编码基本步骤:

  • 创建Transport
  • 创建TProtocol
  • 基于TTransport和TProtocol创建 Client
  • 调用Client的相应方法

4.数据传输协议

  • TBinaryProtocol : 二进制格式.
  • TCompactProtocol : 压缩格式
  • TJSONProtocol : JSON格式
  • TSimpleJSONProtocol : 提供JSON只写协议, 生成的文件很容易通过脚本语言解析

tips:客户端和服务端的协议要一致

[四]、实例演示

1. thrift生成代码

创建Thrift文件:G:\test\thrift\demoHello.thrift ,内容如下:

目录结构如下:

thrift-0.8.0.exe 是官网提供的windows下编译工具,运用这个工具生成相关代码:

生成后的目录结构如下:

将生成的HelloWorldService.java 文件copy到自己测试的工程中,我的工程是用maven构建的,故在pom.xml中增加如下内容:

2. 实现接口Iface

java代码:HelloWorldImpl.java

3.TSimpleServer服务端

简单的单线程服务模型,一般用于测试。

编写服务端server代码:HelloServerDemo.java

编写客户端Client代码:HelloClientDemo.java

先运行服务端程序,日志如下:

再运行客户端调用程序,日志如下:

测试成功,和预期的返回信息一致。

4.TThreadPoolServer 服务模型

线程池服务模型,使用标准的阻塞式IO,预先创建一组线程处理请求。

编写服务端代码:HelloServerDemo.java

客户端Client代码和之前的一样,只要数据传输的协议一致即可,客户端测试成功,结果如下:

5.TNonblockingServer 服务模型

使用非阻塞式IO,服务端和客户端需要指定 TFramedTransport 数据传输的方式。

编写服务端代码:HelloServerDemo.java

编写客户端代码:HelloClientDemo.java

客户端的测试成功,结果如下:

6.THsHaServer服务模型

半同步半异步的服务端模型,需要指定为: TFramedTransport 数据传输的方式。

编写服务端代码:HelloServerDemo.java

客户端代码和上面 4 中的类似,只要注意传输协议一致以及指定传输方式为TFramedTransport

7.异步客户端

编写服务端代码:HelloServerDemo.java

编写客户端Client代码:HelloAsynClientDemo.java

先运行服务程序,再运行客户端程序,测试结果如下:

————

原创文章,转载请注明: 转载自micmiu – 软件开发+生活点滴[ http://www.micmiu.com/ ]

本文链接地址: http://www.micmiu.com/soa/rpc/thrift-sample/

发表评论?

30 条评论。

  1. 请问你的大于 小于用&lt &gt ; 而不直接用呢

  2. 对nifty有研究么?几乎木有什么资料。。。抓狂ing…

  3. 非常好,最近项目中应用到Thrift。学习了,程序也可以跑起来!

  4. 非常不错,刚刚接触这个东西。看了博主的文章懂了些基础的东西。感谢

  5. 使用 thrift 工具生成的java 文件加载到项目中提示出现大量的:
    Error:(383, 20) java: service.demo.Hello.Processor.helloString不是抽象的, 并且未覆盖org.apache.thrift.ProcessFunction中的抽象方法isOneway()
    错误信息。 请教楼主怎么破?

  6. 楼主用的eclispe么,什么主题啊,挺好看的

  7. 请教下博主 用半异步半同步的时候 我开启了多个服务每个都指定了一个端口号 然后 客户端链接的时候 一到执行实现服务接口的方法时就客户端保持了。。既不往下运行也不停止。。。。 可能是什么原因造成的呢。。谢谢啦!

  8. 博主你好,7的代码和5的代码有什么区别呢?

  9. 博主你好,文章非常有用
    就是在最后一个例子,我的异步客户端输出如下:
    Client start …..
    call method sayHello start …
    call method sayHello …. end
    latch.await =:false
    startClient end.

    没有获得和您一样的结果,大约是什么原因呢?感谢

  10. 博主你好,文章非常有用
    就是在最后一个例子,我的异步客户端输出如下:

  11. 请问 Thrift的数据 是如何进行传递的
    和普通的WebService的区别仅在于 WS传递的是XML 而Thrift传递的是thrift包?
    thrift的封包解包和WS的有什么区别
    为什么thrift比用CXF实现的WS要快(PS.我自己做了个实验,前者的耗时大概是后者的1/3到1/10)

  12. 非常感谢!受益匪浅!
    您给出的例子都是java通信的,那如果我想用java调用nodejs或者nodejs调用java该怎么写呢?有类似的例子吗?

  13. 请问在服务端有遇到过这种情况么?
    Thrift error occurred during processing of message.
    org.apache.thrift.TException: Message length exceeded: 2
    at org.apache.thrift.protocol.TBinaryProtocol.checkReadLength(TBinaryProtocol.java:393)
    at org.apache.thrift.protocol.TBinaryProtocol.readAll(TBinaryProtocol.java:377)
    at org.apache.thrift.protocol.TBinaryProtocol.readI16(TBinaryProtocol.java:278)
    at org.apache.thrift.protocol.TBinaryProtocol.readFieldBegin(TBinaryProtocol.java:229)

  14. 请教一个问题
    假如有2个service 如
    HelloWorldService1
    HelloWorldService2.

    那么server端的code 如何写
    System.out.println(“HelloWorld TNonblockingServer start ….”);
    22

    23
    TProcessor tprocessor = new HelloWorldService.Processor(
    24
    new HelloWorldImpl());
    25

    26
    TNonblockingServerSocket tnbSocketTransport = new TNonblockingServerSocket(
    27
    SERVER_PORT);
    28
    TNonblockingServer.Args tnbArgs = new TNonblockingServer.Args(
    29
    tnbSocketTransport);
    30
    tnbArgs.processor(tprocessor);
    31
    tnbArgs.transportFactory(new TFramedTransport.Factory());
    32
    tnbArgs.protocolFactory(new TCompactProtocol.Factory());
    TServer server = new THsHaServer(thhsArgs);
    40
    server.serve();

    这段代码是把 HelloWorldService 启动了 ,如何还想启动一个service 怎么办?

    谢谢赐教!

  15. 可以啦接着看下去,呵呵。thank u

  16. 生成代码具体是怎么实现的啊?看不明白 :cry:

  17. 非常感谢

发表评论


注意 - 你可以用以下 HTML tags and attributes:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code class="" title="" data-url=""> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre class="" title="" data-url=""> <span class="" title="" data-url="">