.NET 雲原生架構師訓練營(基於 OP Storming 和 Actor 的大型分散式架構三)--學習筆記

鄭子銘發表於2023-01-16

目錄

  • 為什麼我們用 Orleans
  • Dapr VS Orleans
  • Actor 模型
  • Orleans 的核心概念
  • 結合 OP Storming 的實踐

結合 OP Storming 的實踐

  • 業務模型
  • 設計模型
  • 程式碼實現

程式碼實現

  • HelloOrleans.Host
  • Orleans.Providers.MongoDB
  • HelloOrleans.Contract
  • HelloOrleans.BlazorWeb

Orleans.Providers.MongoDB

接下來我們把它改為 MongoDB:Orleans.Providers.MongoDB: https://github.com/OrleansContrib/Orleans.Providers.MongoDB

引入 negut 包

<PackageReference Include="Orleans.Providers.MongoDB" Version="3.4.1" />

配置 MongoDB

builder.Host.UseOrleans(silo =>
{
    silo.UseLocalhostClustering();
    // silo.AddMemoryGrainStorage("hello-orleans");
    silo.UseMongoDBClient("mongodb://localhost")
        .AddMongoDBGrainStorage("hello-orleans", options =>
        {
            options.DatabaseName = "hello-orleans";
            options.CollectionPrefix = "";
        });
});

我們啟動專案測試一下

Create 方法入參

{
	"title": "第一個職位",
	"description": "第一個職位"
}

可以看到方法呼叫成功,返回的 job 裡面包含了 identity

{
    "title": "第一個職位",
    "description": "第一個職位",
    "location": null,
    "identity": "c83725f2-44da-45e0-bc2d-d849563cf924"
}

接著我們開啟 MongoDB

可以看到 JobGrain 中有對應的 identity 的記錄

因此我們可以看到 Storage 的切換是不會影響程式碼的

HelloOrleans.Contract

持久化之後我們再給它改變一下模式,現在我們是 silo 內模式,客戶端和服務端是放到一起的

我們可以把它改變成 silo 外模式,客戶端和服務端分開

建立一個類庫專案 HelloOrleans.Contract

接著把 Contract 目錄下的檔案都搬到 HelloOrleans.Contract 專案中

新增 Orleans 的 nuget 包,它不需要新增 Server 的包

<ItemGroup>
    <PackageReference Include="Microsoft.Orleans.Core" Version="3.6.5" />
    <PackageReference Include="Microsoft.Orleans.CodeGenerator.MSBuild" Version="3.6.5" />
</ItemGroup>

接著在 Host 專案中新增 Contract 的專案引用,即可生成成功

HelloOrleans.BlazorWeb

建立一個 Blazor Server 專案 HelloOrleans.BlazorWeb

新增 Orleans 的 nuget 包

<PackageReference Include="Microsoft.Orleans.Client" Version="3.6.5" />

在 Program 中新增 Orleans 客戶端的配置

var builder = WebApplication.CreateBuilder(args);

var clientBuilder = new ClientBuilder();
clientBuilder.UseLocalhostClustering();

和服務端一樣使用 UseLocalhostClustering

透過單例將 client 配置進去

var builder = WebApplication.CreateBuilder(args);

var clientBuilder = new ClientBuilder();
clientBuilder.UseLocalhostClustering();
builder.Services.AddSingleton(sp =>
{
    var client = clientBuilder.Build();
    client.Connect().Wait();
    return client;
});

接著在 Blazor 的 Index Page 嘗試獲取我們剛剛儲存的 Job,需要新增 Contract 的專案引用

@page "/"
@using Orleans
@using HelloOrleans.Host.Contract.Entity
@using HelloOrleans.Host.Contract.Grain

<PageTitle>Index</PageTitle>

<h1>Hello, world!</h1>

Welcome to your new app.

<SurveyPrompt Title="How is Blazor working for you?" />

職位標題:@Model.Title
<br/>
職位描述:@Model.Description

@code
{
    [Inject]
    public IClusterClient ClusterClient { get; set; }

    public Job Model { get; set; } = new Job();

    protected override async Task OnInitializedAsync()
    {
        var jobId = "c1eb55ff-74bc-4747-a782-5786cc3cdf80";
        var jobGrain = ClusterClient.GetGrain<IJobGrain>(jobId);
        Model = await jobGrain.Get();
    }
}

相當於獲取 Job,然後將 Job 的相關資訊展現在頁面上

接著我們測試一下,先啟動 Host,再啟動 Blazor

可以看到我們已經獲取到了職位的資訊

原始碼連結:https://github.com/MingsonZheng/HelloOrleans

知識共享許可協議

本作品採用知識共享署名-非商業性使用-相同方式共享 4.0 國際許可協議進行許可。

歡迎轉載、使用、重新發布,但務必保留文章署名 鄭子銘 (包含連結: http://www.cnblogs.com/MingsonZheng/ ),不得用於商業目的,基於本文修改後的作品務必以相同的許可釋出。

如有任何疑問,請與我聯絡 (MingsonZheng@outlook.com) 。