天天看點

手把手教你學Dapr - 4. 服務調用

通過使用服務調用,您的應用程式可以使用标準的gRPC或HTTP協定與其他應用程式可靠、安全地通信。

先問幾個問題:

如何發現和調用不同服務的方法

如何安全地調用其他服務,并對方法應用通路控制

如何處理重試和瞬态錯誤

如何使用分布式跟蹤名額來檢視調用圖來診斷生産中的問題

此時你會發現這些事情HttpClientFactory沒有幫你完成,而在微服務中這些又是必不可少的能力,接下來看看服務調用都做了什麼

先看一下兩個服務之間的調用順序

手把手教你學Dapr - 4. 服務調用

服務A 向服務B發起一個HTTP/gRPC的調用。調用轉到了本地的Dapr sidecar

Dapr使用名稱解析元件發現服務B的位置

Dapr 将消息轉發至服務 B的 Dapr sidecar

注: Dapr sidecar之間的所有調用都通過gRPC來提高性能。 僅服務與 Dapr sidecar之間的調用可以是 HTTP或gRPC

服務B 的 Dapr sidecar将請求轉發至服務B 上的特定端點 (或方法) 。 服務B 随後運作其業務邏輯代碼

服務B 發送響應給服務A。 響應将轉至服務B 的Dapr sidecar

Dapr 轉發響應至服務A 的 Dapr sidecar

服務 A 接收響應

預設情況下,調用同一個命名空間的其他服務可以直接使用AppID(假設是:nodeapp)

服務調用也支援跨命名空間調用,在所有受支援的宿主平台上,Dapr AppID遵循FQDN格式,其中包括目标命名空間。

FQDN:(Fully Qualified Domain Name)全限定域名:同時帶有主機名和域名的名稱。(通過符号“.”) 例如:主機名是bigserver,域名是mycompany.com,那麼FQDN就是bigserver.mycompany.com

​ 注:FQDN是通過符号<code>.</code>來拼接域名的,這也就解釋了AppID為什麼不能用符号<code>.</code>,這裡不記住的話,應該會有不少小夥伴會踩坑

​ 比如.net開發者習慣用 <code>A.B.C</code> 來命名項目,但AppID需要把<code>.</code>換成<code>-</code>且所有單詞最好也變成小寫 (a-b-c),建議把它變成約定遵守

比如調用命名空間:production,AppID:nodeapp

這在K8s叢集中的跨名稱空間調用中特别有用

通過托管平台上的互相(mTLS)身份驗證,包括通過Dapr Sentry服務的自動證書轉移,可以確定Dapr應用程式之間的所有調用的安全。 下圖顯示了自托管應用程式的情況。

應用程式可以控制哪些其他應用程式可以調用它們,以及通過通路政策授權它們做什麼。 這使您能夠限制具有個人資訊的敏感應用程式不被未經授權的應用程式通路,并結合服務到服務的安全通信,提供了軟多租戶部署。

具體的通路控制後續章節會介紹

在調用失敗和瞬态錯誤的情況下,服務調用執行自動重試,并在回退時間段内執行。

注:自動重試,預設是開啟的,可以關。但如果不關且業務又不支援幂等是很危險的。建議服務的接口要設計支援幂等,這在微服務裡也是一個标配的選擇。

導緻重試的錯誤有: 網絡錯誤,包括端點不可用和拒絕連接配接。 由于在調用/被調用的Dapr sidecars上更新證書而導緻的身份驗證錯誤。 每次呼叫重試的回退間隔為1秒,最多為3次。 通過gRPC與目标Sidecar連接配接的逾時時間為5秒

Dapr可以在各種托管平台上運作。 為了啟用服務發現和服務調用,Dapr使用可插拔的名稱解析元件。 例如,K8s名稱解析元件使用K8s DNS服務來解析叢集中運作的其他應用程式的位置。 自托管機器可以使用mDNS名稱解析元件。 Consul名稱解析元件可以在任何托管環境中使用,包括K8s或自托管環境

劃重點,自托管機器使用mDNS,在開發環境中後面文章會推薦VS上的無縫開發體驗,就是基于mDNS的 但它有點點小問題,我們已經解決了。你隻需要像開發一個控制台程式一樣,基于Minimal API開心的F5就可以了 建議還沒有了解Minimal API的小夥伴可以研究起來了,真香

一圖勝千言,就使用mDNS輪着調用

手把手教你學Dapr - 4. 服務調用

預設情況下,将跟蹤應用程式之間的所有調用,并收集名額,以提供應用程式的洞察力和診斷,這在生産場景中尤其重要。 這為您提供了服務之間調用的調用圖和名額。

pythonapp 通過Dapr sidecar調用nodeapp,通過服務調用的API及gRPC代理依然是上面見到的那個調用流程,做到了語言無關

手把手教你學Dapr - 4. 服務調用

建立<code>ASP.NET Core空</code>項目,并修改<code>launchSettings.json</code>,讓啟動HTTP的啟動端口變為5000

profiles.Assignment.Server.applicationUrl 的值改為 "https://localhost:6000;http://localhost:5000"

修改<code>Program.cs</code>檔案

此時一共有4個服務

/ :Post方法,列印Hello!

/Hello1:Get方法,列印Hello World1!,傳回Hello World1!

注:傳回的類型要是Json字元串,友善SDK反序列化

/Hello2:Post方法,列印Hello World2!

/Hello3:不帶字尾表示适配所有方法,列印Hello World3!

運作<code>Assignment.Server</code>:在目錄<code>dapr-study-room\Assignment04\Assignment.Server</code>打開指令行工具,并執行下面指令

細心的小夥伴應該可以發現與上一篇的指令有一點點不同,dontet run變成了dotnet watch,這樣會開啟熱重載,友善調試

調用服務:再打開一個新的指令行工具,并執行下面指令

可以發現4個指令都調用成功了,但是<code>Assignment.Server</code>輸出結果有點意外

是的,沒有<code>Hello World1!</code>,那怎麼辦呢?我們把Hello1的指令改一下

invoke調用的輸出除了<code>App invoked successfully</code>以外還多了一行<code>Hello World1!</code>

與此同時<code>Assignment.Server</code>的輸出正确了

除此之外<code>invoke</code>還有一些參數,比如<code>--data</code>,<code>--data-file</code>,喜歡研究Dapr CLI的小夥伴可以繼續嘗試。不過一般情況下用SDK就可以了

建立<code>控制台應用程式</code>項目,使用NuGet包管理器添加<code>Dapr.Client</code> SDK,并修改<code>Program.cs</code>檔案

看幾個細節

DaprClient是從<code>DaprClinetBuilder</code> Build出來的

還有一種方式使用DaprClient,通過DI

首先都是需要添加<code>Dapr.AspNetCore</code> NuGet包

然後開始有分支了,如果是以前Web API的方式可以在Startup.cs檔案<code>ConfigureServices</code>方法加入一行代碼

如果使用Minimal API預設是沒有Controllers的,那可以在<code>var builder = WebApplication.CreateBuilder(args);</code> 之後加入一行代碼

成功的注入進來了,在<code>構造函數</code>或者<code>[FromServices]</code>裡愉快的玩耍吧

HttpMethod.Post 的我都沒有指定,預設就是Post

HttpMethod.Get的時候,傳回值會自動用Json反序列化

不喜歡Json?可以通過 DaprClient.CreateInvokeHttpClient 構造 HttpClient,聰明的你肯定知道後面怎麼辦了

注:

使用指令行工具打開目錄<code>dapr-study-room\Assignment04\Assignment.Client</code>,然後執行指令

如果你不是用VS Code終端的PowerShell執行dapr run就可能遇到下面的錯誤

即便你沒有遇到也建議了解一下如何支援非預設端口

因為上面使用dapr run的時候沒有指定dapr http port,而預設client通路的是3500端口

解決的辦法有兩種:

修改<code>Assignment.Server</code>啟動參數,增加<code>--dapr-http-port 3500</code>,這個方法治标不治本,因為将來我們可能啟動多個服務

修改<code>Assignment.Client</code>的環境變量

首先執行<code>dapr list</code>檢視端口,以下面為例,HTTP PORT是<code>51460</code>

APP ID HTTP PORT GRPC PORT APP PORT COMMAND AGE CREATED PID assignment-server 51460 51461 5000 dotnet watch 7s 2021-10-29 14:13.49 11676

修改<code>Assignment.Client</code>的啟動參數,注意把<code>51460</code>換成你自己的端口,使用<code>PowerShell</code>執行下面指令

再執行一次<code>dotnet run</code>就可以看到正确的輸出結果了

篇幅太長了,舉一反三吧。就是調用<code>InvokeMethodGrpcAsync</code>,然後dapr-http-port換成dapr-grpc-port,DAPR_HTTP_PORT換成DAPR_GRPC_PORT

還記得dapr init的時候docker裡有個zipkin吧,通過zipkin可以看一下調用跟蹤,通過浏覽器打開下面位址

http://localhost:9411/

此時頁面是空的

手把手教你學Dapr - 4. 服務調用

根據步驟操作一下就可以看到了

手把手教你學Dapr - 4. 服務調用

随便點開一行資料尾部的SHOW,就可以看到調用詳情

手把手教你學Dapr - 4. 服務調用

Assignment04

https://github.com/doddgu/dapr-study-room

我們的目标是<code>自由的</code>、<code>易用的</code>、<code>可塑性強的</code>、<code>功能豐富的</code>、<code>健壯的</code>。

是以我們借鑒Building blocks的設計理念,正在做一個新的架構<code>MASA Framework</code>,它有哪些特點呢?

原生支援Dapr,且允許将Dapr替換成傳統通信方式

架構不限,單體應用、SOA、微服務都支援

支援.Net原生架構,降低學習負擔,除特定領域必須引入的概念,堅持不造新輪子

豐富的生态支援,除了架構以外還有元件庫、權限中心、配置中心、故障排查中心、報警中心等一系列産品

核心代碼庫的單元測試覆寫率90%+

開源、免費、社群驅動

還有什麼?我們在等你,一起來讨論

經過幾個月的生産項目實踐,已完成POC,目前正在把之前的積累重構到新的開源項目中

目前源碼已開始同步到Github(文檔站點在規劃中,會慢慢完善起來):

MASA.BuildingBlocks

MASA.Contrib

MASA.Utils

MASA.EShop

BlazorComponent

MASA.Blazor

QQ群:7424099

微信群:加技術營運微信(MasaStackTechOps),備注來意,邀請進群

手把手教你學Dapr - 4. 服務調用

轉載自:(鬼谷子)