.NetCore集成Dapr踩坑經歷

該篇內容由個人博客點擊跳轉同步更新!轉載請注明出處

前言

之前自己有個core2.2的項目一直是用的Surging作為微服務框架的,后來了解到了Dapr,發現比較輕量級,而且像微服務的一些功能比如熔斷啥的也用不到,開發部署等也非常方便,故將自己的程序升級到了3.0同時框架改成了Dapr,網上查到的好多Dapr文章基本都是大差不同,大都是用的GIT上的示例或者是直接文章翻譯很少有提到實戰上的一些問題,下面我把我自己遇到的一些問題和解決方法記錄一下同時大致講下安裝集成步驟。

前期準備

  1. 安裝 Docker(dapr安裝完后會在Docker中生成兩個容器Dapr_redis和Dapr_placement)
  2. 安裝?Dapr CLI(用于使用Dapr的一些命令)
  3. 安裝?.Net Core SDK 3.0(Dapr只能用于3.0的程序中)
  4. 下載dotnet-sdk(Nuget上暫時只有預覽版,所以直接用源碼集成方便源碼調試)

注意:安裝dapr cli的時候他會讓你用 一段powershell腳本安裝,但由于國內墻的問題使用不了所以需要xxxxemmmm,另一個辦法就是直接去release下載文件https://github.com/dapr/cli/releases

具體安裝命令步驟啥的不說了,鏈接點擊過去都有介紹

大致集成步驟

具體的如何集成和配置網上都有大家可以看下這篇GIT上的集成步驟,我這里直接給大家看下我示例程序的項目結構重要的內容會寫在括號里
項目結構

  1. Clients目錄下都是用于調用服務的客戶端(這里都是通過ActorProxy的RPC方式調用,有點像SF、akka.net和Orleans,都引用下面的Service_Interfaces)
  2. Dapr目錄下就是上面下載的Dapr源代碼
  3. CSRedisCore我項目里面用到了Redis所以把CSRedisCore的源代碼下載了下來
  4. Service_Infrastructure 服務的基礎設施存放一些通用的東西或者幫助類
  5. Service_Interfaces服務的接口都在這里(引用Dapr.Actors)
  6. Service_Models服務和客戶端用到的模型都在這
  7. 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服務中如何使用依賴注入

對于這個問題有兩個解決方法:

  1. 默認的服務實現中構造函數只能有兩個參數ActorServiceActorId,但是它在注冊的時候提供了另一個構造方法,比如我的一個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($"//localhost:{5000}/");
  1. 第一個方法有局限性,和自己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服務中的每個方法最多只能有一個參數,多個參數的話都變成寫成一個實體進行傳遞,不然會報錯
參數
2. Dapr提供了一個可視化界面 dashboard 這個暫時有點問題,谷歌打不開,但edge可以,貌似是Angular的BUG,所以推薦大家暫時不要用,因為功能很少不如直接dapr cli方便

結語

大致的問題就如上面這些,但我記得還有幾個隔了一天年紀太大忘光了,后續有新問題我會繼續更新。不要問我dapr和其它微服務框架比效率性能哪個好,我也沒試過。這玩意兒既然是微軟開源的我想也不會太差,而且有專業的團隊維護,不出太大意外我想發展肯定是越來越好的。

微信關注我哦!(轉載注明出處)關注我哦

posted @ 2020-01-01 16:08  邵佳楠  閱讀(...)  評論(...編輯  收藏