在聊如何使用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/
本文版權歸作者和博客園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文鏈接。