1. 程式人生 > >使用Thrift讓Python和C#可以相互呼叫

使用Thrift讓Python和C#可以相互呼叫

在聊如何使用Thrift讓Python和C#可以互相呼叫之前,我們先來看看下面的話題。

一、什麼是微服務、微服務的特徵、誕生的背景、優勢和不足

  微服務:使用一套小服務來開發單個應用的方式,每個服務執行在 獨立的程序中,一般採用輕量級的通訊機制互聯並且他們可以通過自動化的方式部署。

  微服務的特徵:

  1)單一職責 2)輕量級通訊  3)隔離性 4)有自己的資料 5)技術多樣性

  微服務誕生的背景:

  1)網際網路行業的快速發展 2)敏捷開發,精益方法深入人心  3)容器技術的成熟

  優勢:

  1)獨立性,各自開發自己的模組互不影響  2)敏捷性,能很快響應需求的變化  3)高效團隊  4)技術棧靈活,可以使用多種語言進行混合開發。

  不足:

  1)額外的工作

  拆分的太小,服務越多,服務之間的呼叫 就會過多,造成不必要的效能損耗。
  拆分的太大,就會失去微服務的優勢。
  2)資料的一致性
  單體架構可以通過事務很輕鬆的實現資料的一致性,但是微服務,他們都有自己的資料庫,即使我們在拆分微服務是保證資料庫的聯表操作,儘量讓它在同一個微服務內,但是也很保證沒有這種意外的情況,一旦出現就會對我們的資料一致性造成影響。
  3)溝通成本增加

二、微服務架構帶來的問題

  採用微服務架構會帶來很多問題,在這裡只討論微服務之間是如何通訊的。

  1)從通訊模式的角度考慮:

  一對一還是一對多    ;同步還是非同步

  一對一的非同步,這種模式下有兩種場景:一個是我們給某個服務傳送通知的時候,是一個一對一的非同步,傳送通知不需要等待響應;另一種是我們雖然給對方傳送了一個請求,但是並不要求對方立即響應,而是最為一個回撥的方式作為響應。
釋出訂閱:就是一個服務釋出一個訊息,有很多的訂閱者會同時接到這個訊息,接到這個訊息,並不一定要立即響應。
釋出非同步響應:比如滴滴打車,我在叫一輛車的時候,系統會把訊息傳送給能接收到該訊息的車主,然後來響應。

  2)從通訊協議角度考慮:

   基於http協議涉及rest API ; RPC; MQ

  這裡,只來聊聊RPC,市面上有很多RPC框架,比如:dubbo(阿里)、motan(新浪)、grpc(谷歌)、thrift(Facebook),這麼多RPC框架,如何選擇呢?可以參考下面的幾個方面,來選擇RPC框架--【I/O、執行緒排程模型、多語言支援、序列化方式、服務治理】,在這裡我只演示Thrift的使用,因為我只瞭解Thrift,哈哈哈哈哈。

Thrift是2007年Facebook開發的2008年進入Apache開源專案,是一個跨語言的開發框架,它需要定義一個xxx.thrift的檔案, 來生成各種語言的程式碼,生產之後我們的服務提供者和消費者,都需要把程式碼引進出,服務端把程式碼實現,消費者直接使用API的存根,直接呼叫。支援的語言也比較多,thrift是cs模式,通過客戶端來生成不同語言的程式碼,從而實現了服務端和客戶端不同語言的通訊,在傳輸的序列化上它也支援很多種,比如:二進位制、壓縮、json,xml等
在通訊的模式上,支援很多種,支援阻塞的IO,還有專門傳輸檔案的傳輸方式,線上程模型上,它也支援 很多種,比如單執行緒、執行緒池、多執行緒非阻塞IO模式。

附一張對比圖:

下面我們來看看,在Python和C#之間該如何使用。

三、程式碼演示

版本說明:

  1)Python 3.6.3   Thrift-0.10.0

  2)net core 2.1  Install-Package apache-thrift-netcore   -Version=0.9.3.2

  3)win7

首先到Thrift官網上下載:http://archive.apache.org/dist/thrift/0.9.3/

下載完畢之後,新建一個message.thrift檔案:

namespace py message.api
namespace csharp message.api
service MessageService {
    bool sendMobileMessage();
    bool sendEmailMessage();

}

 服務端:

然後在,改資料夾下,執行cmd,會生成對應的Python程式碼

開啟gen-py的資料夾,顯示如下:

然後,把生成的程式碼和檔案,放到下面新建的Python專案中。

接著使用Pycharm,新建一個Python專案,如下所示:

在message資料夾下新建一個:

message-service.py的檔案
安裝:

程式碼:

from message.api import MessageService
from thrift.transport import TSocket
from thrift.transport import TTransport
from thrift.protocol import TBinaryProtocol
from thrift.server import TServer

# 重寫生成 MessageService類中的兩個方法
class MessageServiceHandler:
    def sendMobileMessage(self):
        print("sendMobileMessage")
        return True

    def sendEmailMessage(self):
        print("sendEmailMessage")
        return True


if __name__ == "__main__":
    handler = MessageServiceHandler()
    processor = MessageService.Processor(handler)
  # 注意,這裡的host要設定為:0.0.0.0,如果設定為127.0.0.1,客戶端在訪問時,報:目標計算積極拒絕 transport
= TSocket.TServerSocket(host="0.0.0.0", port=8800)
  # 傳輸方式 buffer tfactory
= TTransport.TBufferedTransportFactory()
  # 傳輸的資料型別:二進位制 pfactory
= TBinaryProtocol.TBinaryProtocolFactory() server = TServer.TSimpleServer(processor, transport, tfactory, pfactory) print("python thrift server start") server.serve() print("python thrift server exit")

 客戶端:

把 gen-csharp中的 MessageService類複製到該專案下,安裝Thrift對應的.Net Core Nuget包

新建一個.Net Core 控制檯程式:

程式碼:

 static void Main(string[] args)
        {
            using (TSocket socket = new TSocket("localhost", 8800))
       //一定要注意,客戶端使用傳輸協議要和服務端的一致,否則會報錯
using (TTransport transport = new TBufferedTransport(socket))
        
using (TProtocol protocol = new TBinaryProtocol(transport)) using (var client = new MessageService.Client(protocol)) { transport.Open(); Console.WriteLine(client.sendEmailMessage()); ; } Console.ReadKey(); }

最後,確保客戶端和服務端程式碼都沒有問題,先啟動服務端程式碼,再啟動客戶端程式碼,結果如下:

服務端啟動:

客戶端啟動:

結果:

客戶端返回了:True

服務端列印的結果:

到此,C#和Python的相互訪問就實驗成功了,希望對你有幫助,謝謝。

最後,給大家提供一些Thrift的參考文章,因為這些前輩寫的很好,希望對你有幫助。

https://www.cnblogs.com/mumuxinfei/category/597031.html

http://zheming.wang/blog/2014/08/28/94D1F945-40EC-45E4-ABAF-3B32DFFE4043/

注:本篇部落格參考了楊中科老師的Thrift部分和劉果國老師Docker+k8s 

作者:郭崢

出處:http://www.cnblogs.com/runningsmallguo/

本文版權歸作者和部落格園共有,歡迎轉載,但未經作者同意必須保留此段宣告,且在文章頁面明顯位置給出原文連結。