11個顯著提升 ASP.NET 應用程式效能的技巧——第1部分

OneAPM官方技術部落格發表於2016-01-13

【編者按】本文出自站外作者 Brij Bhushan Mishra ,Brij 是微軟 MVP-ASP.NET/IIS、C# Corner MVP、CodeProject Insider,前 CodeProject MVP,CodeProject Mentor 以及 CodeProject Platinum Member,擁有6年左右的高階開發工程師/架構師經驗,自幼酷愛計算機。

採用 ASP.NET 和 IIS 構建 Web 應用程式並將其託管到 Web 伺服器上極其簡單,但是許多可提升 Web 應用程式效能的機會或隱藏配置同樣不能忽視。本系列博文將介紹一些簡單但卻可以應用於任何 Web 應用程式的技巧,而它們卻是經常被忽略或遺忘的。

1- 核心模式快取——這是廣泛用於程式編寫的主要工具之一,可加速 Web 應用程式。但是大多數時候,很少開發者以最佳方式應用核心模式快取,僅僅發揮其部分主要優勢。由於所有 ASP.NET 請求均會經歷不同階段,因此可在不同級別使用快取,具體如下所示。

11個顯著提升 ASP.NET 應用程式效能的技巧——第1部分

由上圖可見,http.sys 首先接收請求。由於 http.sys 是位於 OS 核心內且直接接收 TCP 層請求的http listener,因此如果使用核心級快取可節省大多用於伺服器的時間,同時可省去用於 IIS/ASP.NET Pipeline、頁面生命週期、自定義程式碼、資料庫等的所有時間。使用快取的具體步驟如下:

a)轉到 IIS 並選擇網站。 b)點選 IIS 部分正下方的Output Cache 圖示。 c)點選右側皮膚中 Actions 下方的 Add,出現以下對話方塊:

11個顯著提升 ASP.NET 應用程式效能的技巧——第1部分

首先需要在第一個紅框內確定快取至核心的副檔名,然後選中第二個紅框內的核取方塊。第三個紅框內為使快取失效的三個選項,可根據具體需求進行設定。

注:核心級快取具有一定侷限性。由於 IIS 所有功能均針對使用者級,因此無法使用任何功能。不能使用核心快取情況的完整列表見 msdn 文章。

2- Pipeline 模式(IIS 7+可用)——應用程式池級有兩種 Pipeline 模式可用:經典模式和整合模式。經典模式可用於支援來自 IIS6 的應用程式。因此,首先需要了解這兩種模式。IIS 許多功能均以 IIS 模組形式實現,同樣也有不少功能以 HTTP 模組實現,而 HTTP 模組構成 ASP.NET Pipeline 的一部分。在經典模式下,所有請求在被處理之前首先經過 IIS Pipeline,再經過 ASP.NET Pipeline。許多功能同時是兩種 Pipeline 的一部分,比如 Authentication。在整合模式下,兩種 Pipeline 合而為一,所有模組(IIS 模組及 ASP.NET 模組)出現時便從單一事件呼叫,從而降低冗餘性且對提升應用程式效能非常有幫助。

選擇相應應用程式池並右擊屬性,便可設定/更新 Pipeline 模式。

11個顯著提升 ASP.NET 應用程式效能的技巧——第1部分

可在上圖紅框內設定 Pipeline 模式。

注:切勿盲目更改設定。如果應用程式來自 IIS6,則可能對 IIS6 存在一定依賴性。因此,徹底更改設定後,進行測試後方可進入下一步。

3- 刪除不用的模組——所有請求均會經過 ASP.NET Pipeline,而 ASP.NET Pipeline 包含許多 HTTP 模組,以及一個 http handler,如下圖所示對請求進行處理:

11個顯著提升 ASP.NET 應用程式效能的技巧——第1部分

由上圖可見,請求經過所有模組,再經處理程式處理,然後再次經過各個模組。預設情況下,ASP.NET 應用程式究竟啟用了多少個模組。通過新增以下程式碼得到所有模組列表:

HttpApplication httpApps = HttpContext.ApplicationInstance;

//Get list of active modules
HttpModuleCollection httpModuleCollections = httpApps.Modules;
ViewBag.ModulesCount = httpModuleCollections.Count;

得到的模組可繫結至任何控制元件,具體結果如下:

11個顯著提升 ASP.NET 應用程式效能的技巧——第1部分

上圖顯示已啟用18個模組,而其中有些模組並未真正使用,但是請求仍需通過所有模組。因此,可從 Pipeline 中刪除不用的模組。只需在 web.config 中新增下列配置便可刪除模組:

 <system.webServer>
<modules>
  <remove name="FormsAuthentication" />
  <remove name="DefaultAuthentication" />
  <remove name="OutputCache" />
  <remove name="AnonymousIdentification" />
  <remove name="RoleManager" />
modules>
system.webServer>

此處,採用刪除標記列出需要刪除的模組。由於在此刪除了5個模組,下次檢視現用模組便只有13個。

注:示例為2013版,如果使用其他版本,得到的模組數可能不相同,但重點是需刪除不需要的模組。

4- 為所有請求執行所有託管模組——這是存在於 web.config 或 applicationHost.config中的另一配置,通過以下程式碼設定對IIS 上所有應用程式有效。

<modules runAllManagedModulesForAllRequests="true">

