Thrift是一个facebook开源的高效RPC框架,其主要特点是跨语言及二进制高效传输(除了二进制,也支持json等常用序列化机制),官网地址:http://thrift.apache.org

跨语言通常有二种做法,

一是将其它语言转换成某种主流的通用语言,比如:delphi.net以前就是先将delphi转换成c#,然后再编译成IL,从而实现delphi在.net上的运行(好久没关注delphi了,不知道现在还是不是这种机制)

二是先定义一种规范文件(可以简单的理解为『母版』),然后由特定的编译器,将『母版』直接编译成目标语言的源代码。

thrift走的是第二条路,使用thrift框架时,先定义名为.thrift后缀的文件,然后由thrift编译器编译成指定语言的源文件,然后借助thrift提供的各种语言的实现lib库,完成rpc的调用。

一、thrift编译器的安装

1.1、windows 安装

http://thrift.apache.org/docs/install/windows 这是官网的windows安装指导说明,windows的安装其实最简单

Thrift compiler for Windows (thrift-0.9.2.exe)

thrift-0.9.2.tar.gz

下载这二个文件即可,第1个是编译器,第2个压缩包里包括了种示例代码。把thrift-0.9.2.exe保存到某个目录,比如:c:\thrift下,然后将thrift-0.9.2.exe改个简单的名字,比如:thrift.exe(这一步非必须),最后在环境变量的path路径里,把c:\thrift加上,保证Command窗口下,键入thrift能找到该文件即可。

1.2、centos 安装

http://thrift.apache.org/docs/install/centos 参考这个安装,上面的详细的命令,按上面的命令一步步来就行了,主要过程是先安装一堆依赖的工具,然后

git clone https://git-wip-us.apache.org/repos/asf/thrift.git

将thrift源代码拉到本地,再build,生成thrift编译器

1.3、mac osx 安装

http://thrift.apache.org/docs/install/os_x 参考这里,大概步骤跟centos差不多,相信大家都能搞定,唯一要注意的是,mac os上没有yum之类的工具,建议使用brew 工具安装

二、thrift文件的定义

从git拉回来的源代码tutorial目录下,有二个示例文件:shared.thrift及tutorial.thrift,大家可以打开看看,演示了主要用法,但我觉得还是有些小复杂,初学者一眼看上去有些乱,我按服务开发的常规场景,自己弄了二个小demo:

首先定义要传输的dto对象

dto.thrift

 
namespace java yjmyzz.thrift.study.dto
namespace csharp yjmyzz.thrift.study.dto //Person类
struct Person {
1: i16 age = 0,
2: string name,
3: bool sex,
4: double salary,
5: byte childrenCount
} //查询参数
struct QueryParameter{
1: i16 ageStart,
2: i16 ageEnd
}
 

这里定义了二个类,一个是Person类,一个是查询的参数对象类,最上面的namespace即为最终java, c#里的package及namespace

再定义服务接口service.thrift

 
namespace java yjmyzz.thrift.study.service
namespace csharp yjmyzz.thrift.study.service include "dto.thrift" //服务
service DemoService { //用于检测client-server之间通讯是否正常
string ping(), list<dto.Person> getPersonList(1:dto.QueryParameter parameter) }
 

实际开发中,建议大家使用intellij idea,其thrift插件可以支持高亮语法和代码智能提示,如下图:

三、client及server端项目开发

如果大家使用过hessian、dubbo之类的框架,相信对于服务开发这一类套路都很熟悉,通常会拆分成3部分,接口定义(也称服务&数据契约 contract)、服务生产方(即:server端)、服务消费方(即:client端),按这一思路,创建三个module,项目结构见下图:

其中thrift-contract即为公用的接口部分,thrift-client为客户端,thrift-server为服务端,注意:dto.thrift及service.thrift这二个文件,我放在了thrift-contract\src\thrift这个目录下。

3.1 生成目标语言源文件

架势拉好了,开始干活,命令行下先进入thrift-contract\src\thrift所在目录,

thrift -gen java dto.thrift

thrift -gen java service.thrift

这样就把二个thrift【母版】文件生成了对应的java代码,生成的源文件会存放在当前工作目录的gen-java下,如果把-gen java换成-gen csharp就会生成c#代码。

