日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

手把手教你学Dapr - 5. 状态管理

發(fā)布時(shí)間:2023/12/4 编程问答 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 手把手教你学Dapr - 5. 状态管理 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

介紹

使用狀態(tài)管理,您的應(yīng)用程序可以將數(shù)據(jù)作為鍵/值對(duì)存儲(chǔ)在支持的狀態(tài)存儲(chǔ)中。

您的應(yīng)用程序可以使用 Dapr 的狀態(tài)管理 API 使用狀態(tài)存儲(chǔ)組件來(lái)保存和讀取鍵/值對(duì),如下圖所示。例如,通過(guò)使用 HTTP POST,您可以保存鍵/值對(duì),通過(guò)使用 HTTP GET,您可以讀取鍵并返回其值。

特性

可插拔狀態(tài)存儲(chǔ)

Dapr 數(shù)據(jù)存儲(chǔ)被建模為組件,可以在不更改代碼的情況下更換它。例如:MySQL、Redis、Azure CosmosDB等。

可配置的狀態(tài)存儲(chǔ)行為

Dapr 允許開發(fā)人員將額外的元數(shù)據(jù)附加到狀態(tài)操作請(qǐng)求中,用以描述請(qǐng)求的處理方式。如:

  • 并發(fā)要求

  • 一致性要求

默認(rèn)情況下,您的應(yīng)用程序應(yīng)假定數(shù)據(jù)存儲(chǔ)最終一致并使用最后寫入獲勝的并發(fā)模式

并發(fā)

Dapr 支持使用 ETags 的樂(lè)觀并發(fā)控制 (OCC)。當(dāng)請(qǐng)求狀態(tài)時(shí),Dapr 總是將 ETag 屬性附加到返回的狀態(tài)。當(dāng)用戶代碼嘗試更新或刪除狀態(tài)時(shí),應(yīng)該通過(guò)請(qǐng)求正文附加 ETag 以進(jìn)行更新或通過(guò) If-Match 標(biāo)頭進(jìn)行刪除。只有當(dāng)提供的 ETag 與狀態(tài)存儲(chǔ)中的 ETag 匹配時(shí),寫操作才能成功。建議您在使用 ETag 時(shí)使用重試策略來(lái)補(bǔ)償此類沖突。

如果您的應(yīng)用程序在寫入請(qǐng)求時(shí)省略 ETag,則 Dapr 在處理請(qǐng)求時(shí)會(huì)跳過(guò) ETag 檢查。與使用 ETag 的先寫贏模式相比,這實(shí)質(zhì)上啟用了最后寫贏模式。

自動(dòng)加密

Dapr 支持應(yīng)用程序狀態(tài)的自動(dòng)客戶端加密,并支持密鑰輪換。這是一項(xiàng)預(yù)覽功能,所有 Dapr 狀態(tài)存儲(chǔ)都支持。

一致性

Dapr 支持強(qiáng)一致性和最終一致性,最終一致性作為默認(rèn)行為。

  • 當(dāng)使用強(qiáng)一致性時(shí),Dapr 在確認(rèn)寫入請(qǐng)求之前等待所有副本(或指定的仲裁)確認(rèn)。

  • 當(dāng)使用最終一致性時(shí),一旦底層數(shù)據(jù)存儲(chǔ)接受寫入請(qǐng)求,Dapr 就會(huì)立即返回,即使這是單個(gè)副本。

批量操作

Dapr 支持兩種類型的批量操作 - 批量(bulk)或多(multi)。

注:bulk與multi的區(qū)別在于bulk不是事務(wù)性的,multi是事務(wù)處理。

Actor狀態(tài)

事務(wù)狀態(tài)存儲(chǔ)可用于存儲(chǔ)Actor狀態(tài)。要指定用于Actor的狀態(tài)存儲(chǔ),請(qǐng)?jiān)跔顟B(tài)存儲(chǔ)組件的元數(shù)據(jù)部分中將屬性 actorStateStore的值指定為 true。

注:Actors 狀態(tài)以特定方案存儲(chǔ)在事務(wù)狀態(tài)存儲(chǔ)中允許一致的查詢。所以只能有一個(gè)狀態(tài)存儲(chǔ)組件被用于所有的Actor。

