Python Thrift 簡單示例


本文基於Thrift-0.10,使用Python實現服務器端,使用Java實現客戶端,演示了Thrift RPC調用示例。Java客戶端提供兩個字符串參數,Python服務器端計算這兩個字符串的相似度,並返回相似度結果(double類型,范圍[0, 1],0表示不相似,1表示完全相同)

一,環境安裝

開發環境:Windows10,PyCharm2016,Anaconda3,Python3.6

首先安裝python 的thrift包:windows打開Anaconda prompt,輸入:conda install -c anaconda thrift   安裝thrift包。

輸入:conda list 可查看系統中已經安裝了哪些包,及包的版本,如下圖所示:我們安裝的是:thrift-0.10.0

在寫代碼之前,需要先定義一個 .thrift文件,然后使用Thrift Compiler生成相應的Thrift服務需要依賴的“文件”

①定義.thrift文件

namespace py similarityservice
namespace java similarityservice

service ChatSimilarityService{
    double similarity(1:string chat1, 2:string chat2),
}

namespace提供了一種組織代碼的方式。其實就是,生成的文件放在:similarityservice這個文件夾下。

由於前面的Python安裝的thrift-0.10,因此在官網上下載:thrift-0.10.exe,將它放在與 .thrift相同的目錄下,cmd切換到該目錄下,執行命令:

.\thrift-0.10.0.exe --gen py chat_similarity.thrift

生成的文件如下,將它們放在合適的python包下,即可供python 服務端程序 import 了。

 

二,Python服務端實現

pycharm thrift插件支持

可以去pycharm插件官網下載一個thrift插件,安裝好之后,編寫 .thrift 文件能夠自動補全提示。

服務端的實現 主要有以下五方面:(個人理解,可能有錯)

①Handler

服務端業務處理邏輯。這里就是業務代碼,比如 計算兩個字符串 相似度

②Processor

從Thrift框架 轉移到 業務處理邏輯。因此是RPC調用,客戶端要把 參數發送給服務端,而這一切由Thrift封裝起來了,由Processor將收到的“數據”轉交給業務邏輯去處理

③Protocol

數據的序列化與反序列化。客戶端提供的是“字符串”,而數據傳輸是一個個的字節,因此會用到序列化與反序列化。

④Transport

傳輸層的數據傳輸。

⑤TServer

服務端的類型。服務器以何種方式來處理客戶端請求,比如,一次Client請求創建一個新線程呢?還是使用線程池?……可參考:阻塞通信之Socket編程

TSimpleServer —— 單線程服務器端使用標准的阻塞式 I/O

TThreadPoolServer —— 多線程服務器端使用標准的阻塞式 I/O

TNonblockingServer —— 多線程服務器端使用非阻塞式 I/O

 

把上面生成的thrift文件復制到 thrift_service包下,如下圖:

 

整個python 服務端的完整代碼如下:

 1 from thrift.protocol import TBinaryProtocol
 2 from thrift.server import TServer
 3 from thrift.transport import TSocket, TTransport
 4 
 5 from text.thrift_service.similarityservice import ChatSimilarityService
 6 
 7 from difflib import SequenceMatcher
 8 from pypinyin import pinyin
 9 import zhon
