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

 package org.seava.thrift_example.thrift;

 import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map; public class ThriftServiceImpl implements ThriftService.Iface { public void addUser(User user) throws org.apache.thrift.TException{
System.out.println(user.userId + " " + user.username + " " + user.password);
} public User queryUser(int id) throws org.apache.thrift.TException{
System.out.println(id);
User user = new User();
user.userId = 100;
user.username = "FFF";
user.password = "NNN";
return user;
} public List<User> queryUserList() throws org.apache.thrift.TException{
User user = new User();
user.userId = 100;
user.username = "FFF";
user.password = "NNN";
User user2 = new User();
user2.userId = 102;
user2.username = "FFF2";
user2.password = "NNN2";
List<User> list = new ArrayList<User>();
list.add(user2);
list.add(user);
return list;
} public Map<String,String> queryUserNamePass() throws org.apache.thrift.TException{
User user = new User();
user.userId = 100;
user.username = "FFF";
user.password = "NNN";
Map<String, String> map = new HashMap<String, String>();
map.put("password", user.password);
map.put("useranme", user.username);
return map;
} public Map<Integer,User> queryUserMap() throws org.apache.thrift.TException{
User user = new User();
user.userId = 100;
user.username = "FFF";
user.password = "NNN";
User user2 = new User();
user2.userId = 102;
user2.username = "FFF2";
user2.password = "NNN2";
Map<Integer, User> map = new HashMap<Integer, User>();
map.put(user.userId, user);
map.put(user2.userId, user2);
return map;
} }

服务器 Server.java

 package org.seava.thrift_example.thrift;

 import org.apache.thrift.TProcessor;
import org.apache.thrift.protocol.TBinaryProtocol;
import org.apache.thrift.protocol.TCompactProtocol;
import org.apache.thrift.server.THsHaServer;
import org.apache.thrift.server.TNonblockingServer;
import org.apache.thrift.server.TServer;
import org.apache.thrift.server.TSimpleServer;
import org.apache.thrift.server.TThreadPoolServer;
import org.apache.thrift.transport.TFramedTransport;
import org.apache.thrift.transport.TNonblockingServerSocket;
import org.apache.thrift.transport.TNonblockingServerTransport;
import org.apache.thrift.transport.TServerSocket;
import org.apache.thrift.transport.TTransportException; public class Server { public static int port = 8090; /**
* 简单服务器类型 阻塞单线程
* 步骤
* 创建TProcessor
* 创建TServerTransport
* 创建TProtocol
* 创建TServer
* 启动Server
*/
public static void startSimpleServer(){
//创建processor
TProcessor tprocessor = new ThriftService.Processor<ThriftService.Iface>(new ThriftServiceImpl());
try {
//创建transport 阻塞通信
TServerSocket serverTransport = new TServerSocket(port);
//创建protocol
TBinaryProtocol.Factory protocol = new TBinaryProtocol.Factory();
//将processor transport protocol设入到服务器server中
TServer.Args args = new TServer.Args(serverTransport);
args.processor(tprocessor);
args.protocolFactory(protocol);
//定义服务器类型 设定参数
TServer server = new TSimpleServer(args);
//开启服务
server.serve();
} catch (TTransportException e) {
e.printStackTrace();
}
} /**
* 多线程服务器 阻塞多线程
*/
public static void startThreadPoolServer(){
//创建processor
TProcessor tprocessor = new ThriftService.Processor<ThriftService.Iface>(new ThriftServiceImpl());
try{
//创建transport 阻塞通信
TServerSocket serverTransport = new TServerSocket(port);
//创建protocol 数据传输协议
TBinaryProtocol.Factory protocol = new TBinaryProtocol.Factory();
TThreadPoolServer.Args args = new TThreadPoolServer.Args(serverTransport);
args.processor(tprocessor);
args.protocolFactory(protocol);
//创建服务器类型 多线程
TServer server = new TThreadPoolServer(args);
//开启服务
server.serve();
}catch(Exception e){
e.printStackTrace();
}
} /**
* 非阻塞I/O
*/
public static void startTNonblockingServer(){
//创建processor
TProcessor tprocessor = new ThriftService.Processor<ThriftService.Iface>(new ThriftServiceImpl());
try{
//创建transport 非阻塞 nonblocking
TNonblockingServerTransport serverTransport = new TNonblockingServerSocket(port);
//创建protocol 数据传输协议
TCompactProtocol.Factory protocol = new TCompactProtocol.Factory();
//创建transport 数据传输方式 非阻塞需要用这种方式传输
TFramedTransport.Factory transport = new TFramedTransport.Factory();
TNonblockingServer.Args args = new TNonblockingServer.Args(serverTransport);
args.processor(tprocessor);
args.transportFactory(transport);
args.protocolFactory(protocol);
//创建服务器 类型是非阻塞
TServer server = new TNonblockingServer(args);
//开启服务
server.serve();
}catch(Exception e){
e.printStackTrace();
}
} /**
* 半同步半异步的非阻塞I/O
*/
public static void startTHsHaServer(){
//创建processor
TProcessor tprocessor = new ThriftService.Processor<ThriftService.Iface>(new ThriftServiceImpl());
try{
//创建transport 非阻塞
TNonblockingServerTransport serverTransport = new TNonblockingServerSocket(port);
//非阻塞需要的传输方式
TFramedTransport.Factory transport = new TFramedTransport.Factory();
//数据传输协议
TCompactProtocol.Factory protocol = new TCompactProtocol.Factory();
//创建半同步半异步服务
THsHaServer.Args args = new THsHaServer.Args(serverTransport);
args.processor(tprocessor);
args.transportFactory(transport);
args.protocolFactory(protocol);
//创建 服务类型
TServer server = new THsHaServer(args);
//开启服务
server.serve();
}catch(Exception e){
e.printStackTrace();
}
} public static void main(String args[]){
//开启简单服务器
// Server.startSimpleServer();
//开启多线程服务器
// Server.startThreadPoolServer();
// Server.startTNonblockingServer();
// Server.startTHsHaServer();
Server.startTNonblockingServer();
}
}

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

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

客户端 Client.java

 package org.seava.thrift_example.thrift;

 import java.util.List;
import java.util.Map;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit; import org.apache.thrift.async.TAsyncClientManager;
import org.apache.thrift.protocol.TBinaryProtocol;
import org.apache.thrift.protocol.TCompactProtocol;
import org.apache.thrift.protocol.TProtocol;
import org.apache.thrift.protocol.TProtocolFactory;
import org.apache.thrift.transport.TFramedTransport;
import org.apache.thrift.transport.TNonblockingSocket;
import org.apache.thrift.transport.TNonblockingTransport;
import org.apache.thrift.transport.TSocket;
import org.apache.thrift.transport.TTransport; public class Client implements Runnable { public static String ip = "localhost";
public static int port = 8090;
public static int time_out = 30000; /**
* 客户端设置
* 创建Transport
* 创建TProtocol
* 基于TTransport和TProtocol创建Client
* 调用Client的相应方法
*/
public static void startSimpleClient(){
TTransport transport = null;
try{
//创建Transport
transport = new TSocket(ip, port, time_out);
//创建TProtocol
TProtocol protocol = new TBinaryProtocol(transport);
//基于TTransport和TProtocol创建Client
ThriftService.Client client = new ThriftService.Client(protocol);
transport.open();
//调用client方法
List<User> list = client.queryUserList();
for(User user : list){
System.out.println(user.userId + " " + user.username + " " + user.password);
}
Map<String, String> map = client.queryUserNamePass();
System.out.println(map);
User user = client.queryUser(10);
System.out.println(user.userId + " " + user.username + " " + user.password);
Map<Integer, User> map_u = client.queryUserMap();
System.out.println(map_u);
User uu = new User();
uu.userId = 1111;
uu.username = "mmbbmmbb";
uu.password = "ppbbppbb";
client.addUser(uu);
}catch(Exception e){
e.printStackTrace();
}
} /**
* 调用阻塞服务器的客户端
*/
public static void startNonblockingClient(){
TTransport transport = null;
try{
transport = new TFramedTransport(new TSocket(ip, port));
TCompactProtocol protocol = new TCompactProtocol(transport);
ThriftService.Client client = new ThriftService.Client(protocol);
transport.open();
//调用client方法
List<User> list = client.queryUserList();
for(User user : list){
System.out.println(user.userId + " " + user.username + " " + user.password);
}
Map<String, String> map = client.queryUserNamePass();
System.out.println(map);
User user = client.queryUser(10);
System.out.println(user.userId + " " + user.username + " " + user.password);
Map<Integer, User> map_u = client.queryUserMap();
System.out.println(map_u);
User uu = new User();
uu.userId = 1111;
uu.username = "mmbbmmbb";
uu.password = "ppbbppbb";
client.addUser(uu);
}catch(Exception e){
e.printStackTrace();
}
} public static void startAsynClient(){
try{
TAsyncClientManager clientManager = new TAsyncClientManager();
TNonblockingTransport transport = new TNonblockingSocket(ip, port, time_out);
TProtocolFactory tprotocol = new TCompactProtocol.Factory();
ThriftService.AsyncClient asyncClient = new ThriftService.AsyncClient(tprotocol, clientManager, transport);
System.out.println("Client start ...");
CountDownLatch latch = new CountDownLatch(1);
AsynCallback callBack = new AsynCallback(latch);
System.out.println("call method queryUser start ...");
asyncClient.queryUser(100, callBack);
System.out.println("call method queryUser end");
boolean wait = latch.await(30, TimeUnit.SECONDS);
System.out.println("latch.await =:" + wait);
}catch(Exception e){
e.printStackTrace();
}
} public void run(){
Client.startSimpleClient();
} public static void main(String args[]){
//调用简单服务器
// Client.startSimpleClient();
/*Client c1 = new Client();
Client c2 = new Client(); new Thread(c1).start();
new Thread(c2).start();*/ // Client.startNonblockingClient();
// Client.startNonblockingClient();
Client.startAsynClient();
}
}

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

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

thrift学习笔记的更多相关文章

  1. Thrift学习笔记—IDL基本类型

    thrift 采用IDL(Interface Definition Language)来定义通用的服务接口,并通过生成不同的语言代理实现来达到跨语言.平台的功能.在thrift的IDL中可以定义以下一 ...

  2. 学习笔记:The Log(我所读过的最好的一篇分布式技术文章)

    前言 这是一篇学习笔记. 学习的材料来自Jay Kreps的一篇讲Log的博文. 原文很长,但是我坚持看完了,收获颇多,也深深为Jay哥的技术能力.架构能力和对于分布式系统的理解之深刻所折服.同时也因 ...

  3. springmvc学习笔记--Interceptor机制和实践

    前言: Spring的AOP理念, 以及j2ee中责任链(过滤器链)的设计模式, 确实深入人心, 处处可以看到它的身影. 这次借项目空闲, 来总结一下SpringMVC的Interceptor机制, ...

  4. 学习笔记:The Log(我所读过的最好的一篇分布式技术文章)

    前言 这是一篇学习笔记. 学习的材料来自Jay Kreps的一篇讲Log的博文. 原文非常长.可是我坚持看完了,收获颇多,也深深为Jay哥的技术能力.架构能力和对于分布式系统的理解之深刻所折服.同一时 ...

  5. Dubbo -- 系统学习 笔记 -- 依赖

    Dubbo -- 系统学习 笔记 -- 目录 依赖 必需依赖 缺省依赖 可选依赖 依赖 必需依赖 JDK1.5+ 理论上Dubbo可以只依赖JDK,不依赖于任何三方库运行,只需配置使用JDK相关实现策 ...

  6. spring cloud 学习(二)关于 Eureka 的学习笔记

    关于 Eureka 的学习笔记 个人博客地址 : https://zggdczfr.cn/ ,欢迎光临~ 前言 Eureka是Netflix开发的服务发现组件,本身是一个基于REST的服务.Sprin ...

  7. SparkSQL学习笔记

    概述 冠状病毒来临,宅在家中给国家做贡献之际,写一篇随笔记录SparkSQL的学习笔记,目的有二,一是记录整理之前的知识作为备忘录,二是分享技术,大家共同进步,有问题也希望大家不吝赐教.总体而言,大数 ...

  8. js学习笔记:webpack基础入门(一)

    之前听说过webpack,今天想正式的接触一下,先跟着webpack的官方用户指南走: 在这里有: 如何安装webpack 如何使用webpack 如何使用loader 如何使用webpack的开发者 ...

  9. PHP-自定义模板-学习笔记

    1.  开始 这几天,看了李炎恢老师的<PHP第二季度视频>中的“章节7:创建TPL自定义模板”,做一个学习笔记,通过绘制架构图.UML类图和思维导图,来对加深理解. 2.  整体架构图 ...

随机推荐

  1. MyBatis 入门到精通(三) 高级结果映射

    MyBatis的创建基于这样一个思想:数据库并不是您想怎样就怎样的.虽然我们希望所有的数据库遵守第三范式或BCNF(修正的第三范式),但它们不是.如果有一个数据库能够完美映射到所有应用程序,也将是非常 ...

  2. HDU 5278 PowMod 数论公式推导

    题意:中文题自己看吧 分析:这题分两步 第一步:利用已知公式求出k: 第二步:求出k然后使用欧拉降幂公式即可,欧拉降幂公式不需要互质(第二步就是BZOJ3884原题了) 求k的话就需要构造了(引入官方 ...

  3. Android引用百度定位API第三方组件后导致其它.so文件无法正常加载的问题

    查看当前调试设备CPU架构的方法: adb.exe shell getprop ro.product.cpu.abi  (一般返回值为:armeabi-v7a) adb.exe shell getpr ...

  4. 记:Tmall活动页面开发

    一.年轻的我 “无人不成商”,如果一个电子商务网站想要做起来,搞活动时必不可少的(引入流量.提高用户黏度.活跃网站氛围),今天打折,明天送红包. (立秋活动,右) 作为一个前端,我当然要从技术的角度来 ...

  5. 【成都GamEver游戏公司诚邀服务器伙伴】【7~15k一年4次项目奖金】

    关于我们 我们厌倦了朝九晚五,一眼看到头的人生我们厌倦了耗费自己青春做的都是没有感情的项目平均从业经验5年以上行业顶尖美术和金牌制作人,资深欧美制作经验立志做中国的suppercell,公司小而美 我 ...

  6. 如何阅读Java源码

    刚才在论坛不经意间,看到有关源码阅读的帖子.回想自己前几年,阅读源码那种兴奋和成就感(1),不禁又有一种激动.源码阅读,我觉得最核心有三点:技术基础+强烈的求知欲+耐心. 说到技术基础,我打个比方吧, ...

  7. 最短路径算法(Dijkstra算法、Floyd-Warshall算法)

    最短路径算法具体的形式包括: 确定起点的最短路径问题:即已知起始结点,求最短路径的问题.适合使用Dijkstra算法. 确定终点的最短路径问题:即已知终结结点,求最短路径的问题.在无向图中,该问题与确 ...

  8. The Datastore

    [中央数据库模式难扩展]绝大多数的Web应用在处理一个为了以后的请求作检索用的请求时,需要存储信息.<1.Most useful web applications need to store i ...

  9. LinkButton(按钮)

    使用$.fn.linkbutton.defaults重写默认值对象. 按钮组件使用超链接按钮创建.它使用一个普通的<a>标签进行展示.它可以同时显示一个图标和文本,或只有图标或文字.按钮的 ...

  10. fx-experience-tools

    http://fxexperience.com/2012/03/announcing-fx-experience-tools/ I have some cool new stuff for you t ...