Dapr专题之06Actors
#Dapr Actors
文章目錄
- Actors簡介以及優(yōu)勢
- 調(diào)用終結(jié)點
- 代碼編寫
- 運行與測試
- Timer和Reminders
- 啟動并測試
- 總結(jié)
提示:以下是本篇文章正文內(nèi)容,下面案例可供參考
Actors簡介以及優(yōu)勢
-
是一種單線程執(zhí)行的工作模式
-
避免代碼里顯示lock
-
避免死鎖,避免性能問題
-
使并發(fā)編程簡單
調(diào)用終結(jié)點
http://localhost:<dapr-port>/v1.0/actors/<actorType>/<actorId>/- <dapr-port>:Dapr正在偵聽的HTTP端口
- <actorType>:執(zhí)行組件類型。
- <actorId>:要調(diào)用的特定參與者的ID。
代碼編寫
新建類庫Common,引入Nuget包:
Dapr.Actors
Dapr.Actors.AspNetCore
新建接口IWorkflowActor,寫入以下代碼:
public interface IWorkflowActor : IActor{Task<bool> Approve();}BackEnd 引用Common,新建Actors文件夾,定義WorkflowActor,實現(xiàn)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
調(diào)用API可以看到成功返回true:
http://localhost:5001/api/ActorsClient/123
Redis里面也可以看到狀態(tài)變?yōu)榱薬pprove
Timer和Reminders
-
timer和reminder可以設(shè)置后臺定時觸發(fā)Actor,兩者區(qū)別在于,Timer的數(shù)據(jù)是不會持久化的且只能作用于激活狀態(tài)的Actor,Reminders則反之。
-
代碼實現(xiàn)
- 在IWorkflowActor中聲明如下方法 Task RegisterTimer();Task UnregisterTimer();Task RegisterReminder();Task UnregisterReminder();
- 在WorkflowActor中繼承IRemindable并實現(xiàn)以下方法public Task RegisterTimer() {var serializedTimerParams = JsonSerializer.SerializeToUtf8Bytes("now is " + DateTime.Now.ToString());//TestTimer 注冊進Actor的名稱//nameof(this.TimerCallback) 注冊進Actor的方法//serializedTimerParams 注冊進Actor的方法的參數(shù)//TimeSpan.FromSeconds(3) 多長時間后第一次執(zhí)行//TimeSpan.FromSeconds(3) 間隔多長時間執(zhí)行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 重啟一下,可以發(fā)現(xiàn)timer不會觸發(fā),也驗證了文章開頭所說的timer不會持久化
測試reminder:
http://localhost:5001/api/ActorsClient/reminder/123
查看Redis中的值:
在此處,我們同樣把BackEnd 重啟一下,可以發(fā)現(xiàn)reminder還是會觸發(fā),驗證了reminder會進行數(shù)據(jù)持久化操作
總結(jié)
以上就是這次要給大家分享的內(nèi)容,本文介紹了Dapr中關(guān)于Actors的相關(guān)內(nèi)容,下次將給大家介紹Dapr中的綁定,歡迎各位朋友點贊收藏,同時希望本文能夠給大家?guī)硪唤z幫助與啟發(fā)。總結(jié)
以上是生活随笔為你收集整理的Dapr专题之06Actors的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 设计模式之美 精华总结 笔记(一)
- 下一篇: 今天给大家分享的案例就是关于电影的啦,我