如何測量並報告ASP.NET Core Web API請求的響應時間


介紹

大家都知道性能是API的流行語。而相應時間則是API性能的一個重要並且可測量的參數。在本文中,我們將了解如何使用代碼來測量API的響應時間,然后將響應時間數據返回到客戶端。

作者:依樂祝
原文地址:https://www.cnblogs.com/yilezhu/p/9520808.html

1

我們為什么需要測量響應時間

首先,讓我們先花一點時間思考下為什么我們需要這么一個特性來測量API的響應時間。下面是編寫代碼來捕獲響應時間的一些場景。

  1. 您需要為您的客戶定義API的SLA(服務水平協議)。客戶需要了解API響應的時間。響應時間數據可以幫助我們確定API的SLA。
  2. 管理層對報告應用程序的速度快慢感興趣。您需要有數據來證實您的報告的聲明。報告應用程序的性能並與利益相關者進行分享時值得的。
  3. 客戶端需要具有API的響應時間的信息,以便它們可以跟蹤在客戶端和服務器上花費了多少時間。
    您可能在項目中也遇到過類似的請求,因此研究一種捕獲API響應時間的方法是值得的。

在哪里添加測量代碼?

讓我們探索一些方法來捕獲API的響應時間,主要集中在捕獲API中花費的時間。我們的目標是計算從Asp.net Core運行時接收請求到處理響應並從服務器返回結果所經過的時間(以毫秒為單位)。

我們需要忽略哪些因素?

重要的是要理解這個討論不包括花在N/W上的時間,以及在IIS和應用程序池啟動中花費的時間。如果應用程序池未啟動並運行,則第一個請求可能會影響API的總體響應時間。我們可以使用一個應用程序初始化模塊,但這超出了本文的范圍。

第一次嘗試

捕獲API響應時間的一種非常異想天開的方法是在開始和結束時向每個API方法添加如下代碼,然后測量增量以計算響應時間,如下所示。

// GET api/values/5   
[HttpGet]  
public IActionResult Get() {  
    // Start the watch   
    var watch = new Stopwatch();  
    watch.Start();  
    // Your actual Business logic   
    // End the watch  
    watch.Stop();  
    var responseTimeForCompleteRequest = watch.ElapsedMilliseconds;  
}  

此代碼應該能夠計算操作所花費的時間。但由於以下原因,這似乎不是正確的方法。

  1. 如果API有很多操作,那么我們需要將這個代碼添加到多個不利於可維護性的地方。
  2. 此代碼僅測量在方法中花費的時間,它不測量在中間件,過濾器,控制器選擇,Action選擇,模型綁定等其他活動上花費的時間。

第二次嘗試

讓我們嘗試通過將代碼集中在一個地方來改進上面的代碼,以便更容易維護。我們需要在執行方法之前和之后執行響應時間的計算代碼。如果您使用過早期版本的Asp.net Web API,那么您將熟悉Filter的概念。過濾器允許您在請求處理管道中的特定階段之前或之后運行代碼。

我們將實現一個用於計算響應時間的過濾器,如下所示。我們將創建一個Filter並使用OnActionExecuting啟動計時器,然后在方法OnActionExecuted中停止計時器,從而計算API的響應時間。

public class ResponseTimeActionFilter: IActionFilter {  
    private const string ResponseTimeKey = "ResponseTimeKey";  
    public void OnActionExecuting(ActionExecutingContext context) {  
        // Start the timer   
        context.HttpContext.Items[ResponseTimeKey] = Stopwatch.StartNew();  
    }  
    public void OnActionExecuted(ActionExecutedContext context) {  
        Stopwatch stopwatch = (Stopwatch) context.HttpContext.Items[ResponseTimeKey];  
        // Calculate the time elapsed   
        var timeElapsed = stopwatch.Elapsed;  
    }  
}  

此代碼不是計算響應時間的可靠技術,因為它沒有解決計算執行中間件,控制器選擇,操作方法選擇,模型綁定等所花費的時間的問題。過濾器管道在MVC選擇Action后執行。因此,它實際上無法檢測在其他Asp.net管道中花費的時間。

2

第三次嘗試

