使用Dapr和.NET 6.0進行微服務實戰:Dapr簡介

張飛洪[廈門]發表於2023-01-18

大家好,我是張飛洪,感謝您的閱讀,我會不定期和你分享學習心得,希望我的文章能成為你成長路上的墊腳石,讓我們一起精進。

本文是《使用Dapr和.NET 6.0進行微服務實戰》的第2篇Dapr簡介部分,大致包括:瞭解Dapr,探索Dapr核心元件,設定Dapr環境,構建Dapr簡單示例,閒話不說,我們開始系列旅程吧。

導讀

Dapr全稱Distributed Application Runtime,翻譯過來就是分散式應用程式執行時,在v1.0釋出後得到了極大的發展。

本章將向您介紹Dapr架構的核心概念,為您使用Dapr進行開發做好預熱和準備工作。

可以這麼說,Dapr加速了新的雲原生應用的開發,並簡化了微服務架構的運用。

在本章中,我們將討論以下主題:

  • 簡單瞭解Dapr
  • 探索Dapr核心元件
  • 設定Dapr環境
  • 構建Dapr示例

這些主題是後續使用Dapr和微服務架構的基礎和理論指導。首先,我們進入開篇的第一步,從Dapr的工作原理開始。

1.簡單瞭解Dapr

Dapr是一個事件驅動的、可移植的執行時,由Microsoft使用開源方法建立的,由雲原生計算基金會(CNCF)孵化的專案。

事件驅動(Dapr的定義中強調了這一點)在微服務中扮演著重要的角色;對來自外部系統或第三方的事件作出的反應,同時可以向其他服務轉發新的事件。

Dapr是可移植的,它有三種託管模式。首先它可以在本地機器上自託管,也可以部署到邊緣,或者在Kubernetes上執行。

下圖顯示了Dapr提供的許多構建塊:

從上圖可以看出,Dapr先要執行在微軟Azure、亞馬遜(AWS)、谷歌雲或國內阿里,華為雲上都是沒問題的。

Dapr建立在微軟開發超大規模雲原生應用的經驗基礎上。它的靈感來自Orleans和Service Fabric(服務網格),同時又反哺微軟雲的大規模運用。

1.1Dapr簡史

Dapr於2019年10月首次釋出,您可以在這裡上了解到。

Dapr在2020年9月,在初始開發階段採用了開放式治理模式;請參見下面的描述.

Dapr於2021年2月釋出了面向生產環境的v1.0版本,請參看這裡。2021年11月,Dapr作為孵化專案加入CNCF;請參閱公告

Dapr為開發人員提供了一種面向微服務架構的設計工具和執行時,以便更好地執行我們的應用。

微服務提供了面向高可用,高併發等一系列的好處,但是同時帶來了響應的複雜行,比如熔斷限流,服務呼叫監控,負載均衡等,通常會給開發團隊帶來沉重的負擔。

而Dapr執行時剛好可以幫助我們簡化以上覆雜性操作,我們看看具體如何操作:


(圖1.2)
如圖1.2所示,它顯示了兩種Dapr託管模式:Dapr執行時在邊車(sidecar)程式中執行,將應用的大部分複雜性提升到一個單獨的環境中,這大大簡化了開發和操作。這些sidecar程式在您的開發環境的本地執行,或者在Kubernetes的Pod的容器中執行。

從應用程式的角度來看,Dapr是一種應用程式設計介面(API),可以透過超文字傳輸協議(HTTP)、遠端過程呼叫(gRPC)直接訪問,或者更簡單地說,可以透過適用於.NET、Java、Go、Python、PHP、JavaScript、C++和Rust語言的任何軟體開發工具包(SDK)直接訪問。

當然,你也可以不必採用Dapr SDK(稍後將體驗到),對Dapr服務的請求可以像對HTTP呼叫一樣簡單,例如:http://localhost:3500/v1.0/invoke//method/。如果您透過Dapr SDK與Dapr互動,或者使用Actor SDK利用Dapr Actor模型,那麼使用SDK確實會帶來許多好處。

您可以在Dapr文件中瞭解有關SDK和支援的語言的更多資訊,網址

