`
gaozzsoft
  • 浏览: 411322 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类

Apache Thrift简介

 
阅读更多

Apache Thrift

Apache Thrift 是跨语言服务访问的框架。最早由Facebook 开发,贡献给了Apache。
通过接口定义语言(IDL),定义和创建服务,Thrift生成特定语言的可供server和client 访问的代码。
Thrfit 有着非常优秀的效率,无论是内存还是 传输效率上。

Cassandra 支持多种语言的编程接口,正式由于使用了Thrift。

架构

以上是创建server和client的stack。最上面的是IDL,然后生成Client和Processor。红色的是发送的数据。protocol和transport 是Thrift运行库的一部分。
通过Thrift 你只需要关心服务的定义,而不需要关心protocol和transport。

Thrift允许你选择 protocol ,transport和server。因为Thrift 最早是有C++开发的,Thrift在C++实现中有最大的变化。

Thrift支持 text 和 binary protocols,binary protocols要比text protocols,但是有时候 text protocols比较有用(例如:调试的时候)。支持的协议有:
TBinaryProtocol  -直接的二进制格式
TCompactProtocol  效率和高压缩编码数据
TDenseProtocoal  和TCompactProtocol相似,但是省略了meta信息,从哪里发送的,增加了receiver。还在实验中,java实现还不可用。
TJSONProtocoal 使用JSON
TSImpleJSONProtocoal  只写的protocol使用JSON。适合被脚本语言转化
TDebugProtocoal  使用人类可读的text 格式 帮助调试

上面的protocol 说明了 什么被传送,Thrift  transports 说明了怎样传送。支持的transport:
TSocket  使用 blocking socket I/O
TFramedTransport   以帧的形式发送,每帧前面是一个长度。要求服务器来non-blocking server
TFileTransport   写到文件。没有包括在java实现中。
TMemoryTransport   使用内存 I/O 。java实现中在内部使用了ByteArrayOutputStream
TZlibTransport 压缩 使用zlib。在java实现中还不可用

最后,thrift 提供了servers:
TSimpleServer  单线程 server,使用标准的blocking IO。用于测试
TThreadPoolServer  多线程  使用标准的blocking IO
TNonblockingServer  多线程  使用 non-blocking IO (java实现中使用了NIO channels)。TFramedTransport必须使用在这个服务器。

一个server只允许定义一个接口服务。这样的话多个接口需要多个server。这样会带来资源的浪费。同意通过继承接口的方式。

创建服务 
1创建user.thrift

Java代码
  1. namespace java thrift.demo.gen
  2. namespace py thrift.demo
  3. struct User{
  4.     1: i32 id,
  5.     2: string username,
  6.     3: string password
  7. }
  8. exception UserNotFound{
  9.     1:string message
  10. }
  11. service UserService{
  12.     list<User> getUsers(),
  13.     User getUserByName(1:string username) throws(1:UserNotFound unf)
  14. }

定义了一个User ,一个UerNotFound异常,一个UserService服务接口

 

服务定义主要使用了 类C的语法

Types

Thrift 定义的类型

base type:bool,byte,i16,i32,i64,double,string(UTF-8 编码)

binary

structs

Contains:list<type>,set<type>,map<type>

exception

services:包含了一组接口方法

 

注意定义的时候 序号是不可省略的,使用序号可以提升序列化和反序列对象的速度。

2.生成代码
命令行下执行
生成java代码

Java代码
  1. thrift-0.6.1.exe –gen java  user.thrift

生成python代码

Java代码
  1. thrift-0.6.1.exe –gen py user.thrift

3.实现服务端
3.1接口服务实现

Java代码
  1. package thrift.demo.server;
  2. import java.util.ArrayList;
  3. import java.util.List;
  4. import org.apache.thrift.TException;
  5. import thrift.demo.gen.User;
  6. import thrift.demo.gen.UserNotFound;
  7. import thrift.demo.gen.UserService.Iface;
  8. public class UserServiceHandler implements Iface {
  9.     @Override
  10.     public List<User> getUsers() throws TException {
  11.         List<User> list = new ArrayList<User>();
  12.         User user = new User();
  13.         user.setId(1);
  14.         user.setUsername(“user1″);
  15.         user.setPassword(“pwd1″);
  16.         list.add(user);
  17.         User user2 = new User();
  18.         user2.setId(1);
  19.         user2.setUsername(“user2″);
  20.         user2.setPassword(“pwd2″);
  21.         list.add(user2);
  22.         return list;
  23.     }
  24.     @Override
  25.     public User getUserByName(String username) throws UserNotFound, TException {
  26.         if (“user1″.equals(username)) {
  27.             User user = new User();
  28.             user.setId(1);
  29.             user.setUsername(“user1″);
  30.             user.setPassword(“pwd1″);
  31.             return user;
  32.         } else {
  33.             throw new UserNotFound();
  34.         }
  35.     }
  36. }

3.2 Server启动类

Java代码
  1. package thrift.demo.server;
  2. import org.apache.thrift.TProcessorFactory;
  3. import org.apache.thrift.protocol.TCompactProtocol;
  4. import org.apache.thrift.server.THsHaServer;
  5. import org.apache.thrift.server.TServer;
  6. import org.apache.thrift.transport.TFramedTransport;
  7. import org.apache.thrift.transport.TNonblockingServerSocket;
  8. import org.apache.thrift.transport.TTransportException;
  9. import thrift.demo.gen.UserService;
  10. public class UserServer {
  11.     public final static int PORT = 8989;
  12.     /**
  13.      * @param args
  14.      */
  15.     public static void main(String[] args) {
  16.         try {
  17.             TNonblockingServerSocket socket = new TNonblockingServerSocket(PORT);
  18.             final UserService.Processor processor = new UserService.Processor(
  19.                     new UserServiceHandler());
  20.             THsHaServer.Args arg = new THsHaServer.Args(socket);
  21.             arg.protocolFactory(new TCompactProtocol.Factory());
  22.             arg.transportFactory(new TFramedTransport.Factory());
  23.             arg.processorFactory(new TProcessorFactory(processor));
  24.             TServer server = new THsHaServer(arg);
  25.             server.serve();
  26.         } catch (TTransportException e) {
  27.             e.printStackTrace();
  28.         }
  29.     }
  30. }

4.实现客户端

Java代码
  1. package thrift.demo.client;
  2. import org.apache.thrift.TApplicationException;
  3. import org.apache.thrift.TException;
  4. import org.apache.thrift.protocol.TCompactProtocol;
  5. import org.apache.thrift.protocol.TProtocol;
  6. import org.apache.thrift.transport.TFramedTransport;
  7. import org.apache.thrift.transport.TSocket;
  8. import org.apache.thrift.transport.TTransport;
  9. import org.apache.thrift.transport.TTransportException;
  10. import thrift.demo.gen.UserNotFound;
  11. import thrift.demo.gen.UserService;
  12. public class UserClient {
  13.     public static void main(String[] arsg) {
  14.         String address = ”127.0.0.1″;
  15.         int port = 8989;
  16.         int clientTimeout = 30000;
  17.         TTransport transport = new TFramedTransport(new TSocket(address, port,
  18.                 clientTimeout));
  19.         TProtocol protocol = new TCompactProtocol(transport);
  20.         UserService.Client client = new UserService.Client(protocol);
  21.         try {
  22.             transport.open();
  23.             System.out.println(client.getUserByName(“user1″));
  24.         } catch (TApplicationException e) {
  25.             System.out.println(e.getMessage() + ” ” + e.getType());
  26.         } catch (TTransportException e) {
  27.             e.printStackTrace();
  28.         } catch (UserNotFound e) {
  29.             e.printStackTrace();
  30.         } catch (TException e) {
  31.             e.printStackTrace();
  32.         }
  33.         transport.close();
  34.     }
  35. }

注意 客户端和服务端要使用同一中 Protocol 和 Transport,否则会抛出异常

参考:

http://incubator.apache.org/thrift/

http://wiki.apache.org/thrift/FrontPage

http://www.cnblogs.com/end/archive/2011/04/12/2013805.html

http://jnb.ociweb.com/jnb/jnbJun2009.html 非常好的入门教程

http://developers.facebook.com/thrift/thrift-20070401.pdf thrift开发者写的论文

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics