2017-02-20 146 views
1

正如其他各種相關問題中所述,我還期待在重新部署帶有相當大EF6模型的Web角色以及大量參考的nuget之後首次調用持續(30秒) -packages。在嘗試使用preloadEnabledserviceAutoStartProviders的不同建議解決方案後,我仍然很滿意並決定重新開放此主題,希望有人在此期間找到更好的解決方案。部署後Az​​ure Web角色預熱

對於我來說,主要目標是在角色在新部署中退出忙碌狀態並可通過負載平衡器和外部客戶端訪問時,使Web角色以接近後續調用的速度迴應第一個請求。不幸的是我經歷了以下問題,目前提出的解決方案:

  1. preloadEnabled

    • 我通過PKGMGR.EXE /iu:IIS-ApplicationInit在啓動任務添加應用程序初始化模塊。到現在爲止還挺好。
    • 當我然後嘗試執行%windir%\system32\inetsrv\appcmd set site "MySiteName" -applicationDefaults.preloadEnabled:true時,它在執行啓動腳本時失敗,在全新部署中仍然沒有在IIS中創建網站。
    • 如果我嘗試通過我的Application_Start方法中的ServerManager -class設置preloadEnabled設置,我不明白,在對web角色進行第一次外部調用之前如何執行此代碼作爲preloadEnabled設置在新的web角色部署後默認爲false,因此我理解的Application_Start方法沒有機會被Application Initialization模塊執行?
  2. serviceAutostartProviders

    • 這裏我們需要把我們的實施中對ApplicationHost.config的IProcessHostPreloadClient接口通過使用APPCMD腳本或ServerManager的類,即AutostartProvider的名字,但:
      • serviceAutostartProvider就像preloadEnabled一個網站相關的設置,所以我們在這裏有1.237中的%windir%\system32\inetsrv\appcmd set site "MySiteName" -applicationDefaults.preloadEnabled:true相同的問題 - 在全新部署後的啓動腳本執行時,網站沒有t尚未在IIS中創建並且腳本無法正常執行
      • 另一種可能性是將applicationhost.config包含到部署包中,但我沒有找到任何解決方案來爲Web角色執行此操作。

那麼怎麼你們管理,以確保,即預加載組件和一些初始化代碼(如填充內存高速緩存)被之前運行作用得到它的第一次從外線命中?

我們現在開始獲得一些流量並獲得約。我們的WebApi上每秒發出1-2個請求,因此,每次更新部署之後,客戶端預加載「可見」的時間延遲30秒,現在已成爲主要問題。

我們在低流量時間調度更新部署,但如果我需要進行緊急修補程序部署,該怎麼辦?

回答

1

也許最好的方法是使用部署插槽。首先將更新部署到臨時插槽。在從一個臨時插槽切換到一個生產插槽之前,Kudu將通過一個請求打開臨時插槽的根部,以預熱該應用程序。在對分段插槽的根的請求返回之後,IP交換機發生並且您的插槽被交換。

但是,有時您需要預熱其他頁面或服務才能使應用程序準備好處理流量,並且用熱身請求打擊根目錄是不夠的。您可以更新您的web.config,以便Kudu在IP交換機發生並且交換插槽之前將命中額外的頁面和端點。

這些預熱請求URL應該在標籤中。這裏有一個例子:

<?xml version="1.0" encoding="utf-8"?> 
<configuration> 
    <system.webServer> 
    <applicationInitialization> 
     <add initializationPage="/pagetowarmup1" /> 
     <add initializationPage="/pagetowarmup2" /> 
     <add initializationPage="/pagetowarmup3" /> 
    </applicationInitialization> 
    </system.webServer> 
</configuration> 

你可以在這個問題上here讀庫杜文檔。

+0

謝謝熱身實例的代碼。但您的解決方案是否也適用於Web角色?據我所知,它只是一個Azure Web Apps的功能? – maxyha

0

好的。現在我懂了。

的點是設置preloadEnabled -property不內側Global.asax中Application_Start方法(因爲它不會在第一請求中的作用無論如何之前被擊中)的,但內部RoleEntryPoint.OnStart

不同之處在於在部署包之後直接調用RoleEntryPoint.OnStart並且所有設置都是爲了啓動角色。此時,Azure實例仍處於繁忙狀態,並且只要RoleEntryPoint.OnStart中的某些代碼正在執行,尚未從外部獲得。

因此,這裏是我想出了迄今爲它獲得了第一次調用之前從外部

public class WebRole : RoleEntryPoint 
{ 
    public override bool OnStart() 
    { 
     // set preloadEnabled of each Site in this deployment to true 
     using (var serverManager = new ServerManager()) 
     { 
      foreach (var mainSite in serverManager.Sites) 
      { 
       var mainApplication = mainSite.Applications["/"]; 
       mainApplication["preloadEnabled"] = true; 
      } 
      serverManager.CommitChanges(); 
     } 

     // call my warmup-code which will preload caches and do some other time consuming preparation 
     var localuri = new Uri(string.Format("https://{0}/api/warmup", RoleEnvironment.CurrentRoleInstance.InstanceEndpoints["Endpoint1"].IPEndpoint)); 
     try 
     { 
      var request = (HttpWebRequest)WebRequest.Create(localuri); 
      request.Method = "GET"; 
      var response = request.GetResponse(); 
     } 
     catch { } 

     // send this thread to sleep in order to give the warmup-request a chance to complete BEFORE the Role will get started 
     // and becomes available to the outside world 
     System.Threading.Thread.Sleep(60000); 


     return base.OnStart(); 
    } 


} 
+0

在這種情況下,您正在創建的WebRequest由完全IIS創建的HttpApplication處理,而不是由執行熱身代碼的相同進程處理,對嗎? – NStuke