10 import pypinyin
11 from zhon.hanzi import punctuation
12 import re
13 
14 __HOST = '127.0.0.1'
15 __PORT = 9090
16 
17 
18 def similar_num(list1, list2):
19     return len(set(list1).intersection(list2))
20 
21 
22 def similar_ration(str1, str2):
23     return SequenceMatcher(lambda x: x == ' ', str1, str2).ratio()
24 
25 class SimilarityHandler(ChatSimilarityService.Iface):
26     def __init__(self):
27         self.log={}
28     def ping(selfs):
29         print('ping')
30 
31     def similarity(self, chat1, chat2):
32         #去掉中文字符串中的特殊標點符號
33         list1 = re.findall('[^{}]'.format(zhon.hanzi.punctuation), chat1)
34         list2 = re.findall('[^{}]'.format(zhon.hanzi.punctuation), chat2)
35 
36         #將標點符號轉換成拼音
37         pinyin1 = pinyin(list1, style=pypinyin.STYLE_NORMAL)
38         pinyin2 = pinyin(list2, style=pypinyin.STYLE_NORMAL)
39 
40         #將所有的拼音統一保存到 單個list 中
41         pinyin_list1 = [word[0] for word in pinyin1]
42         pinyin_list2 = [word[0] for word in pinyin2]
43 
44         #計算 list 中元素相同的個數
45         result1 = similar_num(pinyin_list1, pinyin_list2)
46 
47         #list convert to string
48         str1_pinyin = ''.join(pinyin_list1)
49         str2_pinyin = ''.join(pinyin_list2)
50         #計算字符串的相似度
51         result2 = similar_ration(str1_pinyin, str2_pinyin)
52 
53         print('ratio:{}, nums:{}'.format(result2, result1))
54         return result2
55 
56 
57 if __name__ == '__main__':
58     handler = SimilarityHandler()
59     processor = ChatSimilarityService.Processor(handler)
60     transport = TSocket.TServerSocket(host=__HOST, port=__PORT)
61     tfactory = TTransport.TBufferedTransportFactory()
62     pfactory = TBinaryProtocol.TBinaryProtocolFactory()
63 
64     server = TServer.TThreadPoolServer(processor, transport, tfactory, pfactory)
65 
66     print('Starting the server')
67     server.serve()
68     print('done')

這里簡單地介紹下實現思路:

①使用python 的 zhon 包過濾掉中文中出現的標點符號等特殊字符

②python的 pypinyin 包 將中文轉換成字符串(其實也可以直接比較中文字符串的相似度,但我這里轉換成了拼音,就相當於比較英文字符串了)

③使用python 的 difflib 包中的SequenceMatcher 類來計算兩個字符串之間的相似度

 

三,Java客戶端實現

①在maven工程的pom.xml中添加thrift依賴。這里的libthrift版本、windows10下載的thrift compiler版本(thrift-0.10.0.exe),還有 python的 thrift包的版本 最好保持一致。

        <!-- https://mvnrepository.com/artifact/org.apache.thrift/libthrift -->
        <dependency>
            <groupId>org.apache.thrift</groupId>
            <artifactId>libthrift</artifactId>
            <version>0.10.0</version>
        </dependency>

②cmd命令行執行:.\thrift-0.10.0.exe --gen java chat_similarity.thrift  生成 ChatSimilarityService.java 文件,Java 客戶端代碼需要依賴它。

 

整個Java Client的代碼如下:

 1 import thrift.similarityservice.ChatSimilarityService;
 2 import org.apache.thrift.TException;
 3 import org.apache.thrift.protocol.TBinaryProtocol;
 4 import org.apache.thrift.protocol.TProtocol;
 5 import org.apache.thrift.transport.TSocket;
 6 import org.apache.thrift.transport.TTransport;
 7 
 8 /**
 9  * Created by Administrator on 2017/12/20.
10  */
11 public class SimilarityThriftClient {
12 
13     public static void main(String[] args) {
14         try {
15             TTransport transport;
16             transport = new TSocket("127.0.0.1", 9090);
17             transport.open();
18 
19             TProtocol protocol = new TBinaryProtocol(transport);
20             ChatSimilarityService.Client client = new ChatSimilarityService.Client(protocol);
21             perform(client);
22             transport.close();
23 
24         } catch (TException e) {
25             e.printStackTrace();
26         }
27     }
28     private static void perform(ChatSimilarityService.Client client)throws TException {
29         String chat1 = "您好。";
30         String chat2 = "你好";
31         double ratio = client.similarity(chat1, chat2);
32         System.out.println(ratio);
33     }
34 }

 

四,總結

本文介紹了一個簡單的 Python Server、Java Client的Thrift服務調用示例。關於Thrift可參考:

Thrift Tutorial

Apache Thrift - 可伸縮的跨語言服務開發框架

Thrift 安裝及使用

 

原文:Python Thrift 簡單示例


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2026 CODEPRJ.COM