如何预热Web API,减少初次执行时间
Posted dotNET跨平台
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何预热Web API,减少初次执行时间相关的知识,希望对你有一定的参考价值。
前言
在上次的《差距50倍!为什么Web API第一次执行这么慢?》文章中,我们发现了部分耗时比较大的方法:
Microsoft.AspNetCore.Mvc.Infrastructure.ActionInvokerFactory.CreateInvoker - 30.15ms
查看源代码,ActionInvokerFactory使用的是Singleton生命周期:
services.TryAddSingleton<IActionInvokerFactory, ActionInvokerFactory>();
而在构造函数中,会执行排序方法:
public ActionInvokerFactory(IEnumerable<IActionInvokerProvider> actionInvokerProviders)
_actionInvokerProviders = actionInvokerProviders.OrderBy(item => item.Order).ToArray();
我想,这应该是初次执行时间较长的部分原因。
思路
使用Singleton生命周期的类,在应用的生存期内仅创建一次,相当于静态类。
如果我们在执行Web API之前,就使用过了ActionInvokerFactory,那么在第一次执行Web API时就不会再次初始化它,应该可以减少初次执行时间。
验证
创建一个WarmController,代码非常简单:
[ApiController]
[Route("[controller]")]
public class WarmController : ControllerBase
[HttpGet]
public string Get()
return "OK";
首先访问Warm接口,再访问WeatherForecast接口,发现初次访问WeatherForecast的执行时间确实大幅减少:
未预热 | 预热后 | |
---|---|---|
初次执行时间 | 100ms | 21ms |
实现
但是,不太好每次启动服务后,都先手工访问一下预热接口。
我们可以设置成,在启动后,自动访问一下预热接口。
利用应用程序生存期事件,可以达到这一目的。
修改Startup.cs,代码如下:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env, IHostApplicationLifetime lifetime)
...
lifetime.ApplicationStarted.Register(OnAppStarted);
public void OnAppStarted()
var url = Configuration[WebHostDefaults.ServerUrlsKey];
var warm = url.Split(';')[0] + "/warm";
new HttpClient().GetAsync(warm).Wait();
启动后访问WeatherForecast接口,发现确实已经预热过了。
结论
在本文中,我们利用了ASP.NET Core应用程序生存期事件,实现了Web API预热。
如果你觉得这篇文章对你有所启发,请关注我的个人公众号”My IO“
以上是关于如何预热Web API,减少初次执行时间的主要内容,如果未能解决你的问题,请参考以下文章
N95 上的 J2ME 位置 API - 需要打开诺基亚地图来预热 GPS?