IIS上解決ASP.Net第一次訪問慢的處理

IIS中應用程序池和網站是單獨存在的,但是網站運行必須建立在對應的應用程序池啓動的前提下。

默認情況下,應用程序池在不活動情況下(無請求操作),一段時間後,將被IIS自動回收掉。
 

本篇經驗中的方法能解決ASP.Net第一次訪問慢,間隔一段時間後,又訪問慢的問題。

安裝IIS應用程序初始化功能,如下圖所示:

應用程序開發->應用程序初始化

編輯網站對應應用程序池啓動模式,操作路徑:應用程序池 -> 網站對應程序池 -> 右鍵,高級設置 ->選擇,啓動模式 AlwaysRunning,如下圖所示:

開啓對應網站預加載,操作路徑:網站 -> 對應網站 -> 右鍵,高級設置 ->選擇,預加載已啓用 True,如下圖所示:

設置配置編輯器,編寫默認預加載請求,打開配置編輯器,如下圖所示:

在左上角配置節點選擇system.webServer/applicationInitialization,其他配置如紅圈中,如下圖所示:

在集合中添加一個初始化請求地址(用於IIS初始化默認請求地址),添加完成後,點擊配置界面右側的應用按鈕,並重啓應用程序池和網站,如下圖所示:

 

總結:

1、原理說明:IIS應用初始化會在網站第一次創建後或者對應網站的應用程序池回收後,自動開啓新程序池,並啓動網站初始化,模擬一次正常請求,使網站一直處於在線狀態。

(此流程可以藉助第三方工具或者服務模擬網站請求達到相同目的)

2、配置說明:

 (1)、啓用應用程序池(AlwaysRunning):保證應用程序池在第一次創建或者被回收後,能自動再次重啓運行。

 (2)、啓用網站程序預加載(true):保證程序池在啓動過後,網站能響應預加載動作。

 (3)、配置網站默認預加載路徑:保證程序在程序池啓動後,網站預加載過程中,能快速編譯程序並進駐內存,保證請求快速響應。  

轉載地址:https://jingyan.baidu.com/article/c843ea0bb6c13877931e4a2e.html

 

Asp.net Mvc站點部署在IIS上後,第一個用戶第一次訪問站點,都會比較慢,確切的說是訪問站點的Action頁面(即非靜態頁面,因爲靜態頁面直接由IIS處理返回給用戶即完成請求,而Action頁面IIS要轉交給Aspnet_Wp工作進程,進而涉及相關初始化操作,這些初始化操作是比較慢的。第二次訪問站點就不需要再初始化了所以就快了)。

 這種第一次訪問慢的問題不僅發生在網站第一次部署啓動,也發生在站點重啓站點程序池回收(經測試,第一次部署啓動初始化所用時間會多一些,然後是站點重啓,然後是站點回收)。

 

1.站點重啓包含手動重啓和修改web.config配置、修改IIS上站點配置、更新站點bin目錄的dll等引起的自動重啓。如果你的站點是新上線的web或者會持續修改添加功能的web,那難免會更新dll導致重啓。其它編譯型語言(比如java)也是如此,更新了服務端組件,都難免要重啓站點。這邊會分享.net環境下如何優化此問題;

2.站點程序池回收是IIS建議的,本來默認是29小時回收一次。爲什麼要建議回收呢,大致可以這樣理解:一個每日定時回收的機制就像是在發生輕微內存泄露或者其它拖累Worker進程的因素的情況下,刷新IIS的良藥,站點回收即節省了資源又提高了穩定性。然而,自動回收後第一次訪問慢的問題困擾了許多人,其實只要稍微設置就可以解決,即沒有困擾也擁有了回收的優點。

 

問題解決:

1.先在IIS上設置相應應用程序池的“高級設置”(IIS版本要在8或8以上,要知道IIS10早已出來了,如果你在用IIS很低的版本,然後在報怨IIS,我...),如下圖,這樣設置後,回收只會發生在凌晨04:00:00

 

要確定有安裝IIS應用程序初始化功能,如下圖

 

2.在IIS上設置站點的“高級設置”,把【預加載已啓用】設置爲true。

設置完這兩步,當站點(自動)回收時,訪問站點也是秒開不受任何影響,它的原理是在回收時會保持站點持續運行,這樣的回收可以理解爲把舊的Worker內容平滑的移到新的Worker上,然後回收掉舊的Worker。但是要注意,回收會導致站點內存信息丟失,因此如果你的設計是把session放在內存,則就要設置永不自動回收,那只要在第1步的基礎上把【特定時間】清空即可。不過我個人會建議你不要設計session放內存,你更新個dll導致站點重啓,內存也是清空的,你不如把session放在memcache/redis中,如果你的系統還沒用上這些,那你就用cookie代替session吧,cookie更靈活適用的場景也更多。

 

現在回收的問題完美解決了,接下來說說站點重啓。站點重啓肯定是要重新加載配置重新加載dll(不想重新加載dll的,看文章最後一段),初始化是免不了,默認重啓後第一個用戶第一次訪問站點會觸發初始化,那麼我們可以在站點啓動/重啓時,系統自動發一個站點請求,讓系統自己嚐嚐第一次訪問慢的問題。

IIS站點啓動時機自動請求站點

 1.啓動站點時觸發的時機

創建一個類,繼承自IProcessHostPreloadClient接口,其Preload方法就是啓動站點時觸發。然後在裏面自動訪問站點,如下代碼:

複製代碼

   public class ApplicationPreload : System.Web.Hosting.IProcessHostPreloadClient
    {
        public void Preload(string[] parameters)
        {         
            try
            {
                //自動請求的url,其中http://localhost:8001 最好配置在config中,這邊只是演示。
                string url = "http://localhost:8001/home2/about";
                using (var webClient = new WebClient())
                {
                    webClient.DownloadStringAsync(new Uri(url));//要異步請求
                }
            }
            catch (Exception e)
            {
                MvcApplication.DoLogToTxt("Preload Error:" + e.Message);
            }
        }
    }

複製代碼

 

2. 修改IIS配置文件,讓IIS能識別到剛寫的ApplicationPreload類

打開IIS配置文件:%WINDIR%\System32\inetsrv\config\applicationHost.config 

複製代碼

<applicationPools>
    <add name="MyAppWorkerProcess" managedRuntimeVersion="v4.0" startMode="AlwaysRunning" /> <!-- 上面我們在IIS程序池界面中有設置過startMode項爲AlwaysRunning-->
</applicationPools>

<!-- ... -->

<sites>
    <site name="MySite" id="1">
        <application path="/" serviceAutoStartEnabled="true" serviceAutoStartProvider="ApplicationPreload" />
    </site>
</sites>

<serviceAutoStartProviders>
    <add name="ApplicationPreload" type="WebApplication1.ApplicationPreload, WebApplication1" />
</serviceAutoStartProviders>

複製代碼

最後一個條目的type,其中WebApplication1.ApplicationPreload是應用程序中實現IProcessHostPreloadClient接口的類的全名,WebApplication1是程序集名稱。 

設置完這兩步也就搞定了啓動站點時自動訪問站點。 

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