原创  Apache Thrift学习小记 收藏

参考:

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

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

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

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

Thrift是个啥东东?

来自wiki.apache.org/thrift/FrontPage的定义

Thrift is a software framework for scalable cross-language services development. 

Thrift是为了实现跨语言服务访问的一个框架

Thrift allows you to define data types and service interfaces in a simple definition file.

Thrift定义了数据和服务的描述方式,是一种IDL

Taking that file as input, the compiler generates code to be used to easily build RPC clients and servers that communicate seamlessly across programming languages.

写一个定义文件,就可以使用thrift来生成某种语言RPC客户端和服务端程序框架。你只需要考虑如何实现你的服务就可以了。并且它支持很多种语言。

这有点像web service, 定义好一个web service服务描述文件后,可以使用如axis等工具生成服务器端或客户端的框架程序。

为什么还需要Thrift

thrift-20070401.pdf中有解释。

1、多语言开发的需要

比如其中提到的搜索服务,LAMP本身没有这个功能,开发者可能使用C++开发,php如何访问这个服务呢?于是需要有一种高效的跨语言访问的方法。

2、性能问题

web service也可以实现多语言互访问的功能,但xml文件太大,性能不行。Thrift可以使用二进值的格式。

开始测试

实现一个简单的服务,就是根据loginName得到User, user中有userId,loginName, name, password

第一步,写Thrift IDL文件 ,user.thrift,

  1. namespace java mytest.thrift.gen  
  2. namespace py mytest.thrift  
  3. struct User {  
  4.   1: i32    userId,  
  5.   2: string loginName,  
  6.   3: string password,  
  7.   4: string name  
  8. }  
  9. exception UserNotFound {  
  10.   1: string message  
  11. }  
  12. service UserService {  
  13.   User getUser(1:string loginName) throws (1:UserNotFound unf),  
  14.   list<User> getUsers()  
  15. }  
 

第二步,生成java和python代码

thrift --gen java user.thrift

thrift --gen py user.thrift

第三步,实现java服务端

参见:http://wiki.apache.org/thrift/ThriftUsageJava

服务实现 UserServiceHandler.java

  1. package myserver;  
  2. import java.util.ArrayList;  
  3. import java.util.List;  
  4. import mytest.thrift.gen.User;  
  5. import mytest.thrift.gen.UserNotFound;  
  6. import mytest.thrift.gen.UserService;  
  7. import org.apache.thrift.TException;  
  8. public class UserServiceHandler implements UserService.Iface {  
  9.     @Override  
  10.     public User getUser(String loginName) throws UserNotFound, TException {  
  11.         if (!"login1".equals(loginName)) {  
  12.             UserNotFound e = new UserNotFound("User not Found!");  
  13.             throw e;  
  14.         }  
  15.         User user = new User();  
  16.         user.setUserId(100);  
  17.         user.setLoginName("login1");  
  18.         user.setPassword("pwd1");  
  19.         user.setName("user1");  
  20.         return user;  
  21.     }  
  22.     @Override  
  23.     public List<User> getUsers() throws TException {  
  24.         List<User> list = new ArrayList<User>();  
  25.         User user = new User();  
  26.         user.setUserId(100);  
  27.         user.setLoginName("login1");  
  28.         user.setPassword("pwd1");  
  29.         user.setName("user1");  
  30.         list.add(user);  
  31.         User user2 = new User();  
  32.         user2.setUserId(200);  
  33.         user2.setLoginName("login2");  
  34.         user2.setPassword("pwd2");  
  35.         user2.setName("user2");  
  36.         list.add(user2);  
  37.         return list;  
  38.     }  
  39. }  
 

