之前自己有個core2.2的項目一直是用的Surging作為微服務框架的,後來瞭解到了Dapr,發現比較輕量級,開發部署等也非常方便,故將自己的程式升級到了3.0同時框架改成了Dapr,網上查到的好多Dapr文章基本都是大差不同,大都是用的GIT上的示例或者是直接文章翻譯很少有提到實戰上的一些問題,... ...
該篇內容由個人博客點擊跳轉同步更新!轉載請註明出處
前言
之前自己有個core2.2的項目一直是用的Surging作為微服務框架的,後來瞭解到了Dapr,發現比較輕量級,而且像微服務的一些功能比如熔斷啥的也用不到,開發部署等也非常方便,故將自己的程式升級到了3.0同時框架改成了Dapr,網上查到的好多Dapr文章基本都是大差不同,大都是用的GIT上的示例或者是直接文章翻譯很少有提到實戰上的一些問題,下麵我把我自己遇到的一些問題和解決方法記錄一下同時大致講下安裝集成步驟。
前期準備
- 安裝 Docker(dapr安裝完後會在Docker中生成兩個容器Dapr_redis和Dapr_placement)
- 安裝 Dapr CLI(用於使用Dapr的一些命令)
- 安裝 .Net Core SDK 3.0(Dapr只能用於3.0的程式中)
下載dotnet-sdk(Nuget上暫時只有預覽版,所以直接用源碼集成方便源碼調試)
註意:安裝dapr cli的時候他會讓你用 一段powershell腳本安裝,但由於國內牆的問題使用不了所以需要xxxxemmmm,另一個辦法就是直接去release下載文件https://github.com/dapr/cli/releases
具體安裝命令步驟啥的不說了,鏈接點擊過去都有介紹
大致集成步驟
具體的如何集成和配置網上都有大家可以看下這篇GIT上的集成步驟,我這裡直接給大家看下我示常式序的項目結構重要的內容會寫在括弧里
- Clients目錄下都是用於調用服務的客戶端(這裡都是通過ActorProxy的RPC方式調用,有點像SF、akka.net和Orleans,都引用下麵的Service_Interfaces)
- Dapr目錄下就是上面下載的Dapr源代碼
- CSRedisCore我項目裡面用到了Redis所以把CSRedisCore的源代碼下載了下來
- Service_Infrastructure 服務的基礎設施存放一些通用的東西或者幫助類
- Service_Interfaces服務的介面都在這裡(引用Dapr.Actors)
- Service_Models服務和客戶端用到的模型都在這
- Service_Webapi為客戶端提供服務(引用Dapr.Actors和Dapr.Actors.AspNetCore)
具體項目依賴如下圖
錯誤內容和解決方法
由於目標電腦積極拒絕,無法連接。
ERROR: DaprHttpInteractor: System.Net.Http.HttpRequestException: 由於目標電腦積極拒絕,無法連接。
---> System.Net.Sockets.SocketException (10061): 由於目標電腦積極拒絕,無法連接。
這是由於dotnet-sdk預設調用的埠是3500但你通過Darp運行的程式埠是隨機的所以運行的時候需要指定一個埠通過 -port xx,例如:
dapr run --port 3500 --app-id demo_actor --app-port 5000 dotnet run
或者通過指定程式調用的埠通過設置DAPR_HTTP_PORT
的環境變數來指定程式調用埠
ERR_INVOKE_ACTOR
Error converting value "ERR_INVOKE_ACTOR" to type 'System.Nullable
這是由於作者在程式中少寫了這個狀態應該算個bug我提交了issue但還沒回我,具體的在DaprErrorCodes文件中最後加一下就行
Actor服務中如何使用依賴註入
對於這個問題有兩個解決方法:
- 預設的服務實現中構造函數只能有兩個參數ActorService和ActorId,但是它在註冊的時候提供了另一個構造方法,比如我的一個redis服務構造函數是這樣的,裡面iredisprovider需要通過註入來獲取
可以在註冊actor的時候提供你所需要的東西,如下
public static IWebHostBuilder CreateHostBuilder(string[] args)=>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>()
.UseActors(actorRuntime =>
{
//重點
actorRuntime.RegisterActor<RedisCachesService>((type) => new ActorService(type, (actorService, actorId) => new RedisCachesService(new RedisProvider(),actorService, actorId)));
})
.UseUrls($"http://localhost:{5000}/");
- 第一個方法有局限性,和自己new對象沒啥區別。所以這裡推薦自己實現一個ServiceLocator用來獲取所需要的服務,簡單寫一下用法,定義一個ServiceLocator類
public class ServiceLocator
{
public static IServiceProvider Current { get; set; }
}
在startup > configure 中賦值
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
ServiceLocator.Current = app.ApplicationServices;
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseHsts();
}
在Actor服務中使用
public RedisCachesService(ActorService actorService, ActorId actorId) : base(actorService, actorId)
{
using (var scoped=ServiceLocator.Current.CreateScope())
{
_cr = scoped.ServiceProvider.GetService<IRedisProvider>().GetInstance();
}
}
需要註意的點
1.Actor服務中的每個方法最多只能有一個參數,多個參數的話都變成寫成一個實體進行傳遞,不然會報錯
Dapr提供了一個可視化界面 dashboard 這個暫時有點問題,谷歌打不開,但edge可以,貌似是Angular的BUG,所以推薦大家暫時不要用,因為功能很少不如直接dapr cli方便
結語
大致的問題就如上面這些,但我記得還有幾個隔了一天年紀太大忘光了,後續有新問題我會繼續更新。不要問我dapr和其它微服務框架比效率性能哪個好,我也沒試過。這玩意兒既然是微軟開源的我想也不會太差,而且有專業的團隊維護,不出太大意外我想發展肯定是越來越好的。
微信關註我哦!(轉載註明出處)