一.下载安装
- 下载地址: http://www.apache.org/dyn/closer.cgi?path=/thrift/0.11.0/thrift-0.11.0.tar.gz
- 安装之前需要解决依赖问题: https://thrift.apache.org/docs/install/debian
sudo apt-get install automake bison flex g++ git libboost-all-dev libevent-dev libssl-dev libtool make pkg-config
- 解压并进入目录编译安装
sudo tar zxvf thrift-0.11.0.tar.gz
cd thrift-0.11.0/
./configure –-prefix=/usr/local/thrift --enable-libtool-lock
make && make install
ln -s /usr/local/thrift/bin/thrift /usr/bin/thrift
- 如果想通过php使用thrift的话需要安装php-thrift扩展
#安装thrift_protocol扩展,仅支持二进制读写
cd /usr/local/src/thrift-0.11.0/lib/php/src/ext/thrift_protocol
/usr/local/php/bin/phpize
./configure
sudo make
sudo make install
二. 通过java使用thrift
- 加入maven 依赖
org.apache.thrift
libthrift
0.10.0
org.slf4j
slf4j-log4j12
1.5.8
- 编写接口描述文件文件
HelloWorldService.thrift
(以下目录thrift是自己创建的)
namespace java lxf.service
namespace php lxfService
service HelloWorldService {
string sayHello(1:string username)
}
- 在命令行下通过thrift命令生成接口文件(该接口文件需要java客户端和服务器端口使用的)
thrift -r -gen java HelloWorldService.thrift
会自动在gen-java目录下产生java文件,结构请看以上thrift-i.png
-
编写客户端和服务端代码, 结构如下:
通过HelloWorldImpl类实现接口
package lxf.service;
public class HelloWorldImpl implements HelloWorldService.Iface {
public HelloWorldImpl() {
}
@Override
public String sayHello(String username) {
return "Hi," + username + " welcome to my blog www.micmiu.com";
}
}
- 创建服务
HelloServerDemo.java
package lxf.server;
import org.apache.thrift.TProcessor;
import org.apache.thrift.protocol.TBinaryProtocol;
import org.apache.thrift.protocol.TCompactProtocol;
import org.apache.thrift.protocol.TJSONProtocol;
import org.apache.thrift.protocol.TSimpleJSONProtocol;
import org.apache.thrift.server.TServer;
import org.apache.thrift.server.TSimpleServer;
import org.apache.thrift.transport.TServerSocket;
import lxf.service.*;
/**
* blog http://www.micmiu.com
*
* @author Michael
*
*/
public class HelloServerDemo {
public static final int SERVER_PORT = 9090;
public void startServer() {
try {
System.out.println("HelloWorld TSimpleServer start ....");
HelloWorldImpl service = new HelloWorldImpl();
TProcessor tprocessor = new HelloWorldService.Processor(service);
// HelloWorldService.Processor<HelloWorldService.Iface> tprocessor =
// new HelloWorldService.Processor<HelloWorldService.Iface>(
// new HelloWorldImpl());
// 简单的单线程服务模型,一般用于测试
TServerSocket serverTransport = new TServerSocket(SERVER_PORT);
TServer.Args tArgs = new TServer.Args(serverTransport);
tArgs.processor(tprocessor);
tArgs.protocolFactory(new TBinaryProtocol.Factory());
// tArgs.protocolFactory(new TCompactProtocol.Factory());
// tArgs.protocolFactory(new TJSONProtocol.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) {
HelloServerDemo server = new HelloServerDemo();
server.startServer();
}
}
-
运行 java main方法就可以启动服务,监听
9090
端口, 启动成功显示:
创建客户端
HelloClientDemo.java
package lxf.client;
import org.apache.thrift.TException;
import org.apache.thrift.protocol.TBinaryProtocol;
import org.apache.thrift.protocol.TCompactProtocol;
import org.apache.thrift.protocol.TJSONProtocol;
import org.apache.thrift.protocol.TProtocol;
import org.apache.thrift.transport.TSocket;
import org.apache.thrift.transport.TTransport;
import org.apache.thrift.transport.TTransportException;
import lxf.service.*;
/**
* blog http://www.micmiu.com
*
* @author Michael
*
*/
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);
// 协议要和服务端一致
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("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();
int max = 10000;
Long start = System.currentTimeMillis();
for(int i=0; i<=max; i++)
{
client.startClient("Liangxifeng Hello!");
}
Long end = System.currentTimeMillis();
Long elapse = end - start;
int perform = Double.valueOf(max / (elapse / 1000d)).intValue();
System.out.print("thrift " + max + " 次RPC调用,耗时:" + elapse + "毫秒,平均" + perform + "次/秒");
}
}
-
执行java main方法, 成功结果:
三. 通过php作为客户端, 调用以上服务端的 sayHello
方法
参考: 使用php使用thrift
- 使用命令行生成 php 的接口文件, 会生成在gen-php目录下
thrift -r -gen php HelloWorldService.thrift
- 随便找个地方 创建一个目录
thrift
, 将gen-php目录copy到新建的thrift
目录下
mkdir thrift
cp -r gen-php thrift
- 新建php客户端
client.php
registerNamespace('Thrift', THRIFT_ROOT);
$loader->registerDefinition('Service', 'gen-php');
$loader->register();
//use Thrift\Transport\TPhpStream;
use Thrift\Protocol\TBinaryProtocol;
use Thrift\Transport\TSocket;
use Thrift\Transport\TBufferedTransport;
use Thrift\Exception\TException;
try {
//仅在与服务端处于同一输出输出流有用
//使用方式:php Client.php | php Server.php
//$transport = new TBufferedTransport(new TPhpStream(TPhpStream::MODE_R | TPhpStream::MODE_W));
//socket方式连接服务端
//数据传输格式和数据传输方式与服务端一一对应
//如果服务端以http方式提供服务,可以使用THttpClient/TCurlClient数据传输方式
$transport = new TBufferedTransport(new TSocket('localhost', 9090));
$protocol = new TBinaryProtocol($transport);
//$client = new \Services\HelloWorld\HelloWorldClient($protocol);
$client = new \LxfService\HelloWorldServiceClient($protocol);
$transport->open();
//同步方式进行交互
$recv = $client->sayHello('Courages');
echo "\n sayHello11dd:".$recv." \n";
//异步方式进行交互
$client->send_sayHello('Us');
echo "\n send_sayHello \n";
$recv = $client->recv_sayHello();
echo "\n recv_sayHello:".$recv." \n";
$transport->close();
} catch (TException $tx) {
print 'TException: '.$tx->getMessage()."\n";
}
-
使用php端的client, 请求java端的sayHello(), 执行 php client.php , 成功输出:
练习代码地址
参考:
https://zhuanlan.zhihu.com/p/26993406
http://m.blog.csdn.net/yinwenjie/article/details/49620623
http://m.blog.csdn.net/yinwenjie/article/details/49685763
http://m.blog.csdn.net/yinwenjie/article/details/49869535
http://m.blog.csdn.net/yinwenjie/article/details/49976237