主程序 Server.java

  1. package myserver;  
  2. import mytest.thrift.gen.UserService;  
  3. import org.apache.thrift.server.TServer;  
  4. import org.apache.thrift.server.TSimpleServer;  
  5. import org.apache.thrift.transport.TServerSocket;  
  6. import org.apache.thrift.transport.TServerTransport;  
  7. public class Server {  
  8.     public static void main(String[] args) {  
  9.         try {  
  10.             UserServiceHandler handler = new UserServiceHandler();  
  11.             UserService.Processor processor = new UserService.Processor(handler);  
  12.             TServerTransport serverTransport = new TServerSocket(9090);  
  13.             TServer server = new TSimpleServer(processor, serverTransport);  
  14.             // Use this for a multithreaded server  
  15.             // server = new TThreadPoolServer(processor, serverTransport);  
  16.             System.out.println("Starting the server...");  
  17.             server.serve();  
  18.         } catch (Exception x) {  
  19.             x.printStackTrace();  
  20.         }  
  21.         System.out.println("done.");  
  22.     }  
  23. }  
 

第四步,实现java客户端

  1. package myclient;  
  2. import java.util.Iterator;  
  3. import java.util.List;  
  4. import mytest.thrift.gen.User;  
  5. import mytest.thrift.gen.UserNotFound;  
  6. import mytest.thrift.gen.UserService;  
  7. import org.apache.thrift.TException;  
  8. import org.apache.thrift.protocol.TBinaryProtocol;  
  9. import org.apache.thrift.protocol.TProtocol;  
  10. import org.apache.thrift.transport.TSocket;  
  11. import org.apache.thrift.transport.TTransport;  
  12. public class Client {  
  13.     public static void main(String[] args) {  
  14.         try {  
  15.             TTransport transport = new TSocket("localhost", 9090);  
  16.             TProtocol protocol = new TBinaryProtocol(transport);  
  17.             UserService.Client client = new UserService.Client(protocol);  
  18.             transport.open();  
  19.             System.out.println("test1");  
  20.             try {  
  21.                 User user1 = client.getUser("login1");  
  22.                 System.out.println("name=" + user1.getName());  
  23.             } catch (UserNotFound e) {  
  24.                 System.out.println(e.getMessage());  
  25.             }  
  26.               
  27.             System.out.println("test2");  
  28.             try {  
  29.                 User user2 = client.getUser("login10");  
  30.                 System.out.println("name=" + user2.getName());  
  31.             } catch (UserNotFound e) {  
  32.                 System.out.println(e.getMessage());  
  33.             }  
  34.               
  35.             System.out.println("test3");  
  36.             List<User> list = client.getUsers();  
  37.             Iterator<User> it = list.iterator();  
  38.             while(it.hasNext()){  
  39.                 User u = it.next();  
  40.                 System.out.println("name=" + u.getName());  
  41.             }  
  42.             transport.close();  
  43.         } catch (TException x) {  
  44.             x.printStackTrace();  
  45.         }  
  46.     }  
  47. }  
 


第五步,实现python客户端
  1. from mytest.thrift import UserService  
  2. from mytest.thrift.ttypes import UserNotFound  
  3. from thrift import Thrift  
  4. from thrift.transport import TSocket  
  5. from thrift.transport import TTransport  
  6. from thrift.protocol import TBinaryProtocol  
  7. try:  
  8.     # Make socket  
  9.     transport = TSocket.TSocket('localhost', 9090)  
  10.     # Buffering is critical. Raw sockets are very slow  
  11.     transport = TTransport.TBufferedTransport(transport)  
  12.     # Wrap in a protocol  
  13.     protocol = TBinaryProtocol.TBinaryProtocol(transport)  
  14.     # Create a client to use the protocol encoder  
  15.     client = UserService.Client(protocol)  
  16.     # Connect!  
  17.     transport.open()  
  18.     try:    
  19.         user1 = client.getUser("login1")  
  20.         print user1.name  
  21.     except UserNotFound, io:  
  22.         print '%r' % io  
  23.     # Close!  
  24.     transport.close()  
  25. except Thrift.TException, tx:  
  26.     print '%s' % (tx.message) 
posted on 2011-04-12 16:17  风生水起  阅读(5216)  评论(0编辑  收藏  举报