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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Orleans解决并发之痛(二):Grain状态

發布時間:2023/12/4 编程问答 62 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Orleans解决并发之痛(二):Grain状态 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Grains是Orleans應用程序的構建塊,它們是彼此孤立的原子單位,分布的,持久的, 一個典型的Grain是有狀態和行為的一個單實例,每個Grain實例的在單線程內執行,Grain之間共享數據通過消息傳遞,Grains是由Silo自動化管理。

Grain之間傳遞消息過程中也可能出現死鎖的情況,如:Grain A發送消息給Grain B,并等待它的完成,此時Grain B發送一個消息給Grain A,也等待其完成,這時候出現相互等待而造成死鎖。Orleans對Grain之間產生的死鎖問題解決也是非常簡單的,只需要在Grain上加[Reentrant]屬性,具體可查看官方Concurrency。

Grain狀態有好幾種存儲方式,比如:AzureTableStorage、AzureBlobStorage、SQLStorage、MemoryStorage ?等,我們還可以自定義存儲。MemoryStorage在測試項目使用沒問題,但實際生產環境要使用其他持久存儲的方式,因為一旦一個Silo被關閉,內存存儲的狀態將會消失。

在分布式下,State的使用可以減少很多對數據庫層面的壓力。當然也不是所有的Grain都推薦使用State,還是看實際業務需求。我們可以想象一個場景,一個商品的庫存如果保存在State中,所有請求都共享這個State,在判斷是否有剩余商品的時候是不是就不需要每次都去查詢數據庫了?

定義接口

public interface IPersonGrain : IGrainWithStringKey {Task SayHelloAsync(); }

實現接口

public class PersonGrain : Grain, IPersonGrain {public Task SayHelloAsync(){string primaryKey = this.GetPrimaryKeyString();Console.WriteLine($"{primaryKey} said hello!");return Task.CompletedTask;} }

為了實現狀態存儲,我們需要創建一個class:

public class PersonGrainState {public bool SaidHello { get; set; } }

修改代碼,實現的PersonGrain不應該再繼承Grain,而是Grain<T>

[StorageProvider(ProviderName = "OrleansStorage")] public class PersonGrain : Grain<PersonGrainState>, IPersonGrain {public async Task SayHelloAsync(){string primaryKey = this.GetPrimaryKeyString();bool saidHelloBefore = this.State.SaidHello;string saidHelloBeforeStr = saidHelloBefore ? " already" : null;Console.WriteLine($"{primaryKey}{saidHelloBeforeStr} said hello!");this.State.SaidHello = true;await this.WriteStateAsync();} }

第一次調用這個方法的時候this.State.SaidHello為false,輸出'xxx said hello!'。然后我們通過WriteStateAsync修改SaidHello為true,當第二次被調用的時候,從State里取出的SaidHello已經變成了true,則輸出'xxx already said hello!'

Orleans 提供了非常簡單的API來處理持久化裝狀態,看方法名就知道什么啥意思了,WriteStateAsync()、ReadStateAsync() 、 ClearStateAsync()。

同時在PersonGrain加了一個StorageProvider屬性,參數ProviderName賦值為OrleansStorage,這里需要對Silo的配置文件(OrleansConfiguration.xml)做調整,添加StorageProviders配置,Type表示存儲方式,Name表示名稱,程序內指定的ProviderName需要和配置中這個名稱保持一致。

注意:
當Name為Default時,如果某個Grain使用Default來存儲,可以不需要加StorageProvider屬性。StorageProviders下可以有多個Provider,每個Provider的Type可以不一樣,每個Grain指定的存儲方式也可以不一樣,ProviderName指定是誰就用誰存儲。

<?xml version="1.0" encoding="utf-8" ?> <OrleansConfiguration xmlns="urn:orleans"><Globals><SeedNode Address="localhost" Port="11111" /><StorageProviders><Provider Type="Orleans.Storage.MemoryStorage"Name="OrleansStorage" /></StorageProviders></Globals><Defaults><Networking Address="localhost" Port="11111" /><ProxyingGateway Address="localhost" Port="30000" /></Defaults> </OrleansConfiguration>

為了驗證Grain之間是獨立的,在Client加入以下代碼:

var joe = GrainClient.GrainFactory.GetGrain<IPersonGrain>("Joe"); joe.SayHelloAsync(); joe.SayHelloAsync();var sam = GrainClient.GrainFactory.GetGrain<IPersonGrain>("Sam"); sam.SayHelloAsync(); sam.SayHelloAsync();

測試結果:


Test Result

SQL Server 持久存儲State

上面提到State以內存存儲的方式并不適合生產環境,那下面我們使用SQL Server來實現。

在Silo程序集中安裝依賴包:
Install-Package Microsoft.Orleans.OrleansSqlUtils Install-Package System.Data.SqlClient
創建數據庫和表:
  • 在SQL Server中創建一個數據庫,命名如:OrleansStorage(隨意);

  • 在解決方案下找到目錄:packages\Microsoft.Orleans.OrleansSqlUtils.1.5.0\lib\net461\SQLServer,目錄下有一個.sql文件,在OrleansStorage數據庫下執行這個sql腳本即可;

  • 修改OrleansConfiguration.xml的StorageProviders節點為:
    <StorageProviders><Provider Type="Orleans.Storage.AdoNetStorageProvider"Name="OrleansStorage"AdoInvariant="System.Data.SqlClient"DataConnectionString="Server=.;Database=OrleansStorage;
    User ID=sa;Password=123456;"/> </StorageProviders>
    重新啟動Silo和Client:

    執行完成后查看數據庫中表Storage的內容,數據的值是二進制是方式存儲。



    storage

    之后不管重啟多少次,輸出的結果都是 "xxx already saild hello!" 。

    參考鏈接:

    • Actor模型

    • Orleans

    • 案例Demo-OrleansState

    相關文章:?

    • .NET的Actor模型:Orleans

    • 微軟分布式云計算框架Orleans(1):Hello World

    • 微軟分布式云計算框架Orleans(2):容災與集群(1)

    • Aaron Stannard談Akka.NET 1.1

    • 使用Akka.net開發第一個分布式應用

    • Orleans入門例子

    • Orleans例子再進一步

    • Orleans稍微復雜的例子—互動

    • Orleans簡單配置

    • Orleans配置---持久化

    • Orleans—一些概念

    • Orleans的集群構建

    • Oleans集群之Consul再解釋

    • Orleans解決并發之痛(一):單線程

    原文地址:http://www.jianshu.com/p/ccd9cffa77bf


    .NET社區新聞,深度好文,微信中搜索dotNET跨平臺或掃描二維碼關注

    總結

    以上是生活随笔為你收集整理的Orleans解决并发之痛(二):Grain状态的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。