一、前言:
Thrift是一种接口描述语言和二进制通讯协议,它被用来定义和创建跨语言的服务。它被当作一个远程过程调用(RPC)框架来使用,能实现无缝的跨平台的高效服务。由于项目使用到了Thrift框架,Java子项目和Python子项目之间的微服务都是通过 Thrift 进行通信的,所以简单的研究了一下。
和传统的RESTful接口相比,RPC接口通过传输层传递数据包,走 TCP协议,效率更高。Thrift 优势在于发送同样的数据,request包 和 response包 要比 HTTP小很多,在整体性能上要优于 HTTP。
二、使用方法
本文是基于Python环境、virtualenv虚拟环境以及Pycharm工具包已经安装好的前提下,编写的操作文档。
注意:Python的版本是2.7.16
Pycharm2019.1.2专业版链接:
https://pan.baidu.com/s/14tvDRCDqhdodjl-aXDESKQ 提取码: exkk
环境准备
从官网上下载 windows 版的 thrift.exe:http://archive.apache.org/dist/thrift/0.9.2/
Pycharm项目虚拟环境安装thrift==0.9.2
requirements.txt文件
thrift==0.9.2
1.首先使用 Thrift 之前需要定义一个 符合Thrift语言规范的.thrift 格式的接口文件,比如 mytest.thrift
const string MESSAGE = "Learning makes me happy!"
service MyTest {
void helloThrift(),
string studyThrift(),
string sayMsg(1:string msg)
}
打开命令行,进入thrift-0.9.2.exe所在目录然后执行:
thrift-0.9.2.exe -gen py mytest.thrift
生成 Python 代码。
继续执行
thrift-0.9.2.exe -gen java mytest.thrift
生成 Java代码。见图2-1:
图2-1
生成的文件目录结构如图2-2:
图2-2
2.将生成的Python代码和Java代码复制到Python项目和Java项目中,并编写Python服务端代码server.py和客户端调用代码JavaToPython.java,代码如下:
server.py
#!/usr/bin/python2.7.16
# -*- coding: utf-8 -*-
"""
@Time : 2020/5/19 18:29
@Author : donnie99
@Email : chd9_com@163.com
@File : server.py
@Software: PyCharm
"""
import sys
sys.path.append('./gen-py')
from chd9.server.mytest import MyTest
from mytest.ttypes import *
from thrift.transport import TSocket
from thrift.transport import TTransport
from thrift.protocol import TBinaryProtocol
from thrift.server import TServer
import socket
class MyTestHandler:
def __init__(self):
self.log = {}
def helloThrift(self):
print "Hello Thrift!"
def studyThrift(self):
print "I'm studying Thrift!"
return "I'm studying Thrift from " + socket.gethostbyname(socket.gethostname())
def sayMsg(self, msg):
print "sayMsg(" + msg + ")"
return "say " + msg + " from " + socket.gethostbyname(socket.gethostname())
handler = MyTestHandler()
processor = MyTest.Processor(handler)
transport = TSocket.TServerSocket('127.0.0.1', 3333)
# 选择传输层
tfactory = TTransport.TBufferedTransportFactory()
# 选择传输协议
pfactory = TBinaryProtocol.TBinaryProtocolFactory()
# 创建服务端
server = TServer.TSimpleServer(processor, transport, tfactory, pfactory)
print "Starting python server..."
server.serve()
JavaToPython.java
package chd9.test;
import chd9.client.MyTest;
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.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* @Author: donnie99
* @Date: 2020/5/19 23:12
* @Version 1.0
*/
public class JavaToPython {
private static final Logger LOGGER = LoggerFactory.getLogger(JavaToPython.class);
private final static String SERVER_IP="127.0.0.1";
private final static Integer SERVER_PORT=3333;
private final static Integer TIMEOUT=60000;
public static void main(String[] args) {
TTransport transport;
TProtocol protocol;
MyTest.Client client;
transport = new TSocket(SERVER_IP,SERVER_PORT,TIMEOUT);
// 协议要和服务端一致
protocol = new TBinaryProtocol(transport);
client = new MyTest.Client(protocol);
String calculateId = "10000106";
try {
System.out.println("[Thrify ], start => ");
transport.open();
LOGGER.info("java端远程调用Python>>>>>>>开始");
//远程调用Python的第一个方法
LOGGER.info("java端远程调用Python>>>>>第一个方法>>>>>>>开始");
client.helloThrift();
LOGGER.info("java端远程调用Python>>>>>第一个方法>>>>>>>结束");
//远程调用Python的第二个方法
LOGGER.info("java端远程调用Python>>>>>第二个方法>>>>>>>开始");
String result = client.studyThrift();
LOGGER.info(result);
LOGGER.info("java端远程调用Python>>>>>第二个方法>>>>>>>结束");
//远程调用Python的第三个方法
LOGGER.info("java端远程调用Python>>>>>第三个方法>>>>>>>开始");
String result1 = client.sayMsg("我学会java远程调用python了");
LOGGER.info(result1);
LOGGER.info("java端远程调用Python>>>>>第三个方法>>>>>>>结束");
} catch (TException e) {
e.printStackTrace();
} finally {
if (null != transport) {
transport.close();
LOGGER.info("java端远程调用Python>>>>>>>结束");
}
}
}
}
Python项目文件结构如下图2-3:
图2-3
Java项目文件结构如下图2-4:
图2-4
2.运行服务器代码。见图2-5:
图2-5
3.运行Java项目调用Python服务。见图2-6
图2-6
到此,我们就学会了如何使用Thrift框架实现Java远程调用Python。