我們已經瞭解了Dapr的架構,知道Dapr是什麼了,接下來我們要澄清下Dapr不是什麼了。

1.2Dapr不是什麼

我們從正面瞭解到了Dapr,也許你對此頗感興趣,但是我覺得很有必要全面瞭解Dapr,我們需要介紹一下Dapr不是什麼。這使有利我們消除對Dapr產生的誤解,如下所示:

  • Dapr不會強迫開發人員接受具有嚴格規則和約束的程式設計模型。相反,雖然Dapr把開發人員從微服務架構的複雜性中解放出來,但開發人員並沒有被規定要如何編寫應用程式。例如,對儲存狀態的資料庫的連線的管理是Dapr的責任(後續的狀態管理會看到),當它對微服務應用是透明的。

  • Dapr不是服務網格。雖然Dapr和服務網格可以找到許多相似之處,但Dapr是在應用級別提供能力,而服務網格在基礎架構上執行。如果出現衝突或間歇性問題,開發人員有權決定如何處理Dapr可能返回的錯誤;無論是採用Dapr的重試策略,還是向客戶端返回錯誤,或者補償操作,這些都是隻有開發人員才有許可權做出決定。

Dapr旨在與Istio等服務網格整合,這超出了本專欄的範圍。

  • Dapr不是Microsoft雲服務。它確實幫助開發人員在雲中構建微服務應用程式,它當然提供了許多與Azure雲服務的整合,但它也為AWS、GCP和其他服務提供了同樣多的元件。同時,Azure在具有本機擴充套件的Azure Kubernetes Service(AKS)、具有Dapr策略的Azure API管理以及具有Dapr本機整合的Azure容器應用程式中確實為Dapr提供了豐富的支援。

  • Dapr不是一種僅限.NET的技術。Dapr本身是用Go語言編寫的,任何語言都可以利用它。我們可以使用多種語言的SDK,但也可以選擇直接與Dapr API互動,而無需任何額外的SDK庫。

注意事項
雖然本專欄偏向.NET,但作為示例,我也會演示Dapr和Python的使用關係。

希望以上介紹能讓你對Dapr的瞭解會更加全面、客觀,併為你是否採用這項技術提供選項幫助。接下來,我們將專門介紹Dapr的體系結構。

2.探索Dapr核心元件

Dapr從一開始就被設計為一組可插拔的構建塊,開發人員可以依賴該構建塊或叫基礎設施進行開發,而運維人員可以透過簡單地配置就可以讓使應用適配其託管環境。

以下是Dapr工具和元件的完整列表:

  • Dapr命令列工具(CLI):用於配置、管理和監視Dapr環境的跨平臺命令列工具。它也是用於本地除錯Dapr應用的工具。
  • Dapr Helm Charts:提供了在Kubernetes環境中安裝和更新Dapr的手段。
  • Dapr API:定義應用如何與Dapr執行時互動,使用其構建塊的API。
  • Dapr runtime:這是實現Dapr API的核心。如果您很好奇,可以在Dapr的儲存庫中檢視它是如何開發的.
  • Dapr host:在開發機器上,主機作為獨立程式執行;在Kubernetes中,它是應用pod中的一個sidecar容器。
  • Dapr operator:針對Kubernetes模式,該operator用於管理繫結和配置。
  • Dapr sidecar injector(邊車注入):一旦在Kubernetes下配置了該服務,它會將Dapr sidecar注入到應用程式的pod中。
  • Dapr placement service:該服務的目的是在Dapr pod中分發(或放置)Actor例項。
  • Dapr Sentry(哨兵):一個內建的證照頒發機構(CA),用於頒發和管理Dapr使用的證照,以提供透明的互傳輸層安全(mTLS)。

截至目前v1.9版本,Dapr提供了九大構建塊(building blocks),微服務開發人員可以根據需求選擇性地採用這些構建塊,具體如下:

  1. 服務呼叫(Service invocation):服務呼叫使我們能夠呼叫位於同一宿主環境中的其他服務,同時處理重試策略。在第4章“服務呼叫”中會更詳細地介紹了這個構建塊。
  2. 狀態管理(State management):為了將應用狀態作為一個簡單的鍵值對進行有效管理。Dapr提供了許多狀態儲存,包括Redis、Azure Cosmos DB、Azure SQL Server和PostgreSQL,它們可以透過配置插入。在第5章的“狀態管理簡介”中會詳細探討。
  3. 訊息的釋出和訂閱(pub/sub):pub/sub模式透過交換訊息實現微服務之間的解耦通訊,服務匯流排可以在生產者和消費者之間路由訊息。在第6章的“釋出和訂閱”中會詳細討論該構建塊。
  4. 資源繫結(Resource bindings):這就是Dapr的事件驅動特性所在。透過繫結,您的應用程式可以透過SMS進行觸發(這只是通訊API領域的流行服務之一)。第7章“資源繫結”中會更詳細地介紹這個構建塊。
  5. 參與者(Actors):Actors模式可以理解為單執行緒模型,旨在透過在大量計算單元(Actors)之間分配總請求量的負載來簡化高併發場景,這些計算單元透過一次處理一個Actors的請求,在較小但獨立的範圍內處理任務。在第8章“使用Actors”中會詳聊該構建塊。
  6. 可觀察性:Dapr使開發人員和運維員能夠觀察應用和服務的行為,而無需對它們進行檢測。第11章“跟蹤Dapr應用”中會更詳細地介紹了這個構建塊。
  7. 安全金鑰(Secrets):將安全與程式碼分開是一種良性的做法。Dapr能夠儲存金鑰,並從Kubernetes或Azure金鑰庫等其他元件中引用這些金鑰。
  8. 配置(Configuration):在Alpha狀態的Dapr 1.8版中引入了此構建塊,它解決了檢索應用程式所需配置資料的常見需求。
  9. 分散式鎖(Distributed lock:):Dapr 1.8版在Alpha狀態下引入分散式鎖,它提供了一種強大的基於租約的機制來管理對命名鎖的互斥訪問。應用程式可以使用該鎖來確保多個併發例項對資源的獨佔。
    瞭解了Dapr體系結構和元件後,在開始使用之前,我們需要在我們的開發環境中設定Dapr。

3.設定Dapr環境

Dapr是多個平臺和語言的執行時,本專欄的重點是.NET中的C#,並使用Visual Studio Code作為開發工具。
我們使用的開發環境是Windows,如果你需要有關在Linux或macOS上執行特定操作,建議您檢視Dapr官方文件

Dapr路線圖

Dapr執行時於2021年2月釋出v1.0生產環境版本,我們可以在Dapr官方部落格中檢視到,Dapr於2021年釋出了五個新的次要版本。您可以在Dapr路線圖中檢視。

本專欄中的示例和指令碼已經用Dapr的v1.9進行了更新和測試。

接下來,我們將完成以下步驟:

  • 配置Docker
  • 安裝Dapr CLI
  • 安裝.NET 6.0
  • 安裝VS Code
  • 安裝Windows終端
  • 在自託管模式下安裝Dapr
  • 在Kubernetes上安裝Dapr

配置Docker

Docker的安裝很簡單,我們可以在以下位置找到執行Docker的詳細說明。

安裝Dapr CLI

Dapr執行時安裝也不難,您可以在此訪問安裝。

在Windows上,執行以下命令將CLI安裝到c:\dapr目錄中,並將其新增到使用者PATH環境變數中,以便可以從命令列輕鬆使用工具:
powershell -Command "iwr -useb https://raw.githubusercontent.com/dapr/cli/master/install/install.ps1 | iex"
有關Dapr CLI的更多詳細資訊,請參閱

安裝.NET 6.0

要安裝.NET 6,請參閱,獲取最新二進位制檔案的連結。
.NET 6是.NET的長期支援(LTS)版本,可獲得3年免費支援和更新。
在開發機器上,建議安裝包含執行時的完整版SDK。安裝完成後,我們執行dotnet--info命令進行校驗,成功後,您將看到以下輸出:

安裝VS Code

VS Code是微軟的一個很棒的跨平臺原始碼編輯器。您可以按照以下說明免費安裝它:跳轉

Dapr擴充套件

Dapr有一個VS Code的擴充套件,它有助於導航Dapr本地環境,並簡化除錯配置,我們強烈建議安裝它。