上图是生成后的源代码结构,由于src\thrift目录并不是maven工程约定的源代码目录,手动把gen-java下生成的整个目录,复制到src/main/java下即可。

3.2 maven中pom.xml依赖荐的添加

 
 1     <dependencies>
2 <dependency>
3 <groupId>org.apache.thrift</groupId>
4 <artifactId>libthrift</artifactId>
5 <version>0.9.2</version>
6 </dependency>
7
8 <dependency>
9 <groupId>org.slf4j</groupId>
10 <artifactId>slf4j-log4j12</artifactId>
11 <version>1.5.8</version>
12 </dependency>
13 </dependencies>
 

libthrift这一项是必须要添加的,slf4j-log4j12对于接口定义来讲,可以不用(但最终在server\client端运行时,这个包不可少)。然后就可以用 mvn clean install 来生成jar包并安装到本机maven仓库中了,注意这里有一个小问题:

thrift生成的java源代码中,@Override这个注解有些地方添加得不对(比如:实现接口时,实现类中是不需要添加这一注解的),编译时如果出现错误,直接去掉即可,建议:将生成的java源文件,全局替换,把@Override全干掉。

3.3 server端的接口实现

thrift-contract只是生成了服务的接口定义,并未提供实现,下面是DemoService的实现

 
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
35
package yjmyzz.thrift.study;
 
import org.apache.thrift.TException;
import yjmyzz.thrift.study.dto.Person;
import yjmyzz.thrift.study.dto.QueryParameter;
import yjmyzz.thrift.study.service.DemoService;
 
import java.util.ArrayList;
import java.util.List;
 
 
public class DemoServiceImpl implements DemoService.Iface {
 
 
    public String ping() throws TException {
        System.out.println("ping()");
        return "pong";
    }
 
    public List<Person> getPersonList(QueryParameter parameter) throws TException {
        //System.out.println(parameter.getAgeStart() + " - " + parameter.getAgeEnd());
 
        List<Person> list = new ArrayList<Person>(10);
        for (short i = 0; i < 10; i++) {
            Person p = new Person();
            p.setAge(i);
            p.setChildrenCount(Byte.valueOf(i + ""));
            p.setName("test" + i);
            p.setSalary(10000D);
            p.setSex(true);
            list.add(p);
        }
        return list;
    }
}

这里随便返回一堆数据,意思一下而已,注:server端的pom.xml中,记得添加接口层的依赖项引用

 
 1     <dependencies>
2
3 <dependency>
4 <groupId>yjmyzz</groupId>
5 <artifactId>thrift-contract</artifactId>
6 <version>1.0</version>
7 </dependency>
8
9 <dependency>
10 <groupId>org.apache.thrift</groupId>
11 <artifactId>libthrift</artifactId>
12 <version>0.9.2</version>
13 </dependency>
14
15 <dependency>
16 <groupId>org.slf4j</groupId>
17 <artifactId>slf4j-log4j12</artifactId>
18 <version>1.5.8</version>
19 </dependency>
20 </dependencies>

3.4 server的启动

 
 1 package yjmyzz.thrift.study;
2
3
4 import org.apache.thrift.server.TServer;
5 import org.apache.thrift.server.TServer.Args;
6 import org.apache.thrift.server.TSimpleServer;
7 import org.apache.thrift.transport.TServerSocket;
8 import org.apache.thrift.transport.TServerTransport;
9 import yjmyzz.thrift.study.service.DemoService;
10
11
12 public class ThriftServer {
13
14 public static DemoService.Iface service;
15
16 public static DemoService.Processor processor;
17
18 public static void main(String[] args) {
19 try {
20 service = new DemoServiceImpl();
21 processor = new DemoService.Processor(service);
22
23 Runnable simple = new Runnable() {
24 public void run() {
25 simple(processor);
26 }
27 };
28 new Thread(simple).start();
29
30 } catch (Exception x) {
31 x.printStackTrace();
32 }
33 }
34
35 public static void simple(DemoService.Processor processor) {
36 try {
37 TServerTransport serverTransport = new TServerSocket(9090);
38 TServer server = new TSimpleServer(new Args(serverTransport).processor(processor));
39 System.out.println("Starting the simple server...");
40 server.serve();
41 } catch (Exception e) {
42 e.printStackTrace();
43 }
44 }
45
46
47 }
 