我們將使用Asp.net Core中間件來計算API的響應時間

所以,什么是中間件呢?

基本上,中間件是處理請求/響應的軟件組件。中間件被組裝到應用程序管道中並在傳入請求中提供服務。每個組件執行以下操作。

  1. 選擇是否將請求傳遞給管道中的下一個組件。

  2. 可以在調用管道中的下一個組件之前和之后執行工作。

如果您在ASP.NET中使用過HTTPModules或HTTPHandler,那么您可以將中間件視為ASP.NET Core中的替代品。一些中間件的例子是 :

  • MVC中間件

  • Authentication中間件

  • Static File Serving

  • Caching

  • CORS 等等

    3

    我們希望在請求進入ASP.NET Core管道后添加代碼以啟動計時器,並在管道處理響應后停止計時器。請求管道開始時的自定義中間件似乎是訪問請求最早訪問並在管道中執行最后一步之前進行訪問的最佳方法。

    我們將構建一個響應時間中間件,我們將其作為第一個中間件添加到請求管道中,以便我們可以在請求進入Asp.net Core管道后立即啟動計時器。

    如何處理響應時間數據呢?

    一旦我們捕獲到響應時間數據,我們就可以通過以下方式來進行數據的處理。

    1. 將響應時間數據添加到報告數據庫或分析解決方案。
    2. 將響應時間數據寫入日志文件。
    3. 將響應時間數據傳遞到消息隊列,該消息隊列可以由另一個應用程序進一步處理以進行報告和分析。
    4. 使用響應頭將響應時間信息發送到使用我們的Rest API的客戶端應用程序。
      可能還有其他有用的方法來使用響應時間數據。您可以在評論區進行留言,並告訴我您是如何處理應用程序中的響應時間數據的。

    我們開始寫代碼吧

    我們將按照下面的處理步驟來進行代碼的編寫。

    1. 計算API的響應時間數據
    2. 通過在響應頭中傳遞數據將數據報告回客戶端應用程序。

    ResponseTimeMiddleware的完整代碼片段如下所示:

    public class ResponseTimeMiddleware {  
        // Name of the Response Header, Custom Headers starts with "X-"  
        private const string RESPONSE_HEADER_RESPONSE_TIME = "X-Response-Time-ms";  
        // Handle to the next Middleware in the pipeline  
        private readonly RequestDelegate _next;  
        public ResponseTimeMiddleware(RequestDelegate next) {  
            _next = next;  
        }  
        public Task InvokeAsync(HttpContext context) {  
            // Start the Timer using Stopwatch  
            var watch = new Stopwatch();  
            watch.Start();  
            context.Response.OnStarting(() => {  
                // Stop the timer information and calculate the time   
                watch.Stop();  
                var responseTimeForCompleteRequest = watch.ElapsedMilliseconds;  
                // Add the Response time information in the Response headers.   
                context.Response.Headers[RESPONSE_HEADER_RESPONSE_TIME] = responseTimeForCompleteRequest.ToString();  
                return Task.CompletedTask;  
            });  
            // Call the next delegate/middleware in the pipeline   
            return this._next(context);  
        }  
    }  
    

代碼說明

主要的代碼是在InvokeAsync方法中,一旦請求進入到第一個中間件,我們使用秒表類來啟動秒表,然后在處理請求完成后並且響應准備好返回給客戶端的Response后停止秒表。OnStarting方法提供了編寫自定義代碼的機會,以便在將響應頭發送到客戶端之前添加要調用的委托中。
最后,我們在自定義標題中添加響應時間信息。我們使用X-Response-Time-ms標頭作為響應標頭。作為慣例,自定義標題以X開頭。

總結

在本文中,我們了解了如何利用ASP.NET中間件來管理跨領域問題,例如測量API的響應時間。使用中間件還有其他各種有用的用例,可以幫助重用代碼並提高應用程序的可維護性。
本文翻譯自https://www.c-sharpcorner.com/technologies/Asp-Net-core

我的博客即將搬運同步至騰訊雲+社區,邀請大家一同入駐:https://cloud.tencent.com/developer/support-plan?invite_code=36oxtdlslwowo


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM