手動控制IHostService,讓你的後臺任務更加靈活

起因

老闆前段時間找到我,微信會員卡註冊會員爲什麼這麼久?想辦法把這裏優化下。

這樣就有了我們的故事。

首先我們分析下原因:

  • 1:註冊微信會員卡,需要2步,第一步領取會員卡,第二步填寫個人信息,會員操作這2步的時間可長可短,程序無法控制。
  • 2:接收微信的事件推送,我們使用的redis隊列來處理,所有的消息都被丟進一個隊列裏。在消費端是單線程消費,當短時間內數據量大時,會導致時間延遲過長。 

優化方法

既然知道了原因,那麼剩下的就是解決問題。

  • 1:解決原因1,因會員行爲無法操控,所以只能通過調整優化領取會員卡-註冊會員的步驟。從微信官方文檔有找到開卡組件的使用,結合開卡組件,可以有效達到優化目的。具體請自行查看微信會員卡開卡組件官方文檔,這裏不做展開。
  • 2:解決原因2,核心思想是多線程。這裏有2個方向,一是在消費端開啓多線程消費隊列,二是啓用多個隊列。因爲我們的業務是依賴於公衆號,所以可以根據公衆號的appid來啓用隊列。所以我們選擇了二,並且將隊列改爲redis的發佈訂閱。這時候又出現新的問題,公衆號可能隨時會增加或減少,但是IHostService只是在程序啓動時纔會注入,並且是單例注入。下面是.NET Core Host的源碼
_hostedServices = Services.GetService<IEnumerable<IHostedService>>();

foreach (var hostedService in _hostedServices)
{
    // Fire IHostedService.Start
    await hostedService.StartAsync(combinedCancellationToken).ConfigureAwait(false);
}

 

那個剩下的事情就比較簡單了,只需要在公衆號增加或者減少時,加入如下代碼就OK了。

using (var scope = serviceProvider.CreateScope())
                {
                    var hostedServices = scope.ServiceProvider.GetRequiredService<IEnumerable<IHostedService>>();
                    if (hostedServices.Any())
                    {
                        foreach (var host in hostedServices)
                        {
                            if (host is yourHostService )
                            {
                                host.StartAsync(new CancellationToken()).ConfigureAwait(false).GetAwaiter().GetResult();
                            }
                        }
                    }
                }

 

結束

上面廢話一大堆,真正有用的也就最後這幾行代碼。希望對有需要的人有幫助

遇到問題,理性分析,其實沒有那麼難

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章