这里监听9090端口,响应client的调用请求。

3.5 client调用示例

 
 1 package yjmyzz.thrift.study;
2
3 import org.apache.thrift.TException;
4 import org.apache.thrift.protocol.TBinaryProtocol;
5 import org.apache.thrift.protocol.TProtocol;
6 import org.apache.thrift.transport.TSocket;
7 import org.apache.thrift.transport.TTransport;
8 import yjmyzz.thrift.study.dto.QueryParameter;
9 import yjmyzz.thrift.study.service.DemoService;
10
11 public class ThriftClient {
12
13 public static void main(String[] args) {
14
15 try {
16 TTransport transport;
17 transport = new TSocket("localhost", 9090);
18 transport.open();
19
20 TProtocol protocol = new TBinaryProtocol(transport);
21 DemoService.Client client = new DemoService.Client(protocol);
22
23 System.out.println(client.ping());
24
25 int max = 100000;
26
27 Long start = System.currentTimeMillis();
28
29 for (int i = 0; i < max; i++) {
30 call(client);
31 }
32
33 Long end = System.currentTimeMillis();
34
35 Long elapse = end - start;
36
37 int perform = Double.valueOf(max / (elapse / 1000d)).intValue();
38
39 System.out.print("thrift " + max + " 次RPC调用,耗时:" + elapse + "毫秒,平均" + perform + "次/秒");
40
41 transport.close();
42
43 } catch (TException x) {
44 x.printStackTrace();
45 }
46 }
47
48 private static void call(DemoService.Client client) throws TException {
49
50 //client.ping();
51 //System.out.println("ping()=>" + client.ping());
52
53 QueryParameter parameter = new QueryParameter();
54 parameter.setAgeStart(Short.valueOf("5"));
55 parameter.setAgeEnd(Short.valueOf("50"));
56
57 client.getPersonList(parameter);
58 //System.out.println(client.getPersonList(parameter));
59 }
60 }
 

在我mac老爷本(2011年买的)上测试出来的结果,而且server使用的SimpleServer同步阻塞模式,如果采用多线程非阻塞模式,在服务器上性能相信至少还能翻N倍不成问题:

thrift 100000 次RPC调用,耗时:7774毫秒,平均12863次/秒

即使按这个结果来估算,1秒至少处理1w次,1小时3600秒就是3.6kw次,1天24小时,每天处理上亿次调用毫无压力,相信已经能满足很多公司的要求了。而且thrift出来很多年了,相对比较成熟,如果项目是异构系统,要兼容多种语言之间的相互调用,thrift是不错的选择。

但最后也提醒一下,thrift虽然跨语言不假,但是在不同语言的实现上,性能相差甚远,上面的示例client、server都是采用java开发,如果把server换成c#,结果就惨不忍睹了(相差几个数量级),大家可以自行测试,建议实际项目中,至少server端使用java语言(或c++)开发。

另外在使用上,有一些小限制:一个Server只能对应一个Service接口,也就是说,如果有多个服务,要么融合成一个大接口,要么启多个server(对应多个端口)

参见:http://www.cnblogs.com/yjmyzz/p/thrift-hello-world.html

http://www.cnblogs.com/yjmyzz/p/thrift-classname-independent.html

http://www.cnblogs.com/tianhuilove/archive/2011/09/05/2167669.html

http://www.cnblogs.com/yjmyzz/p/4823082.html

Windows Thrift安装及HelloWorld的更多相关文章

  1. Redhat/Ubuntu/Windows下安装Docker

    Redhat/Ubuntu/Windows下安装Docker 什么是Docker Docker是Docker.inc公司开源的一个基于LXC技术之上构建的Container容器引擎,基于Go语言并遵从 ...

  2. windows下安装git & 在git@OSC上推送代码

    第一部分 windows下安装git 1.下载最新版本的git:直接百度“git”,如图所示,点击立即下载. 也可以直接在官网下载最新版本的git:http://www.git-scm.com/dow ...

  3. NodeJs在windows上安装配置测试

    Node.js简介简单的说 Node.js 就是运行在服务端的 JavaScript.Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行环境.Node.js 使用了一个 ...

  4. Mac上brew&thrift安装 以及在thrift架构下,自己新作了maven的小例 Demo

    1.缘由 前几天偶尔在网上看到thrift的信息,其内容和作用极大的引起了我的兴趣,因为我也是做iOS开发的,通过在网上的查询发现信息虽然很多实用的很少,容易误导他人,经过自己的成功实践,做了笔录,为 ...

  5. Docker windows下安装并搭建Nodejs的webapp

    一.关于Docker 什么是Docker?Docker 采用go语言编写,是一个开源的应用容器引擎.让开发者可以快速打包他们的应用以及依赖包到一个封装的可移植的容器Image中,然后发布到任何流行的机 ...

  6. [翻译]第一天 - 在 Windows 下安装和运行 .NET Core

    原文: http://michaelcrump.net/getting-started-with-aspnetcore/ 免责声明:我不是 .NET Core 开发团队的一员,并且使用的是公开.可用的 ...

  7. thrift安装及常见问题

    一.安装thrift (macOS / Linux) 1. 下载thrift0.10.0源码 https://github.com/apache/thrift/releases/tag/0.10.0 ...

  8. Windows下安装Object C开发环境,及Hello Word(转)

    Windows下安装Object C开发环境,及Hello Word 最近想学习iphone开发,但是由于没有c基础,只有java基础.所以先从基础学习,首先是搭建环境,目前手头没有mac机子,只能先 ...

  9. Thrift安装介绍

    一.简介 1.语言库要求 因为thrift支持多语言.所以编译thrift源代码的过程中,会用到该语言的一些类库.如c++的boost.java的jdk等. 那么,在安装thrift过程中,须要对各种 ...

随机推荐

  1. 安装db2 提示不是有效的win32应用程序?

    问题已经解决了,就是版本的问题.我在官网上下载的最新版本(10.5),网上说是最新的版本不支持xp系统,完了我下了9.7的版本,安装没有一点点问题

  2. [POJ 2019] Cornfields

    Cornfields Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 5516   Accepted: 2714 Descri ...

  3. apache开源项目--kylin

    Kylin 是一个开源的分布式的 OLAP 分析引擎,来自 eBay 公司开发,基于 Hadoop 提供 SQL 接口和 OLAP 接口,支持 TB 到 PB 级别的数据量. Kylin 是: 超级快 ...

  4. BrnMall多店版网上商城正式发布

    前些日子一直忙于多店版网上商城系统BrnMall的开发,工作比较多,所以博客断了.这几天项目完成了,时间比较自由,所以把这段时间总结的一些关于单店版BrnShop和多店版BrnMall区别写下来,希望 ...

  5. 关于offset()的理解

    假如要取得x线的offset().top,在页面上的是x线到页面顶端的距离s1,如何取得x线在窗口上的top呢,这就需要取得窗口顶端到页面顶端的距离s2,由于s1和s2都是有方向的,所以,s1-s2就 ...

  6. POJ2236 Wireless Network 并查集

    水题 #include<cstdio> #include<cstring> #include<queue> #include<set> #include ...

  7. apple mac 下使用机械键盘的办法,键盘映射工具软件,apple mac Mechanical keyboard

    apple mac 下使用机械键盘的办法,键盘映射工具软件,apple mac Mechanical keyboard 想在苹果电脑 mac 系统下使用 机械键盘,大部分机械键盘不是为mac设计的,所 ...

  8. UVALive 5135 Mining Your Own Business 双连通分量 2011final

    题意:n条隧道由一些点连接而成,其中每条隧道链接两个连接点.任意两个连接点之间最多只有一条隧道.任务就是在这些连接点中,安装尽量少的太平井和逃生装置,使得不管哪个连接点倒塌,工人都能从其他太平井逃脱, ...

  9. 【Java基础】Java类及成员和修饰符的关系

    修饰符的分类 权限修饰符:private,默认的,protected,public 状态修饰符:static,final 抽象修饰符:abstract 类的修饰符 权限修饰符:默认修饰符,public ...

  10. vmware 8下ubuntu 13.04安装vmware tools

    在虚拟机vmware 8.0里安装了ubuntu 13.04.为了方便与主机交互,安装vmware tools. 解压后直接运行 ./vmware-install.pl 一路默认路径安装下来,到&qu ...