安裝Windows終端

推薦一款不錯的新的Windows終端Windows Terminal,是一款新式、快速、高效、強大且高效的終端應用程式,適用於命令列工具和命令提示符,PowerShell和 WSL 等 Shell 使用者。在接下來的章節中,我們通常必須並行執行多個命令和工具。因此,Windows終端的選項卡功能也是我建議您採用它的原因之一。

在自託管模式下安裝Dapr

Dapr可以以兩種模式初始化:自託管和Kubernetes。

由於打算用於開發環境,所以這裡採用自託管模式,執行Dapr init後,會在本地會預設安裝Redis、Dapr placement services和Zipkin。

這裡要留意的是Dapr init命令,建議在網路比較好的早晨進行初始化,如果是下午或者晚上,可能會無法成功。

預設情況下,Dapr二進位制檔案和預設元件位於%USERPROFILE%.dpr\資料夾中。

例如,在本地開發環境中,Dapr打算用於Redis的埠可能已經被佔用。在這種情況下,您應該確定哪些程式或容器正在使用該埠,並相應地更改它們。

一旦啟動init命令成功,您會看到如下輸出:

PS C:\Repos\practical-dapr\chapter01> dapr init
Making the jump to hyperspace...
Installing runtime version 1.8.4
Downloading binaries and setting up components...
Downloaded binaries and completed components set up.
daprd binary has been installed to C:\Users\dabedin\.dapr\bin.
dapr_placement container is running.
dapr_redis container is running.
dapr_zipkin container is running.
Use `docker ps` to check running containers.
Success! Dapr is up and running. To get started, go here: https://aka.ms/dapr-getting-started

我們可以透過docker ps來驗證一下是否成功:

PS C:\Repos\practical-dapr\chapter01> docker ps --format "{{.
Image}} - {{.Ports}} - {{.Names}}"
daprio/dapr:1.8.4 - 0.0.0.0:6050->50005/tcp, :::6050->50005/tcp
- dapr_placement
openzipkin/zipkin - 9410/tcp, 0.0.0.0:9411->9411/tcp, :::9411-
>9411/tcp - dapr_zipkin
redis - 0.0.0.0:6379->6379/tcp, :::6379->6379/tcp - dapr_redis

下面是在Linux下的驗證:

在Kubernetes上安裝Dapr

Dapr專門用於在Kubernetes上執行。在安裝了Dapr CLI的開發機器上,可以在Kubernetes叢集上設定Dapr:
dapr init -k
或者,您可以使用Helm v3 chart在Kubernetes上安裝Dapr。您可以在官網上檢視詳情。

要驗證k8s當中的安裝是否成功完成,請執行以下命令
kubectl get pods --namespace dapr-system
Linux下的效果是這樣的:

更新Dapr版本

在開發環境是Windows的機器上,Dapr的早期版本已經存在,只需使用我們在上面提到的命令重新安裝即可更新CLI。
官網文件所述,我們必須先解除安裝Dapr,如下所示:
PS C:\Repos\practical-dapr\chapter01> dapr uninstall --all
更新CLI並解除安裝Dapr後,我們可以按如下方式重新安裝Dapr:
PS C:\Repos\practical-dapr\chapter01> dapr init

切記在早上網路好一點的時候進行初始化,具體原因您懂的。

在執行dapr-init之後,檢查dapr版本,我們可以看到CLI和執行時的版本都從1.0向前移動到1.9.5,如以下程式碼片段所示:

PS C:\Repos\practical-dapr\chapter01> dapr --version
CLI version:  1.9.1 
Runtime version: 1.9.5

我們的Dapr測試環境已啟動並正在執行。我們現在準備用我們的第一個示例進行試驗。

4.構建Dapr示例

我們將構建一個返回hello world訊息的web API。我們選擇將所有樣本都放在C:\Repos\pactual dapr\資料夾中,併為第一個樣本建立了C:\Repos\Pactual dapr_chapter01資料夾。我們的步驟如下:
(1)建立Web API ASP.NET專案

PS C:\Repos\practical-dapr\chapter01> dotnet new webapi -o dapr.microservice.webapi

(2)新增Dapr SDK引用