直接查詢狀態(tài)存儲(chǔ)

Dapr 無(wú)需任何轉(zhuǎn)換即可保存和檢索狀態(tài)值。您可以直接從底層狀態(tài)存儲(chǔ)查詢和聚合狀態(tài)。

例如,要在 Redis 中獲取與應(yīng)用程序 ID “myApp” 關(guān)聯(lián)的所有狀態(tài)鍵,請(qǐng)使用:

KEYS "myApp*"

查詢Actor狀態(tài)

如果數(shù)據(jù)存儲(chǔ)支持 SQL 查詢,您可以使用 SQL 查詢查詢參與者的狀態(tài)。例如使用:

SELECT * FROM StateTable WHERE Id='<app-id>||<actor-type>||<actor-id>||<key>'

您還可以跨Actor實(shí)例執(zhí)行聚合查詢,避免Actor 框架常見的基于回合的并發(fā)限制。例如,要計(jì)算所有溫度計(jì)Actor的平均溫度,請(qǐng)使用:

保存并獲取狀態(tài)

狀態(tài)管理是任何應(yīng)用程序最常見的需求之一:新的或遺留的、單體或微服務(wù)。處理不同的數(shù)據(jù)庫(kù)、測(cè)試、處理重試和故障可能既費(fèi)時(shí)又費(fèi)力。

先決條件

準(zhǔn)備好Dapr運(yùn)行環(huán)境可以看之前的文章

手把手教你學(xué)Dapr - 3. 使用Dapr運(yùn)行第一個(gè).Net程序

設(shè)置狀態(tài)存儲(chǔ)

