==== 创建thrift文件 ====
按thrift语法格式编写一个文件,这个文件定义了RPC的接口和数据类型
Hello.thrift
namespace java service.demo
service Hello{
string helloString(1:string para)
i32 helloInt(1:i32 para)
bool helloBoolean(1:bool para)
void helloVoid()
string helloNull()
}
其中定义了服务叫 Hello, 有五个方法,每个方法包含一个方法名,参数列表和返回类型。每个参数包括参数序号,参数类型以及参数名。 Thrift 是对 IDL(Interface Definition Language) 描述性语言的一种具体实现。因此,以上的服务描述文件使用 IDL 语法编写。使用 Thrift 工具编译 Hello.thrift,就会生成相应的 Hello.java 文件。该文件包含了在 Hello.thrift 文件中描述的服务 Hello 的接口定义,即 Hello.Iface 接口(server端需要实现的接口),以及服务调用的底层通信细节,包括客户端的调用逻辑 Hello.Client (client端需要实现的接口)以及服务器端的处理逻辑 Hello.Processor,用于构建客户端和服务器端的功能。
=== 生成java语言的rpc框架 ===
thrift -r --gen java Hello.thrift
这时候会生成一个Hello.java的源文件。这个文件就包含了rpc框架的实现(server端,client端都需要用到这个文件)
==== 服务端实现 ====
将上一步生成的Hello.java拷贝到当前项目中
创建 HelloServiceImpl.java 文件并实现 Hello.java 文件中的 Hello.Iface 接口
HelloServiceImpl.java
package service.demo;
import org.apache.thrift.TException;
public class HelloServiceImpl implements Hello.Iface {
@Override
public boolean helloBoolean(boolean para) throws TException {
return para;
}
@Override
public int helloInt(int para) throws TException {
try {
Thread.sleep(20000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return para;
}
@Override
public String helloNull() throws TException {
return null;
}
@Override
public String helloString(String para) throws TException {
System.out.println("recv: "+ para);
return "return: "+ para;
}
@Override
public void helloVoid() throws TException {
System.out.println("Hello World");
}
}
创建服务器端实现代码,将 HelloServiceImpl 作为具体的处理器传递给 Thrift 服务器
HelloServiceServer.java
package service.server;
import org.apache.thrift.TProcessor;
import org.apache.thrift.protocol.TBinaryProtocol;
import org.apache.thrift.protocol.TBinaryProtocol.Factory;
import org.apache.thrift.server.TServer;
import org.apache.thrift.server.TThreadPoolServer;
import org.apache.thrift.transport.TServerSocket;
import org.apache.thrift.transport.TTransportException;
import service.demo.Hello;
import service.demo.HelloServiceImpl;
public class HelloServiceServer {
/**
* 启动 Thrift 服务器
* @param args
*/
public static void main(String[] args) {
try {
// 设置服务端口为 7911
TServerSocket serverTransport = new TServerSocket(7911);
// 设置协议工厂为 TBinaryProtocol.Factory
Factory proFactory = new TBinaryProtocol.Factory();
// 关联处理器与 Hello 服务的实现
TProcessor processor = new Hello.Processor(new HelloServiceImpl());
//TServer server = new TThreadPoolServer(processor, serverTransport,
proFactory);
TServer server = new TThreadPoolServer(new TThreadPoolServer.Args(serverTransport).processor(processor));
System.out.println("Start server on port 7911...");
server.serve();
} catch (TTransportException e) {
e.printStackTrace();
}
}
}
maven配置
org.apache.thrift
libthrift
0.9.2
# 官方只给了上面一个配置,结果运行错误,网上搜的答复是再添加下面这个配置(错误解决)
org.slf4j
slf4j-api
1.7.6
compile
true
==== 客户端实现(java) ====
将上一步生成的Hello.java拷贝到当前项目中
创建客户端实现代码,调用 Hello.client 访问服务端的逻辑实现
HelloServiceClient.java
package service.client;
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;
import service.demo.Hello;
public class HelloServiceClient {
/**
* 调用 Hello 服务
* @param args
*/
public static void main(String[] args) {
try {
// 设置调用的服务地址为本地,端口为 7911
TTransport transport = new TSocket("localhost", 7911);
transport.open();
// 设置传输协议为 TBinaryProtocol
TProtocol protocol = new TBinaryProtocol(transport);
Hello.Client client = new Hello.Client(protocol);
// 调用服务的 helloVoid 方法
System.out.println(client.helloVoid());
transport.close();
} catch (TTransportException e) {
e.printStackTrace();
} catch (TException e) {
e.printStackTrace();
}
}
}
==== 客户端实现(python) ====
初始化环境
# 安装thrift依赖的库
sudo easy_install pip
sudo pip install thrift
修改Hello.thrift文件 (将javas 改成 py)
namespace py service.demo
service Hello{
string helloString(1:string para)
i32 helloInt(1:i32 para)
bool helloBoolean(1:bool para)
void helloVoid()
string helloNull()
}
生成python的rpc框架
thrift -r --gen py Hello.thrift
命令执行之后会生成Hello.py和一些其他文件。
我在当前目录下新建一个fang.py,代码如下
我为了方便测试,直接在当前目录下创建了fang.py。如果Python项目放在其他路径,一定要保证Hello.py及其依赖的文件都能被import进来
import sys
from Hello import Client
from thrift import Thrift
from thrift.transport import TSocket
from thrift.transport import TTransport
from thrift.protocol import TBinaryProtocol
from thrift.protocol import TCompactProtocol
def run():
try:
transport = TSocket.TSocket('master', 7911)
transport = TTransport.TBufferedTransport(transport)
protocol = TBinaryProtocol.TBinaryProtocol(transport)
# 一定要保证和服务器端的协议相同
#protocol = TCompactProtocol.TCompactProtocol(transport)
client = Client(protocol)
transport.open()
print client.helloString("python")
transport.close()
except Thrift.TException, tx:
print '%s' % (tx.message)
if __name__ == '__main__':
run()
client端发送的协议一定要和server端接收的协议相同