# 微服務怎麼溝通?
我們在工作上做過一些分散式的開發與服務間的溝通。有些是透過開放 HTTP 服務。對於系統間的非同步訊息傳送,我公司使用 FubuMVC 與它的 .Net Core 取代物 "Jasper" 做為 service bus (translate "Jasper" to "MassTransit" or "NServiceBus" when you read this). 此格文是給我們團隊的架構的建議的草案,讓我們團隊為產品選擇何者做為微服務架構的一部份時有個參考。如果我同事看到這篇而有不同意的話,不用擔心。這份文件是活的,總是能討論的。
微服務通常需要傳送訊息給別人或處理別人的訊息,也許是微服務或客戶端。因此,為服務間通訊好好思考是值得的。
我們通常使用 HTTP 或 Jasper/FubuMVC service bus 做為服務間溝通。在思考如何選擇服務間溝通的工具之前,先要想想你的訊息的要求是什麼。服務間溝通約略是以下幾個分類:
1. Publish/Subscribe 非同步廣播一個訊息到所有的訂閱者,不預期一個立即的回應。它與「射後不理」的差異是隱含「保證送達」,也就是訊息會持續保留,直到它被發布出去。Jasper/FubuMVC service bus 有做到「保證送達」,它透過在 LightingQueue 的持續式 "store and forward" 機制,而且最後我們把 RabbitMQ 放進 Docker'ized hosting。
2. Request/Reply 呼叫另一個服務且期待一個回應。從 web service 查詢資料是一個例子。透過 service bus 送訊息且期待一個回應也是一個例子。query handler 就是 request/reply 的範例。
3. Fire and Forget 送出一個 request,然後不管任何回應,不在乎回應是否有來。這種模式多用在效能優先且訊息不是很要緊的情況。Jasper/FubuMVC 使用在 node 內通訊,用以協調訂閱與健康檢查,這是透過 LightningQueue 在 "fire and forget" 的模式來做。
## 以下情況使用 HTTP Service:
* 你的服務要開放 API 給外部使用者。
* 你的服務要給網頁瀏覽器使用。
* 你要開放查詢端點( query endpoint) 給其他服務,它們需要拿到資料馬上使用的方式。
* 你不需要「保證送達」。
* 你在前期不清楚未來你的服務的客戶端會是什麼其他的機制。目前 HTTP 普通存在於所有平台。
* 你需要開放你的服務給「非.Net」客戶端。用現存其他平台的 service bus 是完全可能的,但在這個情況,用 HTTP 端點會比較少阻力。
## 以下情況使用 Service Bus:
* 你需要耐用的 publish/subscribe 的模式。如果你的服務不需要等待下家系統的回應,你需要的可能是 publish/subscribe。
* 如果你會同一個訊息給不同的訂閱者。
* 如果你需要支援「動態訂閱」。也就是讓其他服務可以到你的服務註冊,然後從你的服務接收訊息。
* 如果你要「射後不理」的訊息方式,使用 service bus 在 LightningQueue 的 non-persistent mode。(參考 ZeroMQ)
* 你也許需要 Jasper/FubuMVC 裡的 "delayed message" 的好處。
* 你需要實作長命服務,例如 saga workflow
* 雖然可利用限縮 HTTP request 來控制,但透過 servcie bus 後面的 message queue 來處理大量負載會更簡單有效。
* 如果 message 處理順序很重要,你需要在 servcie bus 排隊。
## 灰色地帶
比較 HTTP 與 service bus 不是完全黑與白的選擇。service bus 也支援 request/reply 模式,你也可以用 HTTP 來做射而不理。兩個招數可以與我們現存的技術堆疊水平擴展。Jasper 最終會支援 HTTP 傳輸以及更有效率的 request/reply,這讓情況更混亂。如果你感覺不是很清楚哪個方向才對,那你的團隊所熟悉的方法會是較可接受的選擇。很可能,這意謂著,使用常見的 ASP.NET Core 堆疊給 HTTP Service 使用,而不是我們今天定做的 service bus 技術。
## 避免以下整合的方式
因為外部客戶端的關係,我們會必須使用下列的方式。但是非常強烈建議不要這麼做:
* publish 檔案到檔案系統及監控目錄
* publish 檔案到 FTP server
* 使用共享資料庫。關聯式資料庫的排隊機制不是很有效率,而且我們也不想要服務之間藉著共享資料庫而有太硬的耦合。
不同意嗎?還有什麼要加的?不用客氣,請幫我讓這個列表更圓滿,可以在下方留言。
原文連結:https://jeremydmiller.com/2017/05/24/how-should-microservices-communicate/