若是咱們想要構建一個生產就緒的系統,那麼必需要權衡全部因素,其中選擇微服務間的鏈接方法更是其中的一個難點。編程
做者在本文中介紹了一些常見的通訊方法,並簡要概述了其項目背景以及爲什麼最終選擇了RPC。服務器
在決定微服務間鏈接方法前,咱們須要搞清楚兩個概念:網絡
在使用服務時如何造成有效負載?是有狀態仍是無狀態?咱們應該採用REST、SOAP、JSON、XML,仍是其餘消息格式?架構
咱們應該用哪一種傳輸協議?應該採用HTTP、HTTP二、消息總線、TCP socket,仍是UDP?框架
一些主流的選項以下:socket
自Roy Fielding提出RESTful架構自提出以來,一直都是備受歡迎的方案,特別是在Web應用的開發中。Fielding提出的約束雖然不是標準,但在聲明咱們的API爲RESTful以前,應該始終遵循這些約束。編程語言
HTTP上有各類各樣的REST,由於沒有強制執行的標準。開發人員能夠自由選擇以JSON、XML或某種自定義格式造成請求有效負載。分佈式
REST over HTTP(S)僅意味着使用REST架構風格並經過HTTP(S)發送請求。函數
例如:JSON-RPC微服務
該選項基本上經過將微服務鏈接到集中消息總線來工做,而且服務之間的全部通訊都經過backbone發送消息來完成。
例如:Python中的Nameko
遠程過程調用在分佈式系統中並不新鮮,它經過在網絡上的另外一個設備上執行函數/方法/過程來工做。
按照RPC標準,RPC 5531:
RPC實現的強制性要求:
例如:gRPC RPyC
咱們有一個一體化Web應用(用Django編寫),性能尚可接受。有些服務能夠做爲單獨的服務解耦。我正在以漸進的方式將咱們的系統架構轉變爲微服務架構,其中一項重要工做是決定通訊方式。
有不少文章主張用REST替換RPC,說RPC是屬於「石器時代」的技術,但也有人說RPC簡單易用。而個人立場是中立的,要根據實際的項目來作選擇。
如下是項目的主要要求:
因爲對調用方的錯誤返回對咱們很重要,RPC是一個很好的候選,由於許多RPC框架將服務器函數中出現的任何異常返回給RPC函數調用方。
大多數RPC框架消除了message broker的須要,所以避免了單點故障。
大多數RPC框架容許遠程過程調用,如:
import my_remote_function try: my_remote_function.validate_user(my_user) except ValueError as e: logging.error(e.message)
還有比RPC更好的選項嗎?
RPC框架大體可分爲如下兩種:
單語框架,僅支持單一編程語言。在Python中這類類別的一個很好的候選者是RPyC。RPyC具備易於使用的標準RPC功能,並使用TCP做爲其傳輸協議。
使用RPyC(單語框架)的優勢是不須要編寫單獨的服務接口。缺點是對不一樣Python版本的支持不足,固然,正如其名稱所暗示的那樣,缺乏對跨語言的支持。
跨語言RPC框架支持多種編程語言,但成本很高。gRPC是我使用的框架之一。
gRPC由Google提供支持,涵蓋了從C++、Ruby、Python到Dart的各類編程語言。爲了支持多種編程語言,必須定義一個通用的服務契約,一般是協議緩衝區(.proto)文件。Service Contract使用服務器提供的參數定義函數,以及要傳輸的消息格式。對於gRPC,將協議緩衝區文件編譯爲特定語言的文件(例如Python中的.py文件),這會在您開始擁有多個版本的service contact時產生問題。這使咱們很難跟蹤不一樣版本的客戶端存根和服務功能。
總結來講,通訊方式須要case by case地選擇,而這些以上基本上是我在選擇微服務之間的通訊媒介時所考慮的問題。