精細度服務
精細度服務可從遠端存取,可分割服務以支援功能精細度。 每個精細度服務的執行個體都負責一組精細度,而這些精細度可以藉由使用 GrainServiceClient
,取得目前負責為其提供服務之精細度服務的參考。
「精細度服務」存在,以支援負責服務的精細度應分散在 Orleans 叢集周圍的案例。 例如,Orleans Reminders 是使用精細度服務來實作:每個定址接收器都會負責處理一部分精細度的提醒作業,並在提醒引發時通知這些精細度。
精細度服務會在定址接收器上設定,在定址接收器啟動時並且在定址接收器完成初始化之前初始化。 閒置時不會收集,而是擁有會針對定址接收器本身延長的存留期。
建立 GrainService
GrainService 是特殊的精細度;沒有穩定的身分識別,並在每個定址接收器中執行,從啟動到關機。 實作 IGrainService 介面時牽涉到數個步驟。
定義精細度服務通訊介面。
GrainService
的介面是使用您用來建置精細度介面的相同原則所建置。public interface IDataService : IGrainService { Task MyMethod(); }
建立
DataService
精細度服務。 最好知道您也可以插入 IGrainFactory,以便從GrainService
進行精細度呼叫。[Reentrant] public class DataService : GrainService, IDataService { readonly IGrainFactory _grainFactory; public DataService( IServiceProvider services, GrainId id, Silo silo, ILoggerFactory loggerFactory, IGrainFactory grainFactory) : base(id, silo, loggerFactory) { _grainFactory = grainFactory; } public override Task Init(IServiceProvider serviceProvider) => base.Init(serviceProvider); public override Task Start() => base.Start(); public override Task Stop() => base.Stop(); public Task MyMethod() { // TODO: custom logic here. return Task.CompletedTask; } }
[Reentrant] public class DataService : GrainService, IDataService { readonly IGrainFactory _grainFactory; public DataService( IServiceProvider services, IGrainIdentity id, Silo silo, ILoggerFactory loggerFactory, IGrainFactory grainFactory) : base(id, silo, loggerFactory) { _grainFactory = grainFactory; } public override Task Init(IServiceProvider serviceProvider) => base.Init(serviceProvider); public override Task Start() => base.Start(); public override Task Stop() => base.Stop(); public Task MyMethod() { // TODO: custom logic here. return Task.CompletedTask; } }
建立 GrainServiceClient<TGrainService>
GrainServiceClient
的介面,讓其他精細度用來連線到GrainService
。public interface IDataServiceClient : IGrainServiceClient<IDataService>, IDataService { }
建立精細度服務用戶端。 用戶端通常會作為其目標精細度服務的 Proxy,因此您通常會在目標服務上為每個方法新增方法。 這些方法需要取得其目標精細度服務的參考,以便進行呼叫。
GrainServiceClient<T>
基底類別提供GetGrainService
方法的數個多載,此方法可以傳回對應至GrainId
的精細度參考、數值雜湊 (uint
) 或SiloAddress
。 後面兩個多載適用於開發人員想要使用不同機制將責任對應至主機,或想要直接定址主機的進階案例。 在下方的範例程式碼中,我們會定義GrainService
屬性,其會傳回呼叫IDataService
之精細度的DataServiceClient
。 為了完成此操作,我們會使用GetGrainService(GrainId)
多載搭配CurrentGrainReference
屬性。public class DataServiceClient : GrainServiceClient<IDataService>, IDataServiceClient { public DataServiceClient(IServiceProvider serviceProvider) : base(serviceProvider) { } // For convenience when implementing methods, you can define a property which gets the IDataService // corresponding to the grain which is calling the DataServiceClient. private IDataService GrainService => GetGrainService(CurrentGrainReference.GrainId); public Task MyMethod() => GrainService.MyMethod(); }
建立實際的精細度服務用戶端。 這只是作為資料服務的 Proxy。 可惜的是,您必須手動輸入所有方法對應,這只是簡單的單行程式碼。
public class DataServiceClient : GrainServiceClient<IDataService>, IDataServiceClient { public DataServiceClient(IServiceProvider serviceProvider) : base(serviceProvider) { } public Task MyMethod() => GrainService.MyMethod(); }
將精細度服務用戶端插入其他需要該用戶端的精細度。
GrainServiceClient
不保證可以在本機定址接收器上存取GrainService
。 您的命令可能會傳送至叢集中任何定址接收器上的GrainService
。public class MyNormalGrain: Grain<NormalGrainState>, INormalGrain { readonly IDataServiceClient _dataServiceClient; public MyNormalGrain( IGrainActivationContext grainActivationContext, IDataServiceClient dataServiceClient) => _dataServiceClient = dataServiceClient; }
在定址接收器中設定精細度服務和精細度服務用戶端。 您需要這樣做,定址接收器才會啟動
GrainService
。(ISiloHostBuilder builder) => builder.ConfigureServices( services => services.AddGrainService<DataService>() .AddSingleton<IDataServiceClient, DataServiceClient>());
其他注意事項
GrainServicesSiloBuilderExtensions.AddGrainService 上有一個擴充方法,可用來註冊精細度服務。
services.AddSingleton<IGrainService>(
serviceProvider => GrainServiceFactory(grainServiceType, serviceProvider));
定址接收器在啟動時從服務提供者擷取 IGrainService
類型:orleans/src/Orleans.Runtime/Silo/Silo.cs
var grainServices = this.Services.GetServices<IGrainService>();
Microsoft.Orleans.Runtime NuGet 套件應該由 GrainService
專案參考。
Microsoft.Orleans.OrleansRuntime NuGet 套件應該由 GrainService
專案參考。
為了讓此作業能夠運作,您必須同時註冊服務及其用戶端。 程式碼會與下列內容類似:
var builder = new HostBuilder()
.UseOrleans(c =>
{
c.AddGrainService<DataService>() // Register GrainService
.ConfigureServices(services =>
{
// Register Client of GrainService
services.AddSingleton<IDataServiceClient, DataServiceClient>();
});
})