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

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

生活随笔

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

编程问答

Dapr微服务应用开发系列4:状态管理构件块

發(fā)布時(shí)間:2023/12/4 编程问答 68 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Dapr微服务应用开发系列4:状态管理构件块 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
  • Dapr微服務(wù)應(yīng)用開(kāi)發(fā)系列0:概述

  • Dapr微服務(wù)應(yīng)用開(kāi)發(fā)系列1:環(huán)境配置

  • Dapr微服務(wù)應(yīng)用開(kāi)發(fā)系列2:Hello World與SDK初接觸

  • Dapr微服務(wù)應(yīng)用開(kāi)發(fā)系列3:服務(wù)調(diào)用構(gòu)件塊

題記:這篇介紹狀態(tài)管理構(gòu)件塊,這個(gè)概念相對(duì)于微服務(wù)框架而言是比較特殊的。

注:本文僅針對(duì)非Actor狀態(tài)存儲(chǔ)的情況進(jìn)行說(shuō)明,對(duì)于Actor狀態(tài)存儲(chǔ)會(huì)在講述Actor的時(shí)候一并說(shuō)明。

原理

要用好這個(gè)構(gòu)件塊,首先需要正確理解狀態(tài)管理的概念。

大部分微服務(wù)開(kāi)發(fā)框架或者說(shuō)指導(dǎo),都提倡微服務(wù)以無(wú)狀態(tài)類型的方式來(lái)運(yùn)行,這種無(wú)狀態(tài)微服務(wù)當(dāng)然更容易進(jìn)行伸縮,但是在遇到需要處理一些類似Session這樣的數(shù)據(jù)的時(shí)候,為了應(yīng)對(duì)分布式的環(huán)境往往要借助于外部存儲(chǔ)(一般是數(shù)據(jù)庫(kù)或者緩存中間件)。但是這樣做不可避免引入了對(duì)外部服務(wù)以及特定協(xié)議的依賴。

如果對(duì)Service Fabric熟悉的同學(xué),可能對(duì)有狀態(tài)服務(wù)這個(gè)概念有所了解,這種SF中特有的微服務(wù)類型,直接通過(guò)運(yùn)行時(shí)和SDK給微服務(wù)提供了一種開(kāi)箱即用的狀態(tài)管理機(jī)制——即可靠集合(Reliable Collections)。這種機(jī)制讓你可以通過(guò)Key/Value的方式來(lái)存取相關(guān)狀態(tài)值(業(yè)務(wù)數(shù)據(jù)),在某些情況下甚至可以當(dāng)作一個(gè)NoSQL來(lái)使用。有狀態(tài)服務(wù)的優(yōu)勢(shì)是把數(shù)據(jù)和業(yè)務(wù)邏輯作為一個(gè)整體來(lái)處理,特別適合領(lǐng)域驅(qū)動(dòng)設(shè)計(jì)為指導(dǎo)的每個(gè)微服務(wù)對(duì)應(yīng)獨(dú)立的數(shù)據(jù)源的原則。

由于Dapr和Service Fabric有一些淵源,所以“有狀態(tài)”的這個(gè)概念也被引入到了Dapr當(dāng)中,但是這個(gè)時(shí)候的微服務(wù)類型其實(shí)還是依舊保持著無(wú)狀態(tài)。因此狀態(tài)管理構(gòu)件塊本質(zhì)上是給開(kāi)發(fā)人員提供了一種狀態(tài)值存取的機(jī)制和API,并把狀態(tài)存儲(chǔ)的存儲(chǔ)源(也即狀態(tài)存儲(chǔ)組件)和訪問(wèn)協(xié)議進(jìn)行了抽象和屏蔽。原理圖如下(其中使用了Redis作為狀態(tài)存儲(chǔ)組件,這也是開(kāi)發(fā)環(huán)境默認(rèn)的組件):

從上圖所知,微服務(wù)只需要對(duì)自己的Dapr邊車進(jìn)行訪問(wèn),即可完成狀態(tài)的保存和獲取(可批量)。而存取的方式遵循了標(biāo)準(zhǔn)了HTTP規(guī)范的謂詞。

因而,有了狀態(tài)管理構(gòu)件塊,微服務(wù)輕可以利用其完成臨時(shí)狀態(tài)的持久化和微服務(wù)間共享,重可以利用其實(shí)現(xiàn)有狀態(tài)服務(wù)來(lái)保存業(yè)務(wù)模型。

能力

Dapr的狀態(tài)管理構(gòu)件塊并非是簡(jiǎn)簡(jiǎn)單單為大家提供了一種狀態(tài)存取的機(jī)制(可以從原理圖直觀的看出),更為重要的是提供了如下額外能力:

  • 隱藏在運(yùn)行微服務(wù)的時(shí)候配置存儲(chǔ)組件:開(kāi)發(fā)的時(shí)候只需要關(guān)心Dapr的規(guī)范接口,并使用某些簡(jiǎn)單易得的存儲(chǔ)組件來(lái)進(jìn)行調(diào)試,比如默認(rèn)的Redis存儲(chǔ)組件;運(yùn)行的時(shí)候可以引入(替換)為其他存儲(chǔ)組件,比如Azure CosmosDB,而無(wú)需改變業(yè)務(wù)代碼。

  • 內(nèi)置重試機(jī)制:和服務(wù)調(diào)用構(gòu)件塊一樣,狀態(tài)管理的API提供了內(nèi)置的重試能力,并可以用同樣的語(yǔ)義配置重試策略。這樣的重試能力也為并發(fā)和一致性等能力提供了基礎(chǔ)。

  • 內(nèi)置并發(fā)控制機(jī)制:Dapr依賴ETag這一特殊狀態(tài)屬性來(lái)保證樂(lè)觀并發(fā)控制的處理。也即在更新或者刪除狀態(tài)的時(shí)候,會(huì)檢查ETag是否匹配,從而決定是否完成數(shù)據(jù)操作。眾所周知,樂(lè)觀并發(fā)這種模式是比較適合數(shù)據(jù)沖突很少的情況,也即數(shù)據(jù)的更新主要由不同的業(yè)務(wù)數(shù)據(jù)操作而導(dǎo)致。注意:某些狀態(tài)存儲(chǔ)中間件是不支持ETag的,所以Dapr進(jìn)行了額外的處理模擬了這一機(jī)制。

  • 內(nèi)置一致性處理機(jī)制:Dapr支持兩種一致性處理——強(qiáng)一致性和最終一致性。對(duì)于強(qiáng)一致性,Dapr會(huì)等待所有底層請(qǐng)求返回確認(rèn)信息才最終完成操作;最終一致性不會(huì)等待底層請(qǐng)求確認(rèn)。

  • 批量處理:Dapr的狀態(tài)管理提供了兩種模式的批量處理。Bulk模式用于把一種同類型的請(qǐng)求合并,這種時(shí)候不會(huì)保證事務(wù)性;Multi模式可以把不同類型的請(qǐng)求一起發(fā)送,可以保證事務(wù)性。

需要注意的是由于Dapr需要支持盡量多的狀態(tài)存儲(chǔ)源,所以必然有一些存儲(chǔ)源是無(wú)法支持以上所有的能力的(主要是事務(wù)能力),可以通過(guò)瀏覽這個(gè)列表[1]來(lái)確認(rèn)存儲(chǔ)源的支持情況,還算我們常用的Redis、SQL Server、MySQL、PostgreSQL和CosmosDB是可以完整支持。

規(guī)范

Dapr狀態(tài)管理構(gòu)件塊由于提供了這種特定的能力給你的微服務(wù)使用,所以給使用的方式制訂了如下規(guī)范:

  • 由于狀態(tài)管理依賴于狀態(tài)組件,所以首先規(guī)定了應(yīng)用狀態(tài)組件的聲明格式

  • 從概念所知,狀態(tài)的存儲(chǔ)需要依賴狀態(tài)鍵,所以接著規(guī)定了鍵的構(gòu)成方式

  • 最為重要的規(guī)范是規(guī)定了狀態(tài)存取的HTTP/gRPC的地址格式

狀態(tài)組件聲明

通過(guò)如下yaml文件來(lái)聲明對(duì)狀態(tài)組件的引用(在本地開(kāi)發(fā)環(huán)境可以不聲明,使用默認(rèn)的狀態(tài)存儲(chǔ)源):

apiVersion: dapr.io/v1alpha1 kind: Component metadata:name: <NAME>namespace: <NAMESPACE> spec:type: state.<TYPE>metadata:- name:<KEY>value:<VALUE>- name: <KEY>value: <VALUE>

由于整個(gè)聲明的解釋,會(huì)在后續(xù)單獨(dú)的組件文章中詳細(xì)展開(kāi)。我們只要記住其中的 metadata.name 代表了存儲(chǔ)源的名稱,對(duì)于應(yīng)用程序而言需要匹配的就是這個(gè)名稱。另外 spec.type 代表了存儲(chǔ)源所使用的存儲(chǔ)類型,這個(gè)對(duì)于應(yīng)用開(kāi)發(fā)者而言可以了解到存儲(chǔ)源是否具備完整的狀態(tài)存儲(chǔ)能力。

鍵的組成模式

從上所知,狀態(tài)管理構(gòu)件塊是以鍵值的方式保存數(shù)據(jù)的,為了保證和存儲(chǔ)源的兼容,那么就需要按照一定的模式來(lái)定義鍵的組成。

普通的(非Actor)狀態(tài)的鍵為:<App ID>||<state key>

對(duì)于應(yīng)用開(kāi)發(fā)者而言,其實(shí)只需要關(guān)心 <state key> 即可

請(qǐng)求地址

要對(duì)狀態(tài)進(jìn)行操作,需要對(duì)如下地址進(jìn)行HTTP/gRPC請(qǐng)求:http://localhost:<daprPort>/v1.0/state/<storename>

其中daprPort代表了Dapr邊車的特定協(xié)議端口,HTTP默認(rèn)50001或者gRPC默認(rèn)3500;storename即是在組件聲明中的 metadata.name。

保存狀態(tài)

對(duì)上述地址進(jìn)行POST請(qǐng)求,并傳遞一個(gè)鍵值對(duì)(外加可選的etag)的數(shù)組作為請(qǐng)求體,比如:

[{"key": "weapon","value": "DeathStar","etag": "1234"},{"key": "planet","value": {"name": "Tatooine"}} ]

獲取狀態(tài)

對(duì)上述地址進(jìn)行GET請(qǐng)求,并傳遞狀態(tài)鍵作為路由參數(shù):

GET http://localhost:<daprPort>/v1.0/state/<storename>/<key>

返回結(jié)果是一個(gè)json的對(duì)象,具體格式是由你確定(即你保存狀態(tài)的時(shí)候傳入什么格式);另外etag會(huì)附加在響應(yīng)頭 ETag 當(dāng)中。

以bulk的方式獲取狀態(tài)

對(duì)上述地址進(jìn)行POST/PUT請(qǐng)求,并傳遞 bulk 作為路由參數(shù):

POST/PUT http://localhost:<daprPort>/v1.0/state/<storename>/bulk

同時(shí)再構(gòu)建一個(gè)如下格式的請(qǐng)求體,把需要獲取的狀態(tài)鍵放到 keys 數(shù)組當(dāng)中,同時(shí)設(shè)定 parallelism 的值來(lái)確定在存儲(chǔ)源中執(zhí)行查找操作的并行度(如果狀態(tài)是以分區(qū)的方式保存在存儲(chǔ)源中的話):

{"keys": [ "key1", "key2" ],"parallelism": 10 }

請(qǐng)求后,響應(yīng)體是一個(gè)包含了鍵值對(duì)數(shù)組的json對(duì)象:

[{"key": "key1","data": "value1","etag": "1"},{"key": "key2","data": "value2","etag": "1"} ]

刪除狀態(tài)

對(duì)上述地址進(jìn)行GET請(qǐng)求,并傳遞狀態(tài)鍵作為路由參數(shù):

DELETE http://localhost:<daprPort>/v1.0/state/<storename>/<key>

刪除狀態(tài)請(qǐng)求沒(méi)有響應(yīng)體,通過(guò)響應(yīng)狀態(tài)碼204來(lái)確認(rèn)刪除成功。

事務(wù)操作

如果你希望一次請(qǐng)求執(zhí)行多步操作的話,可以使用這種請(qǐng)求方式。這種請(qǐng)求由于是支持事務(wù)的,所以并非所有存儲(chǔ)源都支持。

對(duì)上述地址進(jìn)行POST/PUT請(qǐng)求,并傳遞 transaction 作為路由參數(shù):

POST/PUT http://localhost:<daprPort>/v1.0/state/<storename>/transaction

請(qǐng)求體是一個(gè)操作的數(shù)組,標(biāo)明了各個(gè)操作要完成的操作類型和狀態(tài)內(nèi)容,如:

{"operations": [{"operation": "upsert","request": {"key": "key1","value": "myData"}},{"operation": "delete","request": {"key": "key2"}}],"metadata": {"partitionKey": "planet"} }

其中 operation 有兩種類型:upsert (更新或插入)和 delete(刪除)。

目前支持事務(wù)操作的存儲(chǔ)源有:

  • Redis

  • MongoDB

  • MySQL

  • RethinkDB

  • PostgreSQL

  • SQL Server

  • Azure CosmosDB

DOTNET SDK

由于狀態(tài)管理構(gòu)件塊為你的應(yīng)用程序提供了一些和狀態(tài)相關(guān)的操作接口,SDK除了提供 DaprClient 這個(gè)客戶端封裝類方便你使用.NET函數(shù)庫(kù)來(lái)操作狀態(tài)以外,也為ASP.NET Core提供了更加便捷的模型綁定屬性標(biāo)記類 FromStateAttribute 方便你在Controller中通過(guò)屬性綁定的方式來(lái)獲取狀態(tài)。

DaprClient中和狀態(tài)相關(guān)的方法有:

  • GetStateAsync:基于storeName和key獲取狀態(tài)值

  • GetBulkStateAsync:基于storeName和keys列表獲取多個(gè)狀態(tài)值

  • GetStateAndETagAsync:基于storeName和key獲取狀態(tài)值和etag

  • GetStateEntryAsync:基于storeName和key獲取StateEntry封裝類,此類包含了狀態(tài)的更詳細(xì)信息

  • SaveStateAsync:基于storeName和key保存狀態(tài)值

  • ExecuteStateTransactionAsync:執(zhí)行狀態(tài)事務(wù)操作

  • DeleteStateAsync:基于storeName和key刪除狀態(tài)值

FromStateAttribute可以在Controller的Action中直接獲取StateEntry,如:

[HttpGet("{account}")] public ActionResult<Account> Get([FromState(StoreName)] StateEntry<Account> account) {if (account.Value is null){return this.NotFound();}return account.Value; }

用法與例子

其實(shí)通過(guò)上面對(duì)規(guī)范的講解,對(duì)狀態(tài)管理的基本用法應(yīng)該有一定的理解了。官方文檔給出了如下文章來(lái)分別講述了狀態(tài)管理構(gòu)件塊的3種使用場(chǎng)景:

  • 如何保存和獲取狀態(tài)[2]:基本的HTTP使用方式,如果希望看到DOTNET SDK的使用方式,需要參考(https://github.com/dapr/dotnet-sdk)中的例子,其中包含了Client的使用和ASP.NET Core中的使用

  • 如何構(gòu)建有狀態(tài)服務(wù)[3],其依賴了狀態(tài)管理構(gòu)件塊提供的并發(fā)和一致性特性

  • 如何在服務(wù)之間共享狀態(tài)[4],通過(guò)給狀態(tài)存儲(chǔ)源設(shè)置不同的keyPrefix策略讓不同的服務(wù)之間可以以特定的鍵組成格式來(lái)讀取同一個(gè)存儲(chǔ)源

  • 另外,我的dapr-dotnet-quickstarts開(kāi)源項(xiàng)目(https://github.com/heavenwing/dapr-dotnet-quickstarts)也包含了狀態(tài)管理構(gòu)件塊的基本用法的例子:

    • StateManagement:使用原生的HTTP請(qǐng)求來(lái)保存、獲取和刪除狀態(tài)

    • StateManagementWithSdk:使用SDK的DaprClient來(lái)保存、獲取和刪除狀態(tài)

    參考資料

    [1]

    列表: https://docs.dapr.io/operations/components/setup-state-store/supported-state-stores/

    [2]

    如何保存和獲取狀態(tài): https://docs.dapr.io/developing-applications/building-blocks/state-management/howto-get-save-state/

    [3]

    如何構(gòu)建有狀態(tài)服務(wù): https://docs.dapr.io/developing-applications/building-blocks/state-management/howto-stateful-service/

    [4]

    如何在服務(wù)之間共享狀態(tài): https://docs.dapr.io/developing-applications/building-blocks/state-management/howto-share-state/

    總結(jié)

    以上是生活随笔為你收集整理的Dapr微服务应用开发系列4:状态管理构件块的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

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