PS C:\Repos\practical-dapr\chapter01> dotnet add package Dapr.AspNetCore --version 1.9.5

(3)我們用Vs Code開啟專案,並對生成的模板做些更改
(4)為了在ASP.NET 6中支援Dapr,我們對Program.cs中的程式碼進行了一些更改。我們將builder.Services.AddControllers方法更改為builder.Services.addController().AddDapr()。
最後,為了簡化程式碼,我們註釋掉app.UseHttpsRedirection()中介軟體。
最後看下最終的程式碼:


var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddControllers().AddDapr();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
var app = builder.Build();
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
}
//app.UseHttpsRedirection();
app.UseAuthorization();
app.MapControllers();
app.MapSubscribeHandler();
app.Run();

(5)最後,我們新增了一個名為HelloWorldController的控制器,如以下程式碼片段所示:

[ApiController]
[Route("[controller]")]
public class HelloController : ControllerBase
{
    private readonly ILogger<HelloController> _logger;

    public HelloController(ILogger<HelloController> logger)
    {
        _logger = logger;
    }

    [HttpGet()]
    public ActionResult<string> Get()
    {
        Console.WriteLine("Hello, World.");
        return "Hello, World";
    }
}

以上我們設定了路由和一個Get方法。
(6)為了執行Dapr應用程式,可以使用以下命令:
dapr run --app-id <my app id> --app-port <port of the app> --dapr-http-port <port in Dapr> dotnet run
我們將ASP.NET預設埠設為5000,將Dapr HTTP埠設為5010。以下命令列啟動Dapr應用程式:

PS C:\Repos\dapr.microservice.webapi> dapr run --app-id hello-world --app-port 5000 --dapr-http-port 5010 dotnet run

我們在對應的專案目錄下執行以上程式碼,啟動Dapr。Dapr將為HTTP使用埠5010,而對於gRPC,它將自動選擇一個可用埠。
啟動後會在控制檯列印日誌資訊,要確認應用程式在Dapr執行時上下文中正確執行:

Updating metadata for app command: dotnet run
You're up and running! Both Dapr and your app logs will
appear here.

在此階段,ASP.NET在埠5000上進行監聽,Dapr在埠5010上進行監聽。為了測試Dapr,我們按如下方式呼叫curl命令,使用瀏覽器也可以:

PS C:\Repos\practical-dapr> curl http://localhost:5010/v1.0/invoke/hello-world/method/hello
Hello, World

Dapr返回了這個響應,同時Dapr視窗也會列印結果,如下所示

== APP == Hello, World.

(7)從另一個視窗,讓我們驗證Dapr服務的詳細資訊。我們按如下方式開啟dapr儀表板,而不是使用dapr list命令
PS C:\Windows\System32> dapr dashboard Dapr Dashboard running on http://localhost:8080
我們可以透過導航到http://localhost:8080顯示了hell-world的詳細資訊:

在本例中,Dapr儀表板僅顯示我們在開發機器上執行的示例應用程式。在Kubernetes環境中,它將顯示所有正在執行的微服務以及其他元件:

Dapr儀表板顯示,部署了Zipkin,Redis,Redis除了做狀態儲存,還支援訊息的釋出訂閱。
以上就是我們構建的第一個Dapr示例。

5.總結

在本章,您瞭解了Dapr專案及其元件、構建塊和sidecar方法。所有這些概念將在後面的章節中單獨深入探討。同時,我們還演示了在本地開發機器上設定Dapr,準備必要的工具。我們還學習瞭如何建立一個簡單的ASP.NET專案,以及如何配置和檢查Dapr,我們還了解了Dapr儀表板,我們可以從中獲得Dapr環境的完整和即時檢視。
在下一章中,我們將使用環境來學習如何除錯Dapr。

6.問題

  1. Dapr提供哪些構建塊?
  2. Dapr CLI和Dapr執行時之間的關係是什麼?
  3. 如何在本地開發環境中安裝Dapr?
  4. 在Kubernetes中,可以採用哪些方法安裝Dapr?

7.擴充套件閱讀

如果您想提前閱讀Dapr系列文章,請移步,這裡會優先發布我的最新成果,歡迎您不吝賜教。