thrift总结 - 跨语言服务开发
IBM-Apache Thrift - 可伸缩的跨语言服务开发框架
POM:
<dependency> <groupId>org.apache.thrift</groupId> <artifactId>libthrift</artifactId> <version>0.9.2</version> </dependency>
Thrift是一个软件框架,用来进行 可扩展且跨语言的服务的开发。
thrift允许你定义一个简单的定义文件中的数据类型和服务接口。以作为输入文件,编译器生成代码用来方便地生成RPC客户端和服务器通信的无缝跨编程语言。
支持多种语言之间的 RPC方式的通信:
php语言client可以构造一个对象,调用相应的服务方法来调用java语言的服务 ,跨越语言的C/S RPC调用 。
thrift可以用来快速的开发基于Socket的接口工具。简单的说,就是可以让人快速的写Socket Server和Client。其实不用thrift开发socket也不难,
那么为什么要用thrift开发呢?主要有两个原因,一个是因为thrift本身帮你封装了很多基本的东西,你不需要自己去写socket里面的bind,accept之类的,以及他们的逻辑。可以很快速的开发基于进程的,线程的,SSL的socket。第二个理由是标准化,跨语言和跨平台,windows不算在其中。主要是在各种Posix兼容的操作系统中都可以不需要改造基本直接可用,支持的语言种类也很多,基本你会写的,他都支持。你不会写的,他也支持。
Thrift与其他传输方式的比较
xml与JSON相比体积太大,但是xml传统,也不算复杂。
json 体积较小,新颖,但不够完善。
thrift 体积超小,使用起来比较麻烦,不如前两者轻便,但是对于 1.高并发、2.数据传输量大、3.多语言环境, 满足其中2点使用 thrift还是值得的。
建立一个java rmi的流程 :
1、定义一个服务调用接口 。
2、server端:接口实现---impl的实例---注册该服务实现(端口)---启动服务。
3、client端:通过ip、端口、服务名,得到服务,通过接口来调用 。
4、rmi数据传输方式:java对象序列化 。
Thrift:
thrift --gen <language> <Thrift filename>
To recursivly generate source code from a Thrift file and all other Thrift files included by it, run
thrift -r --gen <language> <Thrift filename>
thrift-0.7.0.exe -r -gen java TestThrift.thrift 生成java 代码
thrift-0.7.0.exe -r -gen php TestThrift.thrift 生成php代码
thrift-0.7.0.exe -r -gen py TestThrift.thrift 生成python代码
thrift-0.7.0.exe -r -gen as3 TestThrift.thrift 生成as3代码
thrift-0.7.0.exe -r -gen cpp TestThrift.thrift 生成C++代码
基本概念
1.数据类型
基本类型:
bool:布尔值,true 或 false,对应 Java 的 boolean
byte:8 位有符号整数,对应 Java 的 byte
i16:16 位有符号整数,对应 Java 的 short
i32:32 位有符号整数,对应 Java 的 int
i64:64 位有符号整数,对应 Java 的 long
double:64 位浮点数,对应 Java 的 double
string:utf-8编码的字符串,对应 Java 的 String
结构体类型:
struct:定义公共的对象,类似于 C 语言中的结构体定义,在 Java 中是一个 JavaBean
容器类型:
list:对应 Java 的 ArrayList
set:对应 Java 的 HashSet
map:对应 Java 的 HashMap
异常类型:
exception:对应 Java 的 Exception
服务类型:
service:对应服务的类
2.服务端编码基本步骤:
实现服务处理接口impl
创建TProcessor
创建TServerTransport(TServerSocket)
创建TProtocol
创建TServer
启动Server
3.客户端编码基本步骤:
创建Transport
创建TProtocol
基于TTransport和TProtocol创建 Client
调用Client的相应方法
4.数据传输协议
TBinaryProtocol : 二进制格式.
TCompactProtocol : 压缩格式
TJSONProtocol : JSON格式
TSimpleJSONProtocol : 提供JSON只写协议, 生成的文件很容易通过脚本语言解析
tips:客户端和服务端的协议要一致
服务端类型:
TSimpleServer
简单的单线程服务模型,一般用于测试。
TThreadPoolServer
线程池服务模型,使用标准的阻塞式IO,预先创建一组线程处理请求。
TNonblockingServer:
使用非阻塞式IO,服务端和客户端需要指定 TFramedTransport 数据传输的方式。
例子:
1、thrift生成代码
使用thrift需要 先定义接口文件demo.thrift,在thrift里简称叫IDL,全称叫Interface Description Language,接口描述语言。接口描述语言里面需要定义接口中所使用的数据类型,方法等等。
使用 Thrift 工具编译 demo.thrift,就会生成相应的 HelloWorldService.java 文件。 该文件包含了在 demo.thrift 文件中描述的服务 HelloWorldService 的接口定义,即 HelloWorldService.Iface 接口,以及服务调用的底层通信细节,包括客户端的调用逻辑 HelloWorldService.Client 以及服务器端的处理逻辑 HelloWorldService.Processor,用于构建客户端和服务器端的功能。
创建一个简单的服务 HelloWordService。首先根据 Thrift 的语法规范编写脚本文件 demo.thrift:
namespace java com.service.demo
service HelloWorldService{
string sayHello(1:string username)
i32 helloInt(1:i32 para)
bool helloBoolean(1:bool para)
void helloVoid()
string helloNull()
}
thrift-0.9.2.exe 是官网提供的windows下编译工具,运用这个工具生成相关代码:
thrift-0.9.2.exe -r -gen java demo.thrift
生成文件目录:\gen-java\com\service\demo\HelloWorldService.java
将架包导入工程中,并将生成的HelloWordService.java拷入
2、 实现接口Iface
import org.apache.thrift.TException;
public class HelloWorldServiceImpl implements HelloWorldService.Iface{
@Override
public String sayHello(String username) throws TException {
return "Hi," + username + " this is my first thrift demo.";
}
@Override
public boolean helloBoolean(boolean para) throws TException {
// TODO Auto-generated method stub
return false;
}
@Override
public int helloInt(int para) throws TException {
// TODO Auto-generated method stub
return 0;
}
@Override
public String helloNull() throws TException {
// TODO Auto-generated method stub
return null;
}
@Override
public void helloVoid() throws TException {
// TODO Auto-generated method stub
}
}
3、创建服务端实现代码:
package com.common.test;
import org.apache.thrift.TProcessor;
import org.apache.thrift.protocol.TBinaryProtocol;
import org.apache.thrift.server.TServer;
import org.apache.thrift.server.TThreadPoolServer;
import org.apache.thrift.transport.TServerSocket;
public class HelloServiceServer {
public static final int SERVER_PORT = 8090;
public static void startServer() {
try {
System.out.println("HelloWorld TThreadPoolServer start ....");
TProcessor processor = new HelloWorldService.Processor(new HelloWorldServiceImpl());
TServerSocket serverTransport = new TServerSocket(SERVER_PORT);
//TServerTransport serverTransport = new TServerSocket( new InetSocketAddress("0.0.0.0",9813));
TThreadPoolServer.Args ttpsArgs = new TThreadPoolServer.Args(serverTransport);
ttpsArgs.processor(processor);
ttpsArgs.protocolFactory(new TBinaryProtocol.Factory());
// 线程池服务模型,使用标准的阻塞式IO,预先创建一组线程处理请求。
TServer server = new TThreadPoolServer(ttpsArgs);
server.serve();
/* 或者:
Args trArgs=new Args(serverTransport);
trArgs.processor(processor);
//使用二进制来编码应用层的数据
trArgs.protocolFactory(new TBinaryProtocol.Factory(true, true));
//使用普通的socket来传输数据
//trArgs.transportFactory(new TTransportFactory());
TServer server = new TThreadPoolServer(trArgs); */
System.out.println("Start server on port "+SERVER_PORT+"...");
} catch (Exception e) {
System.out.println("Server start error!!!");
e.printStackTrace();
}
}
/**
* @param args
*/
public static void main(String[] args) {
startServer();
}
}
HelloWorld TThreadPoolServer start ....
4、创建客户端实现代码:
package com.common.test;
import org.apache.thrift.TException;
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 org.apache.thrift.transport.TTransportException;
public class HelloServiceClient {
public static final String SERVER_IP = "192.168.3.76";
public static final int SERVER_PORT = 8090;
public static final int TIMEOUT = 30000;
/**
*
* @param userName
*/
public static void startClient(String userName) {
TTransport transport = null;
try {
transport = new TSocket(SERVER_IP, SERVER_PORT, TIMEOUT);
// 协议要和服务端一致
TProtocol protocol = new TBinaryProtocol(transport);
// TProtocol protocol = new TCompactProtocol(transport);
// TProtocol protocol = new TJSONProtocol(transport);
HelloWorldService.Client client = new HelloWorldService.Client(protocol);
transport.open();
String result = client.sayHello(userName);
System.out.println(result);
} catch (TTransportException e) {
e.printStackTrace();
} catch (TException e) {
e.printStackTrace();
} finally {
if (null != transport) {
transport.close();
}
}
}
/**
* @param args
*/
public static void main(String[] args) {
startClient("Michael");
}
}
Hi,Michael this is my first thrift demo.
-
本文附件下载:
- thrift例子_lib.zip (699.3 KB)
- thrift编译工具.zip (9.5 MB)
已有 0 人发表留言,猛击->> 这里<<-参与讨论
ITeye推荐