手动控制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();
                            }
                        }
                    }
                }

 

结束

上面废话一大堆,真正有用的也就最后这几行代码。希望对有需要的人有帮助

遇到问题,理性分析,其实没有那么难

 

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