Thrift 是Fackbook推出的一个跨语言通讯框架,相比常用的以json为载体的rest http方式来说,性能上更加优越。另外Thrift集成了RPC(Remote Procedure Call Protocol)的实现,比同类型的产品Protobuf 功能要更全面。
安装和镜像源
以Ubuntu14.04为例,首先安装Thrift所需要的软件。
1 sudo apt-get install libboost-dev libboost-test-dev libboost-program-options-dev libboost-system-dev libboost-filesystem-dev libevent-dev automake libtool flex bison pkg-config g++ libssl-dev
接着安装对应语言的编译器,以Java为例,需要安装JDK和Ant,顺便把Maven也装上。
1 sudo apt-get install openjdk-7-jdk ant maven
下载Thrift的包,最新的版本是0.9.2,但不知道什么原因,0.9.2版本安装会有问题,退一个版本就OK了,我们安装0.9.1版本。
1 2 3 4 5 6 wget http://apache.fayea.com/thrift/0.9.1/thrift-0.9.1.tar.gz tar -zxvf thrift-0.9.1.tar.gz cd thrift-0.9.1sudo ./configure --without-testssudo makesudo make install
1 2 $ thrift --version Thrift version 0.9.1
如果嫌安装比较麻烦,也可以使用下面Vagrant或者Docker的Thrift镜像。
接口定义 安装完成Thrift之后,我们来编写一个thrift文件,定义服务端的接口。
hello.thrift 1 2 3 4 5 6 7 8 namespace java service.demo service Hello{ string helloString (1 :string para) i32 helloInt (1 :i32 para) bool helloBoolean (1 :bool para) void helloVoid () string helloNull () }
可以看到我们定义了5个不同的接口,接着使用Thrift对文件进行编译,产生对应语言的程序文件,下面以Java为例。
1 thrift —gen java hello.thrift
命令执行完成后,会生成一个Hello.java的文件。
接口实现 前面只是定义了接口的签名,现在我们来对接口进行实现,实现类需要实现Hello.Iface,代码如下:
HelloServiceImpl 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 package service.demo;import org.apache.thrift.TException;public class HelloServiceImpl implements Hello .Iface { @Override public boolean helloBoolean (boolean para) throws TException { System.out.printf("hello true/false" ); return para; } @Override public int helloInt (int para) throws TException { System.out.println("hello times: " + para); return para; } @Override public String helloNull () throws TException { System.out.println("hello null" ); return null ; } @Override public String helloString (String para) throws TException { System.out.println("hello " + para); return para; } @Override public void helloVoid () throws TException { System.out.println("Hello World" ); } }
服务端代码的实现 接着我们来编写我们的服务器代码:
HelloServiceImpl 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 package service.server;import org.apache.thrift.TProcessor;import org.apache.thrift.server.TServer;import org.apache.thrift.server.TThreadPoolServer;import org.apache.thrift.transport.TServerSocket;import org.apache.thrift.transport.TTransportException;import service.demo.Hello;import service.demo.HelloServiceImpl;public class HelloServiceServer { public static void main (String[] args) { try { TServerSocket serverTransport = new TServerSocket (9527 ); TProcessor processor = new Hello .Processor(new HelloServiceImpl ()); TServer server = new TThreadPoolServer (new TThreadPoolServer .Args(serverTransport).processor(processor)); System.out.println("Start server on port 9527..." ); server.serve(); } catch (TTransportException e) { e.printStackTrace(); } } }
客户端代码的实现 最后来完成我们的客户端代码,客户端我们也是用Java来实现。
HelloServiceImpl 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 package service.client;import org.apache.thrift.TException;import org.apache.thrift.protocol.TBinaryProtocol;import org.apache.thrift.protocol.TProtocol;import org.apache.thrift.transport.TSocket;import org.apache.thrift.transport.TTransport;import org.apache.thrift.transport.TTransportException;import service.demo.Hello;public class HelloServiceClient { public static void main (String[] args) { try { TTransport transport = new TSocket ("localhost" , 9527 ); transport.open(); TProtocol protocol = new TBinaryProtocol (transport); Hello.Client client = new Hello .Client(protocol); client.helloVoid(); transport.close(); } catch (TTransportException e) { e.printStackTrace(); } catch (TException e) { e.printStackTrace(); } } }
代码完成后,可以先运行HelloServiceServer的main方式,然后再运行HelloServiceClient的main方法,可以在HelloServiceServer的输出结果中看到客户端打印的Hello World
字样。
部署 参考了一些资料后,决定使用Jar包来启动thrift服务,并使用Supervisor 来进行进程的监控和自动重启,下面是supervisor的配置文件,里面配置了我们的thrift程序。
/etc/supervisord.conf 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 [program:thrift] command =/usr/bin/java -jar /home/vagrant/thrift-hello/demo.jarstderr_logfile=/home/vagrant/logs/err.log stdout_logfile=/home/vagrant/logs/out.log autostart=true [unix_http_server] file = /tmp/supervisor.sock chmod = 0777chown = nobody:nogroup[inet_http_server] port = 127.0.0.1:9001 [supervisord] logfile = /tmp/supervisord.log logfile_maxbytes = 50MB logfile_backups=10 loglevel = info pidfile = /tmp/supervisord.pid nodaemon = false [supervisorctl] serverurl = unix:///tmp/supervisor.sock [rpcinterface:supervisor] supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface
参考资料: http://stackoverflow.com/questions/17639442/deploy-and-serve-a-thrift-server