Thrift 入门学习记录
参照着官网以及各位大神的文档总算了解了些thrift的入门知识,记录了我第一次学习thrift的历程,不是什么经验心得,只是分享记录下自己的学习过程,如有错误,欢迎各位大大指正^_^
1、thrift是什么
thrift允许定义一个简单的定义文件中的数据类型和服务接口,这个文件就是IDL(Interface Definition Language)以作为输入文件,编译器生成代码。简单的说就是thrift定义了统一的文件(对象或者结构体,服务接口),使用thrift的编译器能够生成对应语言的代码文件。thrft之所以是跨语言的原意就是他通过语言无关的自定义语言来生成语言相关的代码。
2、thrift的基本数据类型以及对应关系
官网文档的说明如下
bool Boolean, one byte
byte Signed byte
i16 Signed 16-bit integer
i32 Signed 32-bit integer
i64 Signed 64-bit integer
double 64-bit floating point value
string String
Map<t1,t2> Map from one type to another
List<t1> Ordered list of one type
Set<t1> Set of unique elements of one type
容器
注:容器包含的元素可以是任意的Thrift类型(包含structs, exception), 不能是service
3、结构体及异常(Structs and Exceptions)
Struct同C语言中struct类似. Thrift编译工具将struct转换为OO语言中的类.Exception语法和功能等同于struct, 用于声明异常.。他们只存在语义上的差别, 比如定义一个RPC服务, 开发可能会声明一个远程方法, 并抛出一个Exception
4、服务Services
等同于OOP中的定义一个interface. Thrift的编译工具会以此生成接口的客户端, 服务端
5、类型别名
Typedefs
同C/C++的typedef
typedef i32 MyInteger
typedef Tweet ReTweet
结尾可以没有分号,可以为struct定义别名
6、命名空间Namespaces
Thrift的命名空间类似C++或者Java的包. 他们都提供了一套便捷的代码组织(或者说隔离)的方法.命名空间可以避免类型定义中同名冲突的问题。因为每个语言都有自己的命名管理机制, Thrift允许你分别定义不同语言的命名习惯。
例如,java中可以使用namespace java com.demo.thrift
7、包含Includes
为了便于维护, 我们会把Thrift的定义分拆到多个文件, 从而达到重用并提升定义的模块化, 结构化. Thrift允许include其他Thrift定义文件。include默认从当前文件所在目录开始搜索, 也可以增加-I参数搜索指定目录下的关联路径.被包含进来的对象, 以thrift文件名作为前缀文件名称必须使用双引号, 对末尾分号不敏感
从第一个thrift demo入门
下载安装thrift
1) apprach官网下载thrift以及thrift.jar,slf4j.Jar,记得将下载的jar包导入项目
2) thrift可以在官网下载,windows下,可以直接使用thrift.exe
3) 进入cmd命令行模式,进入到存放thrift.exe的目录
4) cmd命令行下运行thrift -version输出版本号即为可以使用创建一个.thrift文件
我的.thrift文件为:namespace java com.demo.thrift //命名空间 //在这里我定义了一个叫 addStringService的服务, service AddStringService{ // 服务中有一个叫做addString的方法名,返回类型是string 包括两个参数,参数类型均为string string addString(1:string str1,2:string str2) }
接下来在cmd命令行下运行
thrift -gen java <.thrift文件的路径>
会在thrift的存放目录下生成gen-java 文件,将里面生成的java拷贝到项目相应位置即可
自动生成了1000多行代码真是可怕。
代码中包括了一个Iface接口,需要我们后面来自己实现。编写刚刚生成文件的实现类,实现刚刚生成文件中的Iface接口
我的实现类如下:AddString.java
java package com.demo.thrift; import org.apache.thrift.TException; public class AddString implements AddStringService.Iface{ public String addString(String str1, String str2) throws TException { //将str1与str2合并为一个字符串 return str1+str2; } }
server端的实现
这里是我的server段代码
TestThriftServer.java
package com.demo.server; import org.apache.thrift.protocol.TBinaryProtocol; import org.apache.thrift.protocol.TBinaryProtocol.Factory; import org.apache.thrift.server.TServer; import org.apache.thrift.server.TSimpleServer; import org.apache.thrift.transport.TServerSocket; import org.apache.thrift.transport.TServerTransport; import com.demo.thrift.AddString; import com.demo.thrift.AddStringService; import com.demo.thrift.AddStringService.Processor; public class TestThriftServer { public static void main(String[] args) { try { //设置服务器的端口 TServerTransport serverTransport = new TServerSocket(9090); //设置二进制协议接收工厂 Factory protocolFactory=new TBinaryProtocol.Factory(); //设置关联业务 AddString strhandler = new AddString(); Processor<AddStringService.Iface> processor=new Processor<AddStringService.Iface>(strhandler); //单线程服务器端 Server.Args simpleArgs = new TServer.Args(serverTransport); simpleArgs.processor(processor); simpleArgs.protocolFactory(protocolFactory); TServer server = new TSimpleServer(simpleArgs); System.out.println("服务开启...端口9090"); server.serve(); } catch (Exception x) { x.printStackTrace(); } System.out.println("done."); } }
client端的实现
a)设定传输方式,此处我使用的是socket方式传输 b)设置协议,这里的协议和服务端协议保持一致 c)实例化客户端对象,使用哪个接口的Client d)客户端调用关联后的业务 我的client端代码 TestThriftClient.java
package com.demo.client; 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 com.demo.thrift.AddStringService.Client; public class TestThriftClient { public static void main(String[] args) { try{ //设置调用的服务地址端口 TTransport transport=new TSocket("localhost",9090); //此处的协议和服务器上设置的保持一致 TProtocol protocol=new TBinaryProtocol(transport); //使用的接口 Client client=new Client(protocol); //打开socket transport.open(); String res=client.addString("abc", "123"); System.out.println(res); transport.close(); }catch(Exception e){ e.printStackTrace(); } } }
运行服务端代码与客户端代码,看到客户端打印出abc123,第一个demo构建成功
第一篇博客,还不会调格式- -,见谅