如何预热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,减少初次执行时间的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: WPF中的触发器(Trigger)
- 下一篇: 开源软件的痛点