為什麼我們需要狀態管理?

在建構複雜架構或容易有問題的功能時,你可以透過狀態管理達到目的,如:

  1. 分散式併發
  2. 資料一致性
  3. 批次 新增、讀取、更新、刪除 (CRUD) 操作行為

你可以透過 State Management API 存取狀態 (Key-Value),如下圖所示:使用 HTTP POST 保存狀態;使用 HTTP GET 取得狀態。你可以增加額外 metadata,要求以 Concurrency requirements 或 Consistency requirements 方式進行處理。預設情況下,會使用 eventually consistent 與 last-write-wins 併發模式。




Dapr 可以透過不同服務進行狀態儲存,你可以隨意更換不同的儲存服務 (如 Cosmos、Redis)。簡單來說,Dapr 提供可插拔 (Pluggable) 狀態儲存功能。您可以 C:\Users\<您的使用者帳戶>\.dapr\components 找到 statestore.yaml,檢視相關設定。





併發 (Concurrency)

Dapr 支援使用 ETag 的 Optimistic Concurrency Control (OCC)。當要求取得狀態時,Dapr 會回傳一個 ETag 屬性,後續要求嘗試變更/刪除狀態時,會透過 Body 內附加 ETag 進行更新 或 Header 內附加 If-Match 進行刪除。只有 ETag 相同時,操作才會成功。

依據官方網站說明,採用這種機制是因為多數應用程式中,很少發生資料更新衝突,主要原因在於客戶端是依據業務流程對於不同資料進行操作。若您 ETags 不符合而造成操作失敗,建議需要使用 Retry 機制來解決 ETag 衝突



一致性 (Consistency)

Dapr 同時支援 strong consistencyeventual consistency,eventual consistency 為預設值。使用 strong consistency 會等待所有 replicas 確定後才寫入;使用 eventual consistency 時,底層資料接受寫入請求後即會回傳 (即使是單一 replica )。更多一致性的操作可以參考 State management API - Optional behaviors





實作狀態管理

此實作延續 Dapr 服務調用 (Service invocation) 進階篇,建議您先完成


步驟 1. 右鍵點選 Controller > 點選加入 > 控制器 > 選擇空白的 API 控制器





步驟 2. 名稱輸入 StateController




步驟 3. 貼上下列程式碼




步驟 4. 以管理者身分開啟命令提示字元,輸入指令

dapr run --app-id client --app-port 5200 --dapr-http-port 3501 -- dotnet DaprClientDemo\bin\Debug\netcoreapp3.1\DaprClientDemo.dll --urls=http://localhost:5200



步驟 5. 您可以使用 postman、powershell 進行測試,我們這裡直接使用 Dapr CLI 來調用服務。開啟另一個命令提示字元,輸入下列指令記錄狀態

dapr invoke --app-id  client --verb POST --method api/state

 




步驟 6. 接下來,輸入下列指令取得紀錄狀態

dapr invoke --app-id  client --verb GET --method api/state





步驟 7. 我們可以直接查看狀態儲存內容,因為預設是使用 Redis,所以我們可以輸入下列 docker指令進入檢視資料

docker exec -it dapr_redis redis-cli





步驟 8. 輸入 keys * ,取得所有資料




步驟 9. 輸入 hgetall "client||guid",確認資料