這意味著,可為到達應用程式的所有請求執行所有模組,但由於只需執行 ASP.NET 檔案而非 css、js、jpg、html等其他檔案,因此通常不需要執行所有模組。也就是說,即使這些資源的請求經過 Pipeline,但這些檔案並不需要通過 Pipeline,因為這樣只會增加額外開支,但不能僅僅在應用程式級設定為假。因此,可通過以下兩種方式解決:

a) 另外建立一個應用程式來處理上述靜態資源,並在 web.config 中將其設定為假。

b) 或者在同一應用程式中,將所有靜態資源放入一個資料夾,新增針對該資料夾的 web.config 檔案,並將其設定為假。

5- 切勿在資料夾 c:\inetpub\wwwroot中寫入任何內容——檔案觀察程式會檢視資料夾,如果資料夾出現任何變更,檔案觀察程式便會重啟相應的應用程式池。此功能在 IIS 中可用,如果 web.config 或任何檔案出現任何變更,檔案觀察程式便會重啟應用程式池,使得修改後的應用程式可處理請求。現在假設將應用程式日誌寫入應用程式資料夾內的文字檔案內,使得各請求均有幾個條目,從而導致應用程式池會多次重啟,這對應用程式具有危害性。因此,與此相反,請勿在此資料夾內寫入或變更任何內容,直至此檔案不再是 application binaries 的一部分。

6- 刪除多餘的檢視引擎——a)眾所周知,檢視引擎是 MVC 請求生命週期的一部分,且負責發現並處理檢視。也可新增自定義的檢視引擎。接下來建立預設的 MVC 應用程式並試圖返回解決方案中不存在的檢視。現在執行此應用程式會出現以下錯誤。

11個顯著提升 ASP.NET 應用程式效能的技巧——第1部分

上圖表明應用程式在查詢所有可能位置的 razor 和 aspx 檔案。但是由於已知使用的是 razor 檢視引擎並且查詢其他 aspx 檔案並不能解決問題,因此不應浪費時間查詢其他 aspx 檔案,從而應刪除多餘的檢視引擎。需要採用 Application_Start 方法新增以下程式碼,Application_Start 方法在 Global.asax 內可用。

 // Removing all the view engines
        ViewEngines.Engines.Clear();

        //Add Razor Engine (which we are using)
 ViewEngines.Engines.Add(new RazorViewEngine());

現在再次執行應用程式。

現在應用程式只查詢 razor 檔案。

b) 仔細看以上截圖可發現應用程式在查詢 c# 和 vb 檔案,假設解決方案中從未使用 vb,因此查詢 vbhtml 檔案並無任何作用。欲解決這個問題,需要編寫自定義的檢視引擎。因此,按照以下方法編寫自定義 razor 檢視引擎:

public class MyCustomViewEngine : RazorViewEngine
{
    public MyCustomViewEngine()
    {
        base.AreaViewLocationFormats = new string[] {"~/Areas/{2}/Views/{1}/{0}.cshtml", "~/Areas/{2}/Views/Shared/{0}.cshtml"};
        base.AreaMasterLocationFormats = new string[] {"~/Areas/{2}/Views/{1}/{0}.cshtml", "~/Areas/{2}/Views/Shared/{0}.cshtml" };
        base.AreaPartialViewLocationFormats = new string[] {"~/Areas/{2}/Views/{1}/{0}.cshtml","~/Areas/{2}/Views/Shared/{0}.cshtml"};
        base.ViewLocationFormats = new string[] { "~/Views/{1}/{0}.cshtml","~/Views/Shared/{0}.cshtml" };
        base.MasterLocationFormats = new string[] { "~/Views/{1}/{0}.cshtml","~/Views/Shared/{0}.cshtml" };
        base.PartialViewLocationFormats = new string[] {"~/Views/{1}/{0}.cshtml", "~/Views/Shared/{0}.cshtml" };
        base.FileExtensions = new string[] { "cshtml" };
    }
}

在此繼承了 RazorViewEngine,如果看見程式碼中的建構函式,則會發現已指定所有可能存在檔案的位置,也包括可能的副檔名。現在 Global.asax 內使用此檢視引擎。

執行應用程式。

11個顯著提升 ASP.NET 應用程式效能的技巧——第1部分

現在應用程式查詢 csharp razor 檔案,會獲得不錯的效能。

結論——本文介紹了可很容易用於任何 ASP.NET 應用程式的6個技巧:

1- 核心模式快取

2- Pipeline 模式

3- 刪除不用的模組

4- 為所有請求執行所有託管模組

5- 切勿在 wwwroot 內寫入任何內容

6- 刪除未使用的檢視引擎及語言

本系列後續博文將再介紹5個可用作應用程式效能提升器的技巧。敬請期待!

OneAPM 助您輕鬆鎖定 .NET 應用效能瓶頸,通過強大的 Trace 記錄逐層分析,直至鎖定行級問題程式碼。以使用者角度展示系統響應速度,以地域和瀏覽器維度統計使用者使用情況。想閱讀更多技術文章,請訪問 OneAPM 官方部落格

原文地址: http://www.infragistics.com/community/blogs/devtoolsguy/archive/2015/08/07/12-tips-to-increase-the-performance-of-asp-net-application-drastically-part-1.aspx

本文轉自 OneAPM 官方部落格

相關文章