Dapr专题之06Actors
#Dapr Actors
文章目錄
- Actors簡介以及優勢
- 調用終結點
- 代碼編寫
- 運行與測試
- Timer和Reminders
- 啟動并測試
- 總結
提示:以下是本篇文章正文內容,下面案例可供參考
Actors簡介以及優勢
-
是一種單線程執行的工作模式
-
避免代碼里顯示lock
-
避免死鎖,避免性能問題
-
使并發編程簡單
調用終結點
http://localhost:<dapr-port>/v1.0/actors/<actorType>/<actorId>/- <dapr-port>:Dapr正在偵聽的HTTP端口
- <actorType>:執行組件類型。
- <actorId>:要調用的特定參與者的ID。
代碼編寫
新建類庫Common,引入Nuget包:
Dapr.Actors
Dapr.Actors.AspNetCore
新建接口IWorkflowActor,寫入以下代碼:
public interface IWorkflowActor : IActor{Task<bool> Approve();}BackEnd 引用Common,新建Actors文件夾,定義WorkflowActor,實現IWorkflowActor
public class WorkflowActor : Actor, IWorkflowActor{public WorkflowActor(ActorHost host) : base(host){}public async Task<bool> Approve(){await StateManager.AddOrUpdateStateAsync(Id.ToString(), "approve", (key, currentStatus) => "approve");return true;} }注冊Actors,映射Actors路由
builder.Services.AddActors(options =>{options.Actors.RegisterActor<WorkflowActor>();});app.MapActorsHandlers();FrontEnd引入Common,并新建ActorsClientController,添加以下接口
[HttpGet("{orderId}")] public async Task<ActionResult> ApproveAsync(string orderId) {var actorId = new ActorId("actorprifix-" + orderId);var proxy = ActorProxy.Create<IWorkflowActor>(actorId, "WorkflowActor");return Ok(await proxy.Approve()); }運行與測試
- 啟動BackEnddapr run --dapr-http-port 3511 --app-port 5000 --app-id backend dotnet .\BackEnd\bin\Debug\net6.0\BackEnd.dll --app-ssl
- 啟動FrontEnddapr run --dapr-http-port 3501 --app-port 5001 --app-id frontend dotnet .\FrontEnd\bin\Debug\net6.0\FrontEnd.dll
調用API可以看到成功返回true:
http://localhost:5001/api/ActorsClient/123
Redis里面也可以看到狀態變為了approve
Timer和Reminders
-
timer和reminder可以設置后臺定時觸發Actor,兩者區別在于,Timer的數據是不會持久化的且只能作用于激活狀態的Actor,Reminders則反之。
-
代碼實現
- 在IWorkflowActor中聲明如下方法 Task RegisterTimer();Task UnregisterTimer();Task RegisterReminder();Task UnregisterReminder();
- 在WorkflowActor中繼承IRemindable并實現以下方法public Task RegisterTimer() {var serializedTimerParams = JsonSerializer.SerializeToUtf8Bytes("now is " + DateTime.Now.ToString());//TestTimer 注冊進Actor的名稱//nameof(this.TimerCallback) 注冊進Actor的方法//serializedTimerParams 注冊進Actor的方法的參數//TimeSpan.FromSeconds(3) 多長時間后第一次執行//TimeSpan.FromSeconds(3) 間隔多長時間執行return this.RegisterTimerAsync("TestTimer", nameof(this.TimerCallback), serializedTimerParams, TimeSpan.FromSeconds(3), TimeSpan.FromSeconds(3)); }public async Task TimerCallback(byte[] data) {var stateKey = "nowtime";var content = JsonSerializer.Deserialize<string>(data);_logger.LogInformation(" ---------" + content);await this.StateManager.SetStateAsync<string>(stateKey, content); }public Task UnregisterTimer() {//從Actor中注銷return this.UnregisterTimerAsync("TestTimer"); }public async Task RegisterReminder() {await this.RegisterReminderAsync("TestReminder", null, TimeSpan.FromSeconds(5), TimeSpan.FromSeconds(5)); }public async Task ReceiveReminderAsync(string reminderName, byte[] state, TimeSpan dueTime, TimeSpan period) {var stateKey = "nowtime";var content = "now is " + DateTime.Now.ToString();_logger.LogInformation(" reminder---------" + content);await this.StateManager.SetStateAsync<string>(stateKey, content); }public Task UnregisterReminder() {return this.UnregisterReminderAsync("TestReminder"); }
- 在ActorsClientController中新增以下接口[HttpGet("timer/{orderId}")] public async Task<ActionResult> TimerAsync(string orderId) {var actorId = new ActorId("actorprifix-" + orderId);var proxy = ActorProxy.Create<IWorkflowActor>(actorId, "WorkflowActor");await proxy.RegisterTimer();return Ok("done"); }[HttpGet("unregist/timer/{orderId}")] public async Task<ActionResult> UnregistTimerAsync(string orderId) {var actorId = new ActorId("actorprifix-" + orderId);var proxy = ActorProxy.Create<IWorkflowActor>(actorId, "WorkflowActor");await proxy.UnregisterTimer();return Ok("done"); }[HttpGet("reminder/{orderId}")] public async Task<ActionResult> ReminderAsync(string orderId) {var actorId = new ActorId("actorprifix-" + orderId);var proxy = ActorProxy.Create<IWorkflowActor>(actorId, "WorkflowActor");await proxy.RegisterReminder();return Ok("done"); }[HttpGet("unregist/reminder/{orderId}")] public async Task<ActionResult> UnregistReminderAsync(string orderId) {var actorId = new ActorId("actorprifix-" + orderId);var proxy = ActorProxy.Create<IWorkflowActor>(actorId, "WorkflowActor");await proxy.UnregisterReminder();return Ok("done"); }
啟動并測試
- 啟動BackEnddapr run --dapr-http-port 3511 --app-port 5000 --app-id backend dotnet .\BackEnd\bin\Debug\net6.0\BackEnd.dll --app-ssl
- 啟動FrontEnddapr run --dapr-http-port 3501 --app-port 5001 --app-id frontend dotnet .\FrontEnd\bin\Debug\net6.0\FrontEnd.dll
測試timer:
http://localhost:5001/api/ActorsClient/timer/123
查看Redis中的值:
在此處,我們可以把BackEnd 重啟一下,可以發現timer不會觸發,也驗證了文章開頭所說的timer不會持久化
測試reminder:
http://localhost:5001/api/ActorsClient/reminder/123
查看Redis中的值:
在此處,我們同樣把BackEnd 重啟一下,可以發現reminder還是會觸發,驗證了reminder會進行數據持久化操作
總結
以上就是這次要給大家分享的內容,本文介紹了Dapr中關于Actors的相關內容,下次將給大家介紹Dapr中的綁定,歡迎各位朋友點贊收藏,同時希望本文能夠給大家帶來一絲幫助與啟發。總結
以上是生活随笔為你收集整理的Dapr专题之06Actors的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 设计模式之美 精华总结 笔记(一)
- 下一篇: 今天给大家分享的案例就是关于电影的啦,我