Windows打開目錄%USERPROFILE%\.dapr\components

  • 創(chuàng)建文件statestore.yaml

  • 使用redis作為狀態(tài)存儲(chǔ)的數(shù)據(jù)庫(kù)

    apiVersion: dapr.io/v1alpha1 kind: Component metadata:name: statestore spec:type: state.redisversion: v1metadata:- name: redisHostvalue: localhost:6379- name: redisPasswordvalue: ""- name: actorStateStorevalue: "true"

    注:這個(gè)yaml已經(jīng)通過(guò)actorStateStore開啟了Actor狀態(tài)

  • 保存和檢索單個(gè)狀態(tài)

    注:設(shè)置 app-id 很重要,因?yàn)闋顟B(tài)鍵以該值作為前綴。如果您不設(shè)置它,則在運(yùn)行時(shí)為您生成一個(gè),下次運(yùn)行該命令時(shí)將生成一個(gè)新的,您將無(wú)法再訪問(wèn)以前保存的狀態(tài)。換句話說(shuō),如果你要共享狀態(tài)可以自定義一個(gè)保留app-id作為共享狀態(tài)而不是留空。

    運(yùn)行Dapr Sidecar

    運(yùn)行一個(gè)空的Sidecar,因?yàn)槲覀冎挥盟鼇?lái)幫助訪問(wèn)狀態(tài)存儲(chǔ),所以與之前不同的是,dapr run后面沒(méi)有接dotnet run去作為某一個(gè)程序的Sidecar

    dapr run --app-id myapp --dapr-http-port 3500 --dapr-grpc-port 50001

    創(chuàng)建客戶端

    創(chuàng)建控制臺(tái)程序,添加Dapr.Client NuGet包引用。

    修改Program.cs

    using Dapr.Client;var storeName = "statestore"; var key = "myFirstKey"; var value = "myFirstValue";var client = new DaprClientBuilder().Build(); await client.SaveStateAsync(storeName, key, value); Console.WriteLine("State has been stored");var data = await client.GetStateAsync<string>(storeName, key); Console.WriteLine($"Got value: {data}");Console.ReadKey();

    刪除單個(gè)狀態(tài)

    await client.DeleteStateAsync(storeName, key);

    通過(guò)事務(wù)保存和檢索多個(gè)狀態(tài)

    Dapr 還允許您在同一個(gè)調(diào)用中保存和檢索多個(gè)狀態(tài)。

    var lst = new List<StateTransactionRequest>() {new StateTransactionRequest("test1", System.Text.Encoding.UTF8.GetBytes("value1"), StateOperationType.Upsert),new StateTransactionRequest("test2", System.Text.Encoding.UTF8.GetBytes("value2"), StateOperationType.Upsert), }; await client.ExecuteStateTransactionAsync(storeName, lst);var datas = await client.GetBulkStateAsync(storeName, lst.Select(r => r.Key).ToList(), 0); Console.WriteLine($"Got items: {string.Join(",", datas.Select(d => $"{d.Key}={d.Value}"))}");

    強(qiáng)一致性

    使用強(qiáng)一致性時(shí),Dapr將確保底層狀態(tài)存儲(chǔ)在寫入或刪除狀態(tài)之前,一旦數(shù)據(jù)被寫入到所有副本或收到來(lái)自quorum的ack,就會(huì)返回響應(yīng)。

    對(duì)于GET請(qǐng)求,Dapr 將確保存儲(chǔ)在副本之間一致地返回最新數(shù)據(jù)。默認(rèn)為最終一致性,除非在對(duì)狀態(tài) API 的請(qǐng)求中另有說(shuō)明。

    await client.SaveStateAsync(storeName, key, value, new StateOptions() { Consistency = ConsistencyMode.Strong });var etagData = await client.GetStateAndETagAsync<string>(storeName, key, ConsistencyMode.Strong); Console.WriteLine($"ETag:{etagData.etag}");await client.DeleteStateAsync(storeName, key, new StateOptions() { Consistency = ConsistencyMode.Strong });

    先寫贏和最后寫贏

    Dapr 允許開發(fā)人員在使用數(shù)據(jù)存儲(chǔ)時(shí)選擇兩種常見的并發(fā)模式:首先寫入獲勝和`最后寫入獲勝。First-Write-Wins 在您有多個(gè)應(yīng)用程序?qū)嵗那闆r下很有用,所有實(shí)例都同時(shí)寫入同一個(gè)鍵。

    Dapr 的默認(rèn)模式是最后寫入獲勝。

    下面的例子展示了如何獲取一個(gè) ETag,然后使用它來(lái)保存狀態(tài),然后刪除狀態(tài):

    await client.SaveStateAsync(storeName, key, value, new StateOptions() { Concurrency = ConcurrencyMode.FirstWrite }); var firstWriteWinData = await client.GetStateAndETagAsync<string>(storeName, key); var etag = firstWriteWinData.etag;await client.TrySaveStateAsync(storeName, key, DateTime.Now.Ticks.ToString(), etag, new StateOptions() { Concurrency = ConcurrencyMode.FirstWrite }); var firstWriteWinDeleteSucceeded = await client.TryDeleteStateAsync(storeName, key, etag); Console.WriteLine($"First write wins delete:{firstWriteWinDeleteSucceeded}");firstWriteWinData = await client.GetStateAndETagAsync<string>(storeName, key); firstWriteWinDeleteSucceeded = await client.TryDeleteStateAsync(storeName, key, firstWriteWinData.etag); Console.WriteLine($"First write wins delete:{firstWriteWinDeleteSucceeded}");

    注:這里演示了ETag在更新后嘗試刪除失敗的例子,最后再重新獲取新的狀態(tài)以修正ETag再刪除

    在不同的應(yīng)用程序之間共享狀態(tài)

    為了實(shí)現(xiàn)狀態(tài)共享,Dapr 支持以下鍵前綴策略

    • appid - 這是默認(rèn)策略。appid 前綴允許狀態(tài)只能由具有指定 appid 的應(yīng)用程序管理。所有狀態(tài)鍵都將以 appid 為前綴,并以應(yīng)用程序?yàn)榉秶?/p>

    • name - 此設(shè)置使用狀態(tài)存儲(chǔ)組件的名稱作為前綴。對(duì)于給定的狀態(tài)存儲(chǔ),多個(gè)應(yīng)用程序可以共享相同的狀態(tài)。

    • none - 此設(shè)置不使用前綴。多個(gè)應(yīng)用程序在不同的狀態(tài)存儲(chǔ)之間共享狀態(tài)

    舉個(gè)例子:要指定前綴策略,請(qǐng)?jiān)跔顟B(tài)組件上添加名為 keyPrefix 的元數(shù)據(jù)鍵

    apiVersion: dapr.io/v1alpha1 kind: Component metadata:name: statestorenamespace: production spec:type: state.redisversion: v1metadata:- name: keyPrefixvalue: <key-prefix-strategy>

    注:此示例演示相對(duì)較復(fù)雜,思路大概是使用多個(gè)statestore.yaml,然后根據(jù)不同的storename切換不同策略即可。感興趣的小伙伴可以自行嘗試。

    自動(dòng)加密狀態(tài)并管理密鑰輪換

    注:截止目前,這個(gè)功能是個(gè)預(yù)覽版,感興趣的小伙伴可以自行嘗試

    應(yīng)用程序狀態(tài)通常需要靜態(tài)加密,以在企業(yè)工作負(fù)載或受監(jiān)管環(huán)境中提供更強(qiáng)的安全性。Dapr 提供基于 AES256 的自動(dòng)客戶端加密。

    狀態(tài)的生存時(shí)間(TTL)

    Dapr 為每個(gè)狀態(tài)在請(qǐng)求時(shí)設(shè)置生存時(shí)間 (TTL)。這意味著應(yīng)用程序可以為每個(gè)存儲(chǔ)的狀態(tài)設(shè)置生存時(shí)間,并且這些狀態(tài)在到期后無(wú)法檢索。

    注:只有一部分 Dapr 狀態(tài)存儲(chǔ)組件與狀態(tài) TTL 兼容。對(duì)于支持的狀態(tài)存儲(chǔ),只需在發(fā)布消息時(shí)設(shè)置 ttlInSeconds 元數(shù)據(jù)。其他狀態(tài)存儲(chǔ)將忽略此值。

    await client.SaveStateAsync(storeName, key, value, metadata: new Dictionary<string, string>() { { "ttlInSeconds", "3" } }); var ttlData = await client.GetStateAsync<string>(storeName, key); Console.WriteLine($"TTL Data:{ttlData}");Thread.Sleep(5000); ttlData = await client.GetStateAsync<string>(storeName, key); Console.WriteLine($"TTL Data:{ttlData}");

    持久化狀態(tài)

    要顯式設(shè)置持久化狀態(tài)(忽略為鍵設(shè)置的任何 TTL),請(qǐng)將 ttlInSeconds 值指定為 -1。

    本章源碼

    Assignment05

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

    我們正在行動(dòng),新的框架、新的生態(tài)

    我們的目標(biāo)是自由的、易用的、可塑性強(qiáng)的、功能豐富的、健壯的。

    所以我們借鑒Building blocks的設(shè)計(jì)理念,正在做一個(gè)新的框架MASA Framework,它有哪些特點(diǎn)呢?

    • 原生支持Dapr,且允許將Dapr替換成傳統(tǒng)通信方式

    • 架構(gòu)不限,單體應(yīng)用、SOA、微服務(wù)都支持

    • 支持.Net原生框架,降低學(xué)習(xí)負(fù)擔(dān),除特定領(lǐng)域必須引入的概念,堅(jiān)持不造新輪子

    • 豐富的生態(tài)支持,除了框架以外還有組件庫(kù)、權(quán)限中心、配置中心、故障排查中心、報(bào)警中心等一系列產(chǎn)品

    • 核心代碼庫(kù)的單元測(cè)試覆蓋率90%+

    • 開源、免費(fèi)、社區(qū)驅(qū)動(dòng)

    • 還有什么?我們?cè)诘饶?#xff0c;一起來(lái)討論

    經(jīng)過(guò)幾個(gè)月的生產(chǎn)項(xiàng)目實(shí)踐,已完成POC,目前正在把之前的積累重構(gòu)到新的開源項(xiàng)目中

    目前源碼已開始同步到Github(文檔站點(diǎn)在規(guī)劃中,會(huì)慢慢完善起來(lái)):

    MASA.BuildingBlocks

    MASA.Contrib

    MASA.Utils

    MASA.EShop

    BlazorComponent

    MASA.Blazor

    QQ群:7424099

    微信群:加技術(shù)運(yùn)營(yíng)微信(MasaStackTechOps),備注來(lái)意,邀請(qǐng)進(jìn)群

    總結(jié)

    以上是生活随笔為你收集整理的手把手教你学Dapr - 5. 状态管理的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

    如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。