2017-02-20 8 views
1

Как описано в различных других связанных с этим вопросах, я также ожидаю длительного (30 секунд) первого вызова после (повторного) развертывания веб-роли с довольно большой моделью EF6 и большим количеством ссылочных nuget -packages. Пробовав различные предлагаемые решения с preloadEnabled и serviceAutoStartProviders, я все еще согласен и решил вновь открыть эту тему в надежде, что кто-то натолкнулся на лучшее решение тем временем.Azure Web Role warm up после Deploy

Основная цель для меня состоит в том, чтобы сделать веб-роль, отвечающую первому запросу, почти так же быстро, как последующие вызовы, как только эта роль перестанет работать в новом состоянии и получит доступ к балансировщику нагрузки и внешним клиентам. К сожалению, я испытал следующие проблемы с предлагаемыми решениями до сих пор:

  1. preloadEnabled:

    • я добавить модуль инициализации приложений с помощью PKGMGR.EXE /iu:IIS-ApplicationInit в задаче запуска. Все идет нормально.
    • Когда я попытаюсь выполнить %windir%\system32\inetsrv\appcmd set site "MySiteName" -applicationDefaults.preloadEnabled:true, это не сработает, так как на момент запуска сценария запуска все еще нет сайтов, созданных в IIS при новом развертывании.
    • Если я пытаюсь установить параметр preloadEnabled через ServerManager -класс в моем методе Application_Start, я не могу понять, как этот код предназначен для выполнения перед первым внешним вызовом веб-роли, поскольку параметр preloadEnabled по умолчанию установлено значение false после развертывания новой веб-роли и, таким образом, метод Application_Start в моем понимании не может быть запущен модулем инициализации приложения?
  2. serviceAutostartProviders:

    • здесь мы должны поставить имя нашего AutostartProvider реализующего интерфейс IProcessHostPreloadClient в ApplicationHost.config т.е. либо с помощью Appcmd сценария или класс ServerManager, НО:
      • serviceAutostartProvider похож на preloadEnabled параметр, связанный с сайтом, поэтому мы имеем такую ​​же проблему здесь, как и с %windir%\system32\inetsrv\appcmd set site "MySiteName" -applicationDefaults.preloadEnabled:true в 1.2 - во время запуска сценария запуска после нового развертывания веб-сайты не являются t, все еще созданный в IIS, и скрипт не выполняется должным образом
      • Другой возможностью было бы включить applicationhost.config в пакет развертывания, но я не нашел решения для этого для веб-роли.

Так как же вы, ребята, удалось обеспечить, чтобы загружать при сборе и некоторые код инициализации (например, заполнение кэш-память) запускается перед тем роль получает это первый удар из-за пределов?

Теперь мы начнем получать некоторый трафик и получаем ок. 1-2 запросов в секунду на нашем WebApi и, следовательно, 30-секундная задержка для предварительной загрузки «видимых» клиентов после того, как каждое развертывание обновлений становится серьезной проблемой.

Мы планируем развертывание обновлений при низком времени трафика, но что делать, если мне нужно установить срочное исправление?

ответ

1

Возможно, лучший способ выполнить это - использовать слоты для развертывания.Сначала развертывайте обновления в своем промежуточном слоте. Прежде чем переключиться с промежуточного слота на производственный слот, Kudu попадет в корень промежуточного слота с запросом, чтобы разогреть приложение. После того, как запрос возвращается корневому слою промежуточного слота, произойдет переключение IP-коммутатора, и ваши слоты будут заменены.

Однако иногда вам необходимо разогреть другие страницы или службы, чтобы приложение было готово к работе с трафиком, а для запуска root-запроса недостаточно. Вы можете обновить свой 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

Спасибо. Но ваше решение с слотами также применимо к веб-ролям? Насколько я знаю, это особенность Azure Web Apps? – maxyha

0

OK. Теперь я понял.

Дело в том, чтобы установить preloadEnabled -property не внутри метода Application_Start в Global.asax (так как это не будет удар до первого запроса к роли так или иначе), но внутри 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 обрабатывается HttpApplication, созданным Full IIS, а не тем же процессом, выполняющим код разминки, правильно? – NStuke