Apache Thrift入门学习
2016-12-21 15:13
302 查看
本文简单介绍下Apache Thrift。thrift是一个软件框架,用来进行可扩展且跨语言的服务的开发。它结合了功能强大的软件堆栈和代码生成引擎,以构建在 C++, Java, Go,Python, PHP, Ruby, Erlang, Perl, Haskell, C#, Cocoa, JavaScript, Node.js, Smalltalk, and OCaml 这些编程语言间无缝结合的、高效的服务。
全部代码下载:Github链接:github链接,点击惊喜;写文章不易,欢迎大家采我的文章,以及给出有用的评论,当然大家也可以关注一下我的github;多谢;
下载地址:http://archive.apache.org/dist/thrift/0.9.3/
新建一个文件夹如:Thtift
3.将thrift-0.9.3.exe该名为thrift(可以不改名)
4.修改系统的环境变量:
测试安装成功否:
2.tar -xzf thrift-0.9.3.tar.gz
3.cd thrift-0.9.3
./configure
make 有点慢
6.sudo make install
byte: 有符号字节
i16: 16位有符号整型
i32: 32位有符号整型
i64: 64位有符号整型
double: 64位浮点型
string: 字符串/字符数组
binary: 二进制数据
set: 一系列由T类型的数据组成的无序集合,元素不可重复
map
定义格式如下:
如:
IDL文件包含
thrift也支持文件包含,相当于C/C++中的include,Java中的import。使用关键字include定义,例 如:
1. 编写IDL文件,以及编译
2.下载jar包建立服务端代码:实现接口,和启动服务
3.建立客户端代码进行访问
打开终端输入命令:thrift -gen java ./hello.thrift 后会在当前目录生成gen-java文件夹,里面包含了我们定义的类和接口。按namespace路径存放。
点击下载
2.建立服务端代码,需要实现StudnetService类中的Iface接口,代码如下:详见注释
3.启动服务器:
2.启动客户端
客户端结果:
服务端结果:
本文来自伊豚(blog.wpeace.cn)
全部代码下载:Github链接:github链接,点击惊喜;写文章不易,欢迎大家采我的文章,以及给出有用的评论,当然大家也可以关注一下我的github;多谢;
1.Thrift介绍
Thrift是一种接口描述语言和二进制通讯协议,[1]它被用来定义和创建跨语言的服务。[2]它被当作一个远程过程调用(RPC)框架来使用,是由Facebook为“大规模跨语言服务开发”而开发的。它通过一个代码生成引擎联合了一个软件栈,来创建不同程度的、无缝的跨平台高效服务,可以使用C#、C++(基于POSIX兼容系统[3])、Cappuccino、[4]Cocoa、Delphi、Erlang、Go、Haskell、Java、Node.js、OCaml、Perl、PHP、Python、Ruby和Smalltalk。[5]虽然它以前是由Facebook开发的,但它现在是Apache软件基金会的开源项目了。该实现被描述在2007年4月的一篇由Facebook发表的技术论文中,该论文现由Apache掌管(摘自维基百科)2.Thrift安装
安装Thrift主要是为了通过IDL文件生成需要的接口和类。下载地址:http://archive.apache.org/dist/thrift/0.9.3/
2.1windowx的安装:
下载thrift-0.9.3.exe新建一个文件夹如:Thtift
3.将thrift-0.9.3.exe该名为thrift(可以不改名)
4.修改系统的环境变量:
测试安装成功否:
2.2Linux的安装:
下载:thrift-0.9.3.tar.gz2.tar -xzf thrift-0.9.3.tar.gz
3.cd thrift-0.9.3
./configure
make 有点慢
6.sudo make install
3.Thrift的IDL格式要求
IDL即接口定义语言,主要是为了生成各种语言(例如:java,c/C++等)能够理解的消息结构、接口定义的描述形式。因为要生成其他语言的类,接口,或者结构体,所以必须遵守一些规范。3.1文件支持的基本类型:
bool: 布尔值byte: 有符号字节
i16: 16位有符号整型
i32: 32位有符号整型
i64: 64位有符号整型
double: 64位浮点型
string: 字符串/字符数组
binary: 二进制数据
3.2容器类型:
list: 一系列由T类型的数据组成的有序列表,元素可以重复set: 一系列由T类型的数据组成的无序集合,元素不可重复
map
3.3结构体:
结构体经过解析后在面向对象语言中,表现为“类定义”;在弱类型语言、动态语言中,表现为“结构/结构体”。定义格式如下:
struct <结构体名称> { <序号>:[字段性质] <字段类型> <字段名称> [= <默认值>] [;|,] } ·结构体名称:可以按照您的业务需求,给定不同的名称(区分大小写)。但是要注意,一组IDL定义文件中结构体名称不能重复,且不能使用IDL已经占用的关键字(例如required 、struct 等单词)。 ·序号:序号非常重要。正整数,按照顺序排列使用。这个属性在Apache Thrift进行序列化的时候被使用。 ·字段性质:包括两种关键字:required 和 optional,如果您不指定,那么系统会默认为required。required表示这个字段必须有值,并且Apache Thrift在进行序列化时,这个字段都会被序列化;optional表示这个字段不一定有值,且Apache Thrift在进行序列化时,这个字段只有有值的情况下才会被序列化。 ·字段类型:在struct中,字段类型可以是某一个基础类型,也可以是某一个之前定义好的struct,还可以是某种Apache Thrift支持的容器(set、map、list),还可以是定义好的枚举。字段的类型是必须指定的。 ·字段名称:字段名称区分大小写,不能重复,且不能使用IDL已经占用的关键字(例如required 、struct 等单词)。 ·默认值:您可以为某一个字段指定默认值(也可以不指定)。 ·结束符:在struct中,支持两种结束符,您可以使用“;”或者“,”。当然您也可以不使用结束符(Apache Thrift代码生成程序,会自己识别到)
3.4枚举:
枚举的定义形式和C的Enum定义差不多enum <枚举名称> { <枚举字段名> = <枚举值>[;|,] }
3.5常量定义:
IDL允许定义常量。常量的关键字为“const”,与C语言类似,常量可以是基础类型,也可以是定义的Struct。如:
const i32 MAX_AREA = 60
3.6异常定义:
IDL允许定义异常,在定义服务接口使用。其定义方法类似于上面的Struct。因为exception也是类,定义时只需要将struct换成exception就行,如下:exception <异常名称> { <序号>:[字段性质] <字段类型> <字段名称> [= <默认值>] [;|,] }
3.7服务接口:
服务接口在生成代码过程中,生成的接口类是我们需要实现的提供给客户端调用的。service服务接口定义如下:service <服务名称> { <void | 返回指类型> <服务方法名>([<入参序号>:[required | optional] <参数类型> <参数名> ...]) [throws ([<异常序号>:[required | optional] <异常类型> <异常参数名>...])] } ·服务名称:服务名可以按照您的业务需求自行制定,注意服务名是区分大小写的。IDL中服务名称只有两个限制,就是不能重复使用相同的名称,不能使用IDL已经占用的关键字(例如required 、struct 等单词)。 ·返回值类型:如果这个调用方法没有返回类型,那么可以关键字“void”; 可以是Apache Thrift的基础类型,也可以是某一个之前定义好的struct,还可以是某种Apache Thrift支持的容器(set、map、list),还可以是定义好的枚举。 ·服务方法名:服务方法名可以根据您的业务需求自定制定,注意区分大小写。在同一个服务中,不能重复使用一个服务方法名命名多个方法(一定要注意),不能使用IDL已经占用的关键字。 ·服务方法参数:<入参序号>:[required | optional] <参数类型> <参数名>。注意和struct中的字段定义相似,可以指定required或者optional;如果不指定则系统默认为required 。如果一个服务方法中有多个参数名,那么这些参数名称不能重复。 ·服务方法异常:throws ([<异常序号>:[required | optional] <异常类型> <异常参数名>。throws关键字是服务方法异常定义的开始点。在throws关键字后面,可以定义1个或者多个不同的异常类型。
3.8命名空间:
thrift的命名空间相当于Java中的package的意思,主要目的是组织代码。thrift使用关键字namespace定义命名空间,例如:namespace java cn.wpeace.thrift
3.9其他特性:
1.注释:支持下面三种方式: /* * 注释方式1: **/// 注释方式2# 注释方式3
IDL文件包含
thrift也支持文件包含,相当于C/C++中的include,Java中的import。使用关键字include定义,例 如:
include "wpeace.thrift"
4.Hello world Thrift
下面讲解下编写一个Hello world工程的步骤:1. 编写IDL文件,以及编译
2.下载jar包建立服务端代码:实现接口,和启动服务
3.建立客户端代码进行访问
4.1编写IDL文件和编译
按照第三节的规范,编写IDL文件。如下:我命名为hello.thrift//命名空间定义:java包 namespace java cn.wpeace.thrift //结构体定义:转化java中的实体类 struct Request{ 1:required string userName; 2:required string password; } //定义返回类型 struct Student{ 1:required string naem; 2:required i32 age; } //异常描述定义 exception HelloException{ 1:required string msg; } //服务定义,生成接口用 service StudentService{ list<Student> getAllStudent(1:Request request)throws (1:HelloException e); }
打开终端输入命令:thrift -gen java ./hello.thrift 后会在当前目录生成gen-java文件夹,里面包含了我们定义的类和接口。按namespace路径存放。
4.2下载jar包建立服务端代码
1.需要下载的jar包:org.slf4j.api.jar org.slf4j.simple.jar libthrift-0.9.1.jar
点击下载
2.建立服务端代码,需要实现StudnetService类中的Iface接口,代码如下:详见注释
package cn.wpeace.thrift; import java.util.ArrayList; import java.util.List; import java.util.concurrent.Executors; import org.apache.thrift.TException; import org.apache.thrift.protocol.TBinaryProtocol; import org.apache.thrift.server.TThreadPoolServer; import org.apache.thrift.server.TThreadPoolServer.Args; import org.apache.thrift.transport.TServerSocket; import org.apache.thrift.transport.TTransportException; import cn.wpeace.thrift.StudentService.Iface; import cn.wpeace.thrift.StudentService.Processor; public class StudentServiceImpl implements Iface {// 实现的是StudentService类下面的接口 @Override public List<Student> getAllStudent(Request request) throws HelloException, TException { System.out.println(request.getUserName()); System.out.println(request.getPassword()); List<Student> students = new ArrayList<>(); for (int i = 0; i < 5; i++) { Student student = new Student(); student.setNaem("peace" + i); student.setAge(22 + i); students.add(student); } return students; } }
3.启动服务器:
public static void main(String[] args) { try { System.out.println("服务启动"); // 非阻塞式 TNonblockingServerSocket serverSocket=new TNonblockingServerSocket(8081); // 服务执行控制器,类似于rmi中的bind Processor<Iface> processor = new StudentService.Processor<Iface>(new StudentServiceImpl()); // 为服务器设置对应的IO网络模型 TNonblockingServer.Args tArgs = new TNonblockingServer.Args(serverSocket); // 设置控制器 tArgs.processor(processor); //设置传输方式 // tArgs.transportFactory(new TFramedTransport.Factory()); // 设置消息封装格式 tArgs.protocolFactory(new TBinaryProtocol.Factory());//Thrift特有的一种二进制描述格式 // 启动Thrift服务 TNonblockingServer server = new TNonblockingServer(tArgs); server.serve();//启动后,程序就停在这里了。 System.out.println("服务结束"); } catch (TTransportException e) { e.printStackTrace(); } } @Test public void test(String[] args) { try { System.out.println("服务启动"); // 阻塞式同步socket TServerSocket serverSocket = new TServerSocket(8081); // 服务执行控制器,类似于rmi中的bind Processor<Iface> processor = new StudentService.Processor<Iface>(new StudentServiceImpl()); // 为服务器设置对应的IO网络模型 Args tArgs = new Args(serverSocket); // 设置控制器 tArgs.processor(processor); // 设置消息封装格式 tArgs.protocolFactory(new TBinaryProtocol.Factory());//Thrift特有的一种二进制描述格式 // 设置线程池参数 tArgs.executorService(Executors.newFixedThreadPool(10));//线程池调度器,由于是阻塞模式需要设置线程池。 // 启动Thrift服务 TThreadPoolServer server = new TThreadPoolServer(tArgs); server.serve();//启动后,程序就停在这里了。 System.out.println("服务结束"); } catch (TTransportException e) { e.printStackTrace(); } }
4.3建立客户段代码:
注意:客户端和服务端的传输协议需要一至,同时阻塞和非阻塞传输也有区别。详细见代码public static void main(String[] args) { try { //建立socket连接 //TSocket tSocket = new TSocket("192.168.1.118",8081); //如果是非阻塞型 需要使用 TTransport tSocket = new TFramedTransport(new TSocket("192.168.1.118",8081, 30000)); //设置封装协议 TBinaryProtocol protocol = new TBinaryProtocol(tSocket); //建立调用client StudentService.Client client=new StudentService.Client(protocol); //设置调用参数: Request request=new Request().setUserName("peace").setPassword("123456"); //准备传输 tSocket.open(); //正式调用接口 List<Student> allStudent = client.getAllStudent(request); //请求结束,断开连接 tSocket.close(); for(Student student:allStudent) { System.out.println(student.getNaem()+":"+student.getAge()); } } catch (TTransportException e) { e.printStackTrace(); } catch (HelloException e) { e.printStackTrace(); } catch (TException e) { e.printStackTrace(); } }
4.4测试:
1.启动服务器2.启动客户端
客户端结果:
服务端结果:
本文来自伊豚(blog.wpeace.cn)
相关文章推荐
- Apache Thrift学习之一(入门及Java实例演示)
- [转] Apache Thrift入门
- Apache Thrift入门1-架构&介绍
- RPC学习----Thrift快速入门和Java简单示例
- Thrift入门学习
- Apache Thrift入门(安装、测试与java程序编写)
- Apache Thrift学习小记
- 【Apache Thrift】Thrift入门教程(二)Thrift的使用和编译
- Apache Thrift with Java Quickstart(thrift入门及Java实例)
- Apache Thrift with Java Quickstart(thrift入门及Java实例)
- RPC学习----Thrift快速入门和Java简单示例
- Apache Thrift入门2-Java代码实现例子
- [转] Apache Thrift入门
- Apache Thrift 一个入门简单示例
- Apache Spark新手入门学习
- Apache Thrift学习小记
- [zz]Apache Thrift学习小记
- Apache Thrift入门(安装、测试与java程序编写)
- 记录我的Thrift 入门学习
- 【Apache Thrift】thrift入门教程(一)windows下thrift的安装