使用Thrift框架实现Java远程调用Python

一、前言:

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:
使用Thrift框架实现Java远程调用Python_第1张图片
图2-1

生成的文件目录结构如图2-2:
使用Thrift框架实现Java远程调用Python_第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   : [email protected]
    @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:
使用Thrift框架实现Java远程调用Python_第3张图片
图2-3

Java项目文件结构如下图2-4:
使用Thrift框架实现Java远程调用Python_第4张图片
图2-4

2.运行服务器代码。见图2-5:

使用Thrift框架实现Java远程调用Python_第5张图片
图2-5

3.运行Java项目调用Python服务。见图2-6

使用Thrift框架实现Java远程调用Python_第6张图片
图2-6

到此,我们就学会了如何使用Thrift框架实现Java远程调用Python。

你可能感兴趣的:(使用Thrift框架实现Java远程调用Python)