前言之前介绍了Apache Thrift的快速入门,我们使用java作为客户端,使用java作为服务器端Apache Thrift及其入门,我们知道RPC框架的一个基本特征就是支持异构语言之间的调用,本篇博客介绍异构语言之间的调用。
Apache Thrift可以在文件中定义数据类型和服务接口。编译器根据idl(接口定义文件)文件可以生成消息传输类型的Message对象,也生成RPC语言网络传输的代码,使得我们可以跨语言跨平台的调用服务。 Python作为Client,Java作为Serveridl文件(接口描述文件),定义了结构体(struct),异常(exception)和服务(service): namespace java thrift.generated
namespace py py.thrift.generated
typedef i16 short
typedef i32 int
typedef i64 long
typedef bool boolean
typedef string String
struct Person{
1: optional String username,
2: optional int age,
3: optional boolean married
}
exception DataException{
1: optional String message,
2: optional String callStack,
3: optional String date
}
service PersonService{
Person getPersonByUsername(1: required String username) throws (1: DataException dateException),
void savePerson(1: required Person person) throws (1: DataException dataException)
}
使用thrift编译器生成编译文件
java生成的代码
python生成的代码
加入Thrift依赖,pom文件: dependency>
groupId>org.apache.thriftgroupId>
artifactId>libthriftartifactId>
version>0.10.0version>
dependency>
python依赖要自己编译一下官方的包下载地址,到解压后的lib目录下进入py目录下进行编译得到Apache Thrift 项目中所使用的python库(lib目录下有Apache Thrift 支持的各种语言的库):
安装python相应的包 ➜ py sudo python setup.py install
生成的依赖位于/Library/Python/2.7/site-packages/
Python作为Client,Java作为ServerJava Server编写java服务器端实现代码(一般服务器端要编写一个业务代码实现供客户端调用,还有一个服务代码): public class PersonServiceImpl implements PersonService.Iface{
@Override
public Person getPersonByUsername(String username) throws DataException, TException {
System.out.println('Got client Param:' username);
Person person = new Person();
person.setUsername(username);
person.setAge(32);
person.setMarried(true);
return person;
}
@Override
public void savePerson(Person person) throws DataException, TException {
System.out.println('Got Client Param: ');
System.out.println(person.getUsername());
System.out.println(person.getAge());
System.out.println(person.isMarried());
}
}
服务端:
python的客户端:将上面自动生成的代码拷贝到python项目中, python生成的代码
py_client.py代码: # _*_ coding:utf-8 _*_
__author__ = '作者'
# 导入thrift的包
from py.thrift.generated import PersonService
from py.thrift.generated import ttypes
from thrift import Thrift
from thrift.transport import TSocket
from thrift.transport import TTransport
from thrift.protocol import TCompactProtocol
import sys
# 解决中文编码问题
reload(sys)
sys.setdefaultencoding('utf8')
try:
tSocket = TSocket.TSocket('localhost',8899)
tSocket.setTimeout(600)
# 与java服务器一样使用相同的传输协议,数据的传输方式,服务模型
transport = TTransport.TFramedTransport(tSocket)
protocal = TCompactProtocol.TCompactProtocol(transport)
client = PersonService.Client(protocal)
transport.open()
# 调用getPersonByUsername方法返回一个person对象
person = client.getPersonByUsername('张三')
print person.username
print person.age
print person.married
print '--------------'
newPerson = ttypes.Person()
newPerson.username ='lisi'
newPerson.age = 30
newPerson.married =True
client.savePerson(newPerson)
transport.close()
except Thrift.TException,tx:
print '%s' % tx.message
启动java服务器端和python客户端,
java服务器端的打印结果: Got client Param:张三
Got Client Param:
lisi
30
true
java客户端,python服务器端服务器端要编写服务接口的实现和服务器端代码:
python 服务器端代码 # _*_ coding:utf-8 _*_
__author__ = '作者'
# 导入包
from py.thrift.generated import PersonService
from PersonHandler import PersonHandler
from thrift import Thrift
from thrift.transport import TSocket
from thrift.transport import TTransport
from thrift.protocol import TCompactProtocol
from thrift.server import TServer
try:
personHandler = PersonHandler()
processor = PersonService.Processor(personHandler)
serverSocket = TSocket.TServerSocket(port=8899)
# 传输方式工厂
transportFactory = TTransport.TFramedTransportFactory()
# 协议工厂
protocolFactory = TCompactProtocol.TCompactProtocolFactory()
server = TServer.TSimpleServer(processor,serverSocket,transportFactory,protocolFactory)
server.serve()
except Thrift.TException, ex:
print '%s' % ex.message
java客户端:
启动python服务器端和java客户端,python服务器端控制台打印: Got client param: 张三
Got client param:
李四
30
True
java客户端代码:
总结比较一下Apache thrift与Protobuf之间的区别:单纯的只看Protobuf本身,Protobuf只是一个序列化与反序列化的一个库而已,而Protobuf并没有提供网络传输载体,我们之前的netty与Protobuf结合就是使用netty作为网络传输组件(也就是说netty作为RPC框架中的Transport(传输方式)组件),而Protobuf作为Protocal(传输协议)组件。而Apache thrift本身就是一个跨语言的RPC框架,可以直接通过thrift就可以客户端与服务器之间的通信(通过idl文件生成的代码即提供了传输协议,也提供了网络传输方式)。基于Protobuf没有提供网络传输组件,google又推出了自己的RPC框架GRPC,GRPC是基于Protobuf 3.0版本,基于.proto文件不仅能生成序列化反序列化程序代码,也可以生成传输层次的代码。 |
|
来自: liang1234_ > 《rpc和restful》