一、概述
Thrift是一个软件框架,用来进行可扩展且跨语言的服务的开发。它结合了功能强大的软件堆栈和代码生成引擎,以构建在 C++, Java, Python, PHP, Ruby, Erlang, Perl, Haskell, C#, Cocoa, JavaScript, Node.js, Smalltalk, and OCaml 等等编程语言间无缝结合的、高效的服务。
Thrift最初由facebook开发,07年四月开放源码,08年5月进入apache孵化器。thrift允许你定义一个简单的定义文件中的数据类型和服务接口。以作为输入文件,编译器生成代码用来方便地生成RPC客户端和服务器通信的无缝跨编程语言。【来自百度百科】
官网地址:thrift.apache.org
二、下载依赖(Maven)
1、在pom.xml 中添加如下内容:
org.apache.thrift
libthrift
0.9.3
org.slf4j
slf4j-log4j12
1.7.12
三、基本概念以及实现步骤
几张图片说明thrift整个流程:
架构图:
服务端
客户端
部署图
注意:图片来源互联网
1、数据传输协议
TBinaryProtocol : 二进制格式.
TCompactProtocol : 压缩格式
TJSONProtocol : JSON格式
TSimpleJSONProtocol : 提供JSON只写协议, 生成的文件很容易通过脚本语言解析
2、服务端
实现服务处理接口impl
创建TProcessor
创建TServerTransport
创建TProtocol
创建TServer
启动Server
创建Transport
创建TProtocol
基于TTransport和TProtocol创建 Client
调用Client的相应方法
四、实例
1、thrift文件创建,并在文件中定义需要的接口方法
namespace java com.jmust.thrift.demo
service HelloWorldService {
string sayHello(1:string username)
}
2、执行thrift-0.9.3.exe生成代码
thrift-0.9.3.exe -r -gen java ./demoHello.thrift
3、创建一个服务maven项目(shrift-service),将生成的
HelloWorldService.java文件复制到自己的项目中,利用maven打包成为bundle作为一个服务包,里面代码具体是什么样子的,我们不需要关心,到时候需要用到的地方,只需要把这个服务包引进去即可使用,下面看看我的pom.xml文件(把该开放出去的package开放出去,该引进来的package引进来)
4.0.0
com.jmust.thrift
thrift-service
1.0.0
jar
thrift-service
http://maven.apache.org
UTF-8
junit
junit
3.8.1
test
org.apache.thrift
libthrift
0.9.3
org.slf4j
slf4j-log4j12
1.7.12
org.apache.maven.plugins
maven-compiler-plugin
2.3.2
1.7
${project.build.sourceEncoding}
org.apache.maven.plugins
maven-resources-plugin
2.4.3
compile
${project.build.sourceEncoding}
org.apache.maven.plugins
maven-source-plugin
2.4
deploy
jar
org.apache.maven.plugins
maven-deploy-plugin
2.8.2
false
org.apache.maven.plugins
maven-javadoc-plugin
2.10.3
true
org.apache.maven.plugins
maven-surefire-plugin
2.7.2
false
org.codehaus.mojo
cobertura-maven-plugin
2.7
org.apache.maven.plugins
maven-jar-plugin
2.3.1
true
lib/
.
JMUST
2
${project.groupId}.${project.ArtifactId}
${project.groupId}.${project.ArtifactId}
${project.version}
${project.groupId}
com.jmust.thrift.service;version=${project.version}
javax.annotation,org.slf4j,org.apache.thrift,org.apache.thrift.async,org.apache.thrift.scheme,org.apache.thrift.protocol,org.apache.thrift.server.AbstractNonblockingServer
org.apache.thrift
libthrift
0.9.3
org.slf4j
slf4j-log4j12
1.7.12
com.jmust.thrift
thrift-service
1.0.0
package com.jmust.thrift.impl;
import org.apache.thrift.TException;
import com.jmust.thrift.service.HelloWorldService.Iface;
/**
*
* @author LK
*
*/
public class HelloWorldImpl implements Iface
{
public HelloWorldImpl(){
}
public String sayHello(String username) throws TException {
return "Hi," + username + " welcome to my blog www.jmust.com";
}
}
5.1、TSimpleServer服务端-----简单的单线程服务模型,一般用于测试
package com.jmust.thrift.demo;
import org.apache.thrift.TProcessor;
import org.apache.thrift.protocol.TBinaryProtocol;
import org.apache.thrift.server.TServer;
import org.apache.thrift.server.TServer.Args;
import org.apache.thrift.server.TSimpleServer;
import org.apache.thrift.transport.TServerSocket;
import com.jmust.thrift.impl.HelloWorldImpl;
import com.jmust.thrift.service.HelloWorldService.Iface;
import com.jmust.thrift.service.HelloWorldService.Processor;
/**
* 单线程服务模型,一般用于测试 TSimpleServer服务端
* @author LK
*
*/
public class HelloTSimpleServerDemo {
public static final int SERVER_PORT = 8090;
public void startServer() {
try {
System.out.println("HelloWorld TSimpleServer start ....");
TProcessor tprocessor = new Processor(
new HelloWorldImpl());
// 简单的单线程服务模型,一般用于测试
TServerSocket serverTransport = new TServerSocket(SERVER_PORT);
Args tArgs = new Args(serverTransport);
tArgs.processor(tprocessor);
tArgs.protocolFactory(new TBinaryProtocol.Factory());
TServer server = new TSimpleServer(tArgs);
server.serve();
} catch (Exception e) {
System.out.println("Server start error!!!");
e.printStackTrace();
}
}
/**
* @param args
*/
public static void main(String[] args) {
HelloTSimpleServerDemo server = new HelloTSimpleServerDemo();
server.startServer();
}
}
package com.jmust.thrift.demo;
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.server.TThreadPoolServer.Args;
import org.apache.thrift.transport.TServerSocket;
import com.jmust.thrift.impl.HelloWorldImpl;
import com.jmust.thrift.service.HelloWorldService.Iface;
import com.jmust.thrift.service.HelloWorldService.Processor;
/**
* 线程池服务模型,使用标准的阻塞式IO,预先创建一组线程处理请求 TThreadPoolServer 服务模型
* @author LK
*
*/
public class HelloTThreadPoolServerDemo {
public static final int SERVER_PORT = 8090;
public void startServer() {
try {
System.out.println("HelloWorld TThreadPoolServer start ....");
TProcessor tprocessor = new Processor(
new HelloWorldImpl());
TServerSocket serverTransport = new TServerSocket(SERVER_PORT);
//TThreadPoolServer 线程池服务模型
Args ttpsArgs = new Args(
serverTransport);
ttpsArgs.processor(tprocessor);
ttpsArgs.protocolFactory(new TBinaryProtocol.Factory());
//线程池服务模型,使用标准的阻塞式IO,预先创建一组线程处理请求。
TServer server = new TThreadPoolServer(ttpsArgs);
server.serve();
} catch (Exception e) {
System.out.println("Server start error!!!");
e.printStackTrace();
}
}
/**
* @param args
*/
public static void main(String[] args) {
HelloTThreadPoolServerDemo server = new HelloTThreadPoolServerDemo();
server.startServer();
}
}
package com.jmust.thrift.demo;
import org.apache.thrift.TProcessor;
import org.apache.thrift.protocol.TCompactProtocol;
import org.apache.thrift.server.TNonblockingServer;
import org.apache.thrift.server.TNonblockingServer.Args;
import org.apache.thrift.server.TServer;
import org.apache.thrift.transport.TFramedTransport;
import org.apache.thrift.transport.TNonblockingServerSocket;
import com.jmust.thrift.impl.HelloWorldImpl;
import com.jmust.thrift.service.HelloWorldService.Iface;
import com.jmust.thrift.service.HelloWorldService.Processor;
/**
* 使用非阻塞式IO,服务端和客户端需要指定 TFramedTransport 数据传输的方式 TNonblockingServer 服务模型
* @author LK
*
*/
public class HelloTNonblockingServerDemo {
public static final int SERVER_PORT = 8090;
public void startServer() {
try {
System.out.println("HelloWorld TNonblockingServer start ....");
TProcessor tprocessor = new Processor(
new HelloWorldImpl());
TNonblockingServerSocket tnbSocketTransport = new TNonblockingServerSocket(SERVER_PORT);
Args tnbArgs = new Args(tnbSocketTransport);
tnbArgs.processor(tprocessor);
tnbArgs.transportFactory(new TFramedTransport.Factory());
tnbArgs.protocolFactory(new TCompactProtocol.Factory());
TServer server = new TNonblockingServer(tnbArgs);
server.serve();
} catch (Exception e) {
System.out.println("Server start error!!!");
e.printStackTrace();
}
}
/**
* @param args
*/
public static void main(String[] args) {
HelloTNonblockingServerDemo server = new HelloTNonblockingServerDemo();
server.startServer();
}
}
package com.jmust.thrift.demo;
import org.apache.thrift.TProcessor;
import org.apache.thrift.protocol.TBinaryProtocol;
import org.apache.thrift.server.THsHaServer;
import org.apache.thrift.server.THsHaServer.Args;
import org.apache.thrift.server.TServer;
import org.apache.thrift.transport.TFramedTransport;
import org.apache.thrift.transport.TNonblockingServerSocket;
import com.jmust.thrift.impl.HelloWorldImpl;
import com.jmust.thrift.service.HelloWorldService.Iface;
import com.jmust.thrift.service.HelloWorldService.Processor;
/**
* 半同步半异步的服务端模型,需要指定为: TFramedTransport 数据传输的方式 THsHaServer服务模型
* @author LK
*
*/
public class HelloTHsHaServerDemo {
public static final int SERVER_PORT = 8090;
public void startServer() {
try {
System.out.println("HelloWorld THsHaServer start ....");
TProcessor tprocessor = new Processor(
new HelloWorldImpl());
TNonblockingServerSocket tnbSocketTransport = new TNonblockingServerSocket(SERVER_PORT);
Args args = new Args(tnbSocketTransport);
args.processor(tprocessor);
args.transportFactory(new TFramedTransport.Factory());
args.protocolFactory(new TBinaryProtocol.Factory());
TServer server = new THsHaServer(args);
server.serve();
} catch (Exception e) {
System.out.println("Server start error!!!");
e.printStackTrace();
}
}
/**
* @param args
*/
public static void main(String[] args) {
HelloTHsHaServerDemo server = new HelloTHsHaServerDemo();
server.startServer();
}
}
6.1、同步
package com.jmust.thrift.demo;
import org.apache.thrift.TException;
import org.apache.thrift.protocol.TBinaryProtocol;
import org.apache.thrift.protocol.TProtocol;
import org.apache.thrift.transport.TFramedTransport;
import org.apache.thrift.transport.TSocket;
import org.apache.thrift.transport.TTransport;
import org.apache.thrift.transport.TTransportException;
import com.jmust.thrift.service.HelloWorldService.Client;
/**
*
* @author LK
*
*/
public class HelloClientDemo {
public static final String SERVER_IP = "localhost";
public static final int SERVER_PORT = 8090;
public static final int TIMEOUT = 30000;
/**
*
* @param userName
*/
public void startClient(String userName) {
TTransport transport = null;
try {
//transport = new TSocket(SERVER_IP, SERVER_PORT, TIMEOUT);
transport = new TFramedTransport(new TSocket(SERVER_IP, SERVER_PORT, TIMEOUT));
// 协议要和服务端一致
TProtocol protocol = new TBinaryProtocol(transport);
//TProtocol protocol = new TCompactProtocol(transport);
// TProtocol protocol = new TJSONProtocol(transport);
Client client = new Client(protocol);
transport.open();
String result = client.sayHello(userName);
System.out.println("Thrify client result =: " + 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) {
HelloClientDemo client = new HelloClientDemo();
client.startClient("lvk");
}
}
package com.jmust.thrift.demo;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import org.apache.thrift.TException;
import org.apache.thrift.async.AsyncMethodCallback;
import org.apache.thrift.async.TAsyncClientManager;
import org.apache.thrift.protocol.TCompactProtocol;
import org.apache.thrift.protocol.TProtocolFactory;
import org.apache.thrift.transport.TNonblockingSocket;
import org.apache.thrift.transport.TNonblockingTransport;
import com.jmust.thrift.service.HelloWorldService.AsyncClient;
import com.jmust.thrift.service.HelloWorldService.AsyncClient.sayHello_call;
/**
* 异步客户端
* @author LK
*
*/
public class HelloAsynClientDemo {
public static final String SERVER_IP = "localhost";
public static final int SERVER_PORT = 8090;
public static final int TIMEOUT = 30000;
/**
*
* @param userName
*/
public void startClient(String userName) {
try {
TAsyncClientManager clientManager = new TAsyncClientManager();
TNonblockingTransport transport = new TNonblockingSocket(SERVER_IP, SERVER_PORT, TIMEOUT);
TProtocolFactory tprotocol = new TCompactProtocol.Factory();
AsyncClient asyncClient = new AsyncClient(tprotocol, clientManager, transport);
System.out.println("Client start .....");
CountDownLatch latch = new CountDownLatch(1);
AsynCallback callBack = new AsynCallback(latch);
System.out.println("call method sayHello start ...");
asyncClient.sayHello(userName, callBack);
System.out.println("call method sayHello .... end");
boolean wait = latch.await(30, TimeUnit.SECONDS);
System.out.println("latch.await =:" + wait);
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("startClient end.");
}
public class AsynCallback implements AsyncMethodCallback{
private CountDownLatch latch;
public AsynCallback(CountDownLatch latch) {
this.latch = latch;
}
public void onComplete(sayHello_call response) {
System.out.println("onComplete");
try {
// Thread.sleep(1000L * 1);
System.out.println("AsynCall result =:"
+ response.getResult().toString());
} catch (TException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
} finally {
latch.countDown();
}
}
public void onError(Exception exception) {
System.out.println("onError :" + exception.getMessage());
latch.countDown();
}
}
/**
* @param args
*/
public static void main(String[] args) {
HelloAsynClientDemo client = new HelloAsynClientDemo();
client.startClient("lvk");
}
}
先运行服务端,让后再运行客户端,看看是否输出预计结果。
完毕!