Thrift学习

一:thrift介绍

  Thrift是facebook开发的用来处理各不同系统之间数据通讯的rpc服务框架,后来成为apche的开源项目。thrift支持多种程序语言,包括Java,Python,Ruby,JavaScript,Node.js,Go,C,C++,C#,Erlang,Delphi,Perl,Php,SmallTalk,OCaml,Haxe,Haskell,D语言。Thrift采用IDL(Interface Defination Language)描述性语言来定义数据结构和接口。Thrift模型如下所示:
 
                                                  图 thrift模型图

二 thrift数据传输协议

TBinaryProtocol                 二进制传输协议
TCompactProtocol                使用VLQ编码进行压缩的数据传输协议
TJSONProtocol                   JSON格式的数据传输协议
TSimpleJSONProtocol             简单的JSON格式数据传输协议
TDebugProtocol                  调试时使用的文本传输协议

三 thrift传输层

TFramedTransport               按块的大小进行传输
TFileTransport                 按照文件的方式进行传输
TMemoryTransport               使用内存IO方式进行传输
TZlibTransport                 执行zlib压缩方式传输

四 thrift服务器端

TSimpleServer                  简单的单线程标准阻塞式服务器
TThreadPoolServer              多线程阻塞式服务器
TNonblockingServer             多线程非阻塞式服务器
THsHaServer                    半同步半异步服务器
其实传输层的传输只有阻塞和非阻塞,再加上具体的工作方式 单线程 多线程

五 thrift客户端

TClient                    简单单线程阻塞式客户端
TAsynClient                异步客户端(多线程)

六 thrift开发步骤

1服务器端

实现服务处理接口impl
创建TProcessor
创建TServerTransport(TServerSocket)   创建阻塞通信的还是非阻塞通信
创建TProtocol                                      数据传输协议
创建TServer                                       服务器类型 单工(单线程)  双工(多线程)  半单工半双工(多线程)
启动Server

2客户端

创建Transport(TSocket)               创建阻塞通信(客户端只有阻塞)
创建TProtocol                        数据传输协议
基于TTransport和TProtocol创建Client
调用Client的相应方法

七 thrift数据类型

1基本类型

bool:布尔值,true 或 false

byte:8 位有符号整数

i16:16 位有符号整数

i32:32 位有符号整数

i64:64 位有符号整数

double:64 位浮点数

string:utf-8编码的字符串

2结构体类型

struct:定义公共的对象

enum: 枚举类型

3容器类型

list:对应 Java 的 ArrayList

set:对应 Java 的 HashSet

map:对应 Java 的 HashMap

4异常类型

exception:对应 Java 的 Exception

5服务类型

service:对应服务的类  提供接口

八 thrift例子

enum 类型

struct Student{
1: required i32 id
2: required string username
3: required string password
4: requried string number
5: optional double age
}

struct 类型

struct School{
1: required i32 id
2: required string name
3: required set<Student> students
4: required list<Student> rank
5: required map<string, string> number_name
}

service 类型

service ThriftMysqlService{
void addUser(1:Student user)
list<Student> queryAllUser()
Student queryOneUser(1:i32 id)
map<string, string> queryOneArticle(1:i32 id)
}

具体代码

thrift.thrift 定义数据类型和接口的文件

namespace java org.seava.thrift_example.thrift

struct User{
1: required i32 userId
2: required string username
3: required string password
} service ThriftService{
void addUser(1:User user)
User queryUser(1:i32 id)
list<User> queryUserList()
map<string, string> queryUserNamePass()
map<i32, User> queryUserMap()
}

到apache的官网下载thrift.exe程序, 下载地址 http://thrift.apache.org/ ,下下来通过cmd命令窗口去运行如下命令

thrift  -gen java xxx.thrift

接口实现 ThriftServiceImpl.java

 1 package org.seava.thrift_example.thrift;
2
3 import java.util.ArrayList;
4 import java.util.HashMap;
5 import java.util.List;
6 import java.util.Map;
7
8
9 public class ThriftServiceImpl implements ThriftService.Iface {
10
11 public void addUser(User user) throws org.apache.thrift.TException{
12 System.out.println(user.userId + " " + user.username + " " + user.password);
13 }
14
15 public User queryUser(int id) throws org.apache.thrift.TException{
16 System.out.println(id);
17 User user = new User();
18 user.userId = 100;
19 user.username = "FFF";
20 user.password = "NNN";
21 return user;
22 }
23
24 public List<User> queryUserList() throws org.apache.thrift.TException{
25 User user = new User();
26 user.userId = 100;
27 user.username = "FFF";
28 user.password = "NNN";
29 User user2 = new User();
30 user2.userId = 102;
31 user2.username = "FFF2";
32 user2.password = "NNN2";
33 List<User> list = new ArrayList<User>();
34 list.add(user2);
35 list.add(user);
36 return list;
37 }
38
39 public Map<String,String> queryUserNamePass() throws org.apache.thrift.TException{
40 User user = new User();
41 user.userId = 100;
42 user.username = "FFF";
43 user.password = "NNN";
44 Map<String, String> map = new HashMap<String, String>();
45 map.put("password", user.password);
46 map.put("useranme", user.username);
47 return map;
48 }
49
50 public Map<Integer,User> queryUserMap() throws org.apache.thrift.TException{
51 User user = new User();
52 user.userId = 100;
53 user.username = "FFF";
54 user.password = "NNN";
55 User user2 = new User();
56 user2.userId = 102;
57 user2.username = "FFF2";
58 user2.password = "NNN2";
59 Map<Integer, User> map = new HashMap<Integer, User>();
60 map.put(user.userId, user);
61 map.put(user2.userId, user2);
62 return map;
63 }
64
65 }

服务器 Server.java

  1 package org.seava.thrift_example.thrift;
2
3 import org.apache.thrift.TProcessor;
4 import org.apache.thrift.protocol.TBinaryProtocol;
5 import org.apache.thrift.protocol.TCompactProtocol;
6 import org.apache.thrift.server.THsHaServer;
7 import org.apache.thrift.server.TNonblockingServer;
8 import org.apache.thrift.server.TServer;
9 import org.apache.thrift.server.TSimpleServer;
10 import org.apache.thrift.server.TThreadPoolServer;
11 import org.apache.thrift.transport.TFramedTransport;
12 import org.apache.thrift.transport.TNonblockingServerSocket;
13 import org.apache.thrift.transport.TNonblockingServerTransport;
14 import org.apache.thrift.transport.TServerSocket;
15 import org.apache.thrift.transport.TTransportException;
16
17
18 public class Server {
19
20 public static int port = 8090;
21
22 /**
23 * 简单服务器类型 阻塞单线程
24 * 步骤
25 * 创建TProcessor
26 * 创建TServerTransport
27 * 创建TProtocol
28 * 创建TServer
29 * 启动Server
30 */
31 public static void startSimpleServer(){
32 //创建processor
33 TProcessor tprocessor = new ThriftService.Processor<ThriftService.Iface>(new ThriftServiceImpl());
34 try {
35 //创建transport 阻塞通信
36 TServerSocket serverTransport = new TServerSocket(port);
37 //创建protocol
38 TBinaryProtocol.Factory protocol = new TBinaryProtocol.Factory();
39 //将processor transport protocol设入到服务器server中
40 TServer.Args args = new TServer.Args(serverTransport);
41 args.processor(tprocessor);
42 args.protocolFactory(protocol);
43 //定义服务器类型 设定参数
44 TServer server = new TSimpleServer(args);
45 //开启服务
46 server.serve();
47 } catch (TTransportException e) {
48 e.printStackTrace();
49 }
50 }
51
52 /**
53 * 多线程服务器 阻塞多线程
54 */
55 public static void startThreadPoolServer(){
56 //创建processor
57 TProcessor tprocessor = new ThriftService.Processor<ThriftService.Iface>(new ThriftServiceImpl());
58 try{
59 //创建transport 阻塞通信
60 TServerSocket serverTransport = new TServerSocket(port);
61 //创建protocol 数据传输协议
62 TBinaryProtocol.Factory protocol = new TBinaryProtocol.Factory();
63 TThreadPoolServer.Args args = new TThreadPoolServer.Args(serverTransport);
64 args.processor(tprocessor);
65 args.protocolFactory(protocol);
66 //创建服务器类型 多线程
67 TServer server = new TThreadPoolServer(args);
68 //开启服务
69 server.serve();
70 }catch(Exception e){
71 e.printStackTrace();
72 }
73 }
74
75 /**
76 * 非阻塞I/O
77 */
78 public static void startTNonblockingServer(){
79 //创建processor
80 TProcessor tprocessor = new ThriftService.Processor<ThriftService.Iface>(new ThriftServiceImpl());
81 try{
82 //创建transport 非阻塞 nonblocking
83 TNonblockingServerTransport serverTransport = new TNonblockingServerSocket(port);
84 //创建protocol 数据传输协议
85 TCompactProtocol.Factory protocol = new TCompactProtocol.Factory();
86 //创建transport 数据传输方式 非阻塞需要用这种方式传输
87 TFramedTransport.Factory transport = new TFramedTransport.Factory();
88 TNonblockingServer.Args args = new TNonblockingServer.Args(serverTransport);
89 args.processor(tprocessor);
90 args.transportFactory(transport);
91 args.protocolFactory(protocol);
92 //创建服务器 类型是非阻塞
93 TServer server = new TNonblockingServer(args);
94 //开启服务
95 server.serve();
96 }catch(Exception e){
97 e.printStackTrace();
98 }
99 }
100
101 /**
102 * 半同步半异步的非阻塞I/O
103 */
104 public static void startTHsHaServer(){
105 //创建processor
106 TProcessor tprocessor = new ThriftService.Processor<ThriftService.Iface>(new ThriftServiceImpl());
107 try{
108 //创建transport 非阻塞
109 TNonblockingServerTransport serverTransport = new TNonblockingServerSocket(port);
110 //非阻塞需要的传输方式
111 TFramedTransport.Factory transport = new TFramedTransport.Factory();
112 //数据传输协议
113 TCompactProtocol.Factory protocol = new TCompactProtocol.Factory();
114 //创建半同步半异步服务
115 THsHaServer.Args args = new THsHaServer.Args(serverTransport);
116 args.processor(tprocessor);
117 args.transportFactory(transport);
118 args.protocolFactory(protocol);
119 //创建 服务类型
120 TServer server = new THsHaServer(args);
121 //开启服务
122 server.serve();
123 }catch(Exception e){
124 e.printStackTrace();
125 }
126 }
127
128 public static void main(String args[]){
129 //开启简单服务器
130 // Server.startSimpleServer();
131 //开启多线程服务器
132 // Server.startThreadPoolServer();
133 // Server.startTNonblockingServer();
134 // Server.startTHsHaServer();
135 Server.startTNonblockingServer();
136 }
137 }

Server.java实现了简单服务器(阻塞单线程)   阻塞多线程   非阻塞   半同步半异步非阻塞

注意: 非阻塞时传输层需要选择TFramedTransport

客户端 Client.java

  1 package org.seava.thrift_example.thrift;
2
3 import java.util.List;
4 import java.util.Map;
5 import java.util.concurrent.CountDownLatch;
6 import java.util.concurrent.TimeUnit;
7
8 import org.apache.thrift.async.TAsyncClientManager;
9 import org.apache.thrift.protocol.TBinaryProtocol;
10 import org.apache.thrift.protocol.TCompactProtocol;
11 import org.apache.thrift.protocol.TProtocol;
12 import org.apache.thrift.protocol.TProtocolFactory;
13 import org.apache.thrift.transport.TFramedTransport;
14 import org.apache.thrift.transport.TNonblockingSocket;
15 import org.apache.thrift.transport.TNonblockingTransport;
16 import org.apache.thrift.transport.TSocket;
17 import org.apache.thrift.transport.TTransport;
18
19
20 public class Client implements Runnable {
21
22 public static String ip = "localhost";
23 public static int port = 8090;
24 public static int time_out = 30000;
25
26 /**
27 * 客户端设置
28 * 创建Transport
29 * 创建TProtocol
30 * 基于TTransport和TProtocol创建Client
31 * 调用Client的相应方法
32 */
33 public static void startSimpleClient(){
34 TTransport transport = null;
35 try{
36 //创建Transport
37 transport = new TSocket(ip, port, time_out);
38 //创建TProtocol
39 TProtocol protocol = new TBinaryProtocol(transport);
40 //基于TTransport和TProtocol创建Client
41 ThriftService.Client client = new ThriftService.Client(protocol);
42 transport.open();
43 //调用client方法
44 List<User> list = client.queryUserList();
45 for(User user : list){
46 System.out.println(user.userId + " " + user.username + " " + user.password);
47 }
48 Map<String, String> map = client.queryUserNamePass();
49 System.out.println(map);
50 User user = client.queryUser(10);
51 System.out.println(user.userId + " " + user.username + " " + user.password);
52 Map<Integer, User> map_u = client.queryUserMap();
53 System.out.println(map_u);
54 User uu = new User();
55 uu.userId = 1111;
56 uu.username = "mmbbmmbb";
57 uu.password = "ppbbppbb";
58 client.addUser(uu);
59 }catch(Exception e){
60 e.printStackTrace();
61 }
62 }
63
64 /**
65 * 调用阻塞服务器的客户端
66 */
67 public static void startNonblockingClient(){
68 TTransport transport = null;
69 try{
70 transport = new TFramedTransport(new TSocket(ip, port));
71 TCompactProtocol protocol = new TCompactProtocol(transport);
72 ThriftService.Client client = new ThriftService.Client(protocol);
73 transport.open();
74 //调用client方法
75 List<User> list = client.queryUserList();
76 for(User user : list){
77 System.out.println(user.userId + " " + user.username + " " + user.password);
78 }
79 Map<String, String> map = client.queryUserNamePass();
80 System.out.println(map);
81 User user = client.queryUser(10);
82 System.out.println(user.userId + " " + user.username + " " + user.password);
83 Map<Integer, User> map_u = client.queryUserMap();
84 System.out.println(map_u);
85 User uu = new User();
86 uu.userId = 1111;
87 uu.username = "mmbbmmbb";
88 uu.password = "ppbbppbb";
89 client.addUser(uu);
90 }catch(Exception e){
91 e.printStackTrace();
92 }
93 }
94
95 public static void startAsynClient(){
96 try{
97 TAsyncClientManager clientManager = new TAsyncClientManager();
98 TNonblockingTransport transport = new TNonblockingSocket(ip, port, time_out);
99 TProtocolFactory tprotocol = new TCompactProtocol.Factory();
100 ThriftService.AsyncClient asyncClient = new ThriftService.AsyncClient(tprotocol, clientManager, transport);
101 System.out.println("Client start ...");
102 CountDownLatch latch = new CountDownLatch(1);
103 AsynCallback callBack = new AsynCallback(latch);
104 System.out.println("call method queryUser start ...");
105 asyncClient.queryUser(100, callBack);
106 System.out.println("call method queryUser end");
107 boolean wait = latch.await(30, TimeUnit.SECONDS);
108 System.out.println("latch.await =:" + wait);
109 }catch(Exception e){
110 e.printStackTrace();
111 }
112 }
113
114 public void run(){
115 Client.startSimpleClient();
116 }
117
118 public static void main(String args[]){
119 //调用简单服务器
120 // Client.startSimpleClient();
121 /*Client c1 = new Client();
122 Client c2 = new Client();
123
124 new Thread(c1).start();
125 new Thread(c2).start();*/
126
127 // Client.startNonblockingClient();
128 // Client.startNonblockingClient();
129 Client.startAsynClient();
130 }
131 }

客户端实现了 阻塞单线程  和 异步客户端

具体代码在github上:https://github.com/WaterHsu/thrift-example.git

 
 
标签: thriftjava

Thrift学习的更多相关文章

  1. thrift学习笔记

    Thrift学习笔记 一:thrift介绍 Thrift是facebook开发的用来处理各不同系统之间数据通讯的rpc服务框架,后来成为apche的开源项目.thrift支持多种程序语言,包括Java ...

  2. Thrift学习记录

    Thrift学习记录 Thrift是一个软件框架,用来进行可扩展且跨语言的服务的开发.它结合了功能强大的软件堆栈和代码生成引擎,以构建在C++,Java,Python,PHP,Ruby,Erlang, ...

  3. RPC之Thrift学习实战

    关于Thrift的学习实战请参考:http://blog.csdn.net/column/details/slimina-thrift.html

  4. rpc框架之 thrift 学习 2 - 基本概念

    thrift的基本构架: 上图源自:http://jnb.ociweb.com/jnb/jnbJun2009.html 底层Underlying I/O以上的部分,都是由thrift编译器生成的代码, ...

  5. rpc框架之 thrift 学习 1 - 安装 及 hello world

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

  6. Apache Thrift学习之二(基础及原理)

    Apache Thrift 是 Facebook 实现的一种高效的.支持多种编程语言的远程服务调用的框架.本文将从 Java 开发人员角度详细介绍 Apache Thrift 的架构.开发和部署,并且 ...

  7. Apache Thrift学习之一(入门及Java实例演示)

    目录: 概述 下载配置 基本概念 数据类型 服务端编码基本步骤 客户端编码基本步骤 数据传输协议 实例演示(java) thrift生成代码 实现接口Iface TSimpleServer服务模型 T ...

  8. 跨平台通信中间件thrift学习【Java版本】(转)

    转自:http://neoremind.com/2012/03/%E8%B7%A8%E5%B9%B3%E5%8F%B0%E9%80%9A%E4%BF%A1%E4%B8%AD%E9%97%B4%E4%B ...

  9. thrift学习总结

    thrift 重要的几个组件有 :数据类型,transport,protocol,versioning,processor 1.数据类型 thrift的数据类型有1.一些原生类型,比如string,i ...

随机推荐

  1. 用python做oj上的简单题(持续更新中.......)

    本人刚開始接触python,在oj上解一些简单的题,欢迎交流,不喜勿喷. OJ地址链接:acm.sdut.edu.cn http://acm.sdut.edu.cn/sdutoj/showproble ...

  2. Kinect开发笔记之二Kinect for Windows 2.0新功能

    这是本博客翻译文档的第一篇文章.笔者已经苦逼的竭尽全力的在翻译了.但无奈英语水平也是非常有限.不正确或者不妥当不准确的地方必定会有,还恳请大家留言或者邮件我以批评指正.我会虚心接受. 谢谢大家.   ...

  3. 走向DBA[MSSQL篇] 详解游标

    原文:走向DBA[MSSQL篇] 详解游标 前篇回顾:上一篇虫子介绍了一些不常用的数据过滤方式,本篇详细介绍下游标. 概念 简单点说游标的作用就是存储一个结果集,并根据语法将这个结果集的数据逐条处理. ...

  4. 编写高质量JavaScript代码绳之以法(The Essentials of Writing High Quality JavaScript)翻译

    原文:The Essentials of Writing High Quality JavaScript 才华横溢的Stoyan Stefanov,在他写的由O'Reilly初版的新书<Java ...

  5. VC和gcc在保证功能static对线程安全的差异变量

    VC和gcc不同,不能保证静态变量的线程安全性.这就给我们的程序带来了非常大的安全隐患和诸多不便.这一点应该引起我们的重视!尤其是在构造函数耗时比較长的时候.非常可能给程序带来意想不到的结果.本文从測 ...

  6. Redis源代码分析(二十)--- ae事件驱动

    事件驱动的术语出现更频繁.听起来非常大的,今天我把Redis内部驱动器模型来研究它,奖励的感觉啊.一个ae.c主程序,加4文件的事件类型,让你彻底弄清楚,Redis是怎样处理这些事件的. 在Redis ...

  7. matlab练习程序(PCA<SVD>)

    clear all;close all;clc;img1=imread('Corner.png');img2=imread('Corner1.png');img3=imread('Corner2.pn ...

  8. 百度官方wormHole后门检测记录(转)

    本次这个安卓后门真是哔了狗了,刚加入大安卓阵营就出了这个篓子,跟你root不root和什么安卓版本没有版毛钱关系,完全是百度SDK官方提供的后门,不是漏洞,人为的. 乌云地址:http://drops ...

  9. dapper的Dapper-Extensions用法(一)

    dapper的Dapper-Extensions用法(一) Dapper-Extensions Dapper Extensions is a small library that complement ...

  10. DynamicReports

    try { response.setCharacterEncoding("UTF-8"); response.setHeader("Content-disposition ...