Беспроблемное развертывание в ASP.NET (IIS убивает рабочий процесс до того, как новый рабочий процесс будет готов)
Я пытаюсь развернуть веб-приложение.NET в IIS (7.5) без каких-либо хлопот для пользователей. Я удостоверился, что Disable Overlapped Recycle имеет значение False, но я все еще сталкиваюсь с той же проблемой каждый раз.
Каждый раз, когда я загружаю новые двоичные файлы для сайта, IIS убивает рабочий процесс, прежде чем он запустил новый. Поэтому каждый раз, когда я загружаю новые двоичные файлы, пользователи получают следующее сообщение об ошибке:
Ошибка сервера в приложении '/' Не удалось загрузить файл или сборку "MyApplicationWeb" или одну из ее зависимостей. Процесс не может получить доступ к файлу, потому что он используется другим процессом. (Исключение из HRESULT: 0x80070020)
Я понятия не имею, как сделать это без проблем. Как сейчас, я просто загружаю двоичный файл; но в то время как загрузка происходит (или локальная копия), это даст вышеупомянутое поведение. Я также пытался использовать веб-сад, но с тем же результатом.
Что я не ищу:
- Как решить эту проблему с помощью внешних балансировщиков нагрузки (это функциональное решение, но оно является плохим решением для нескольких серверов и не будет работать вообще, если будет только один сервер)
- Как создать обходной путь с обновлением на пользовательской странице ошибки (поскольку у нее есть некоторые очевидные проблемы, но что более важно, она вообще не будет работать с веб-сервисами /ajax).
Я действительно думаю, что это должно быть выполнимо, учитывая http://www.microsoft.com/technet/prodtechnol/WindowsServer2003/Library/IIS/24e3c22e-79a9-4f07-a407-dbd0e7f35432.mspx?mfr=true
Обновление: в статье выше они говорят:
Тем не менее, поскольку значение времени ожидания для завершения работы или завершения работы настраивается, рабочий процесс можно прервать, пока он еще обрабатывает запросы, если он не завершает обслуживание существующих запросов в течение определенного периода времени.
Я понятия не имею, где найти это значение, ни то, что это по умолчанию. Если его меньше, чем несколько секунд, это может объяснить мои результаты.
пс. Я публикую это на SO, а не на SF/Webmasters и т. Д., Потому что я думаю, что такого рода знания, вероятно, будут минимальными среди людей, которые не занимаются разработкой, я надеюсь, что все в порядке.
5 ответов
При развертывании приложений ASP.Net я создаю новую папку на сервере и изменяю домашний каталог веб-сайта в IIS. Это обеспечивает нулевое время простоя развертывания и быструю позицию отката в случае непредвиденных проблем. В будущем обновлении я удаляю старую версию и повторяю процесс, чтобы всегда была единственная позиция отката.
Обновление - ограничение по времени выключения
Подробные сведения о настройке ограничения времени выключения для рабочих подробно описаны по адресу http://www.iis.net/ConfigReference/system.applicationHost/applicationPools/add/processModel. По умолчанию это 1 мин 30 сек. Ищите раздел shutdownTimeLimit на связанной странице.
Обновление - Больше информации
Подобный вопрос с отличным ответом
Суть этого заключается в том, что из-за перезаписи существующих файлов механизм копирования берет на себя исключительную блокировку файлов и что невозможно осуществить безразличное развертывание без использования app_offline.htm или механизма, такого как предложенный выше. Прочитайте связанный ответ, поскольку он углубляется в тему.
Я согласен с ответом Смиркина - обновив вторую папку и изменив домашний каталог IIS, чтобы он указывал на другую папку. Еще одним преимуществом этого является то, что у вас есть простой путь отката (просто переключите домашний каталог IIS обратно).
Я написал сообщение со сценарием о том, как сделать это с помощью Powershell - надеюсь, это поможет: http://davidduffett.net/post/4833657659/blue-green-deployment-to-iis-with-powershell
Вы должны иметь возможность использовать этот скрипт непосредственно из вашей системы непрерывной интеграции.
Хотя ответ Смиркина предоставляет администратору хороший способ развернуть сайт практически без простоев, он должен решить вашу проблему с отсутствующими сборками / ссылками, если у вас есть критические изменения в вашей кодовой базе (т.е. удаление старых страниц, изменения в форм и т. д.), тогда использование этого метода может привести к некоторым "хлопотам" для всех пользователей, которые запускают процесс до переключения и завершают его после переключения (т. е. запрашивают страницу перед переключением, начинают заполнять ее). и затем отправьте страницу после перехода в новый каталог).
Я знаю, что вы не хотите, чтобы я это говорил, но без балансировщика нагрузки с включенными Sticky-Sessions вы не сможете позволить людям продолжать использовать старую версию сайта, пока они не закончили работать с новой сеансы новой версии - изменяя домашний каталог приложения, IIS выполнит перекомпиляцию приложения и перезапустит процессы. Таким образом, вы можете настроить старый сервер так, чтобы он продолжал обслуживать текущие соединения, но при этом указать баланс нагрузки, чтобы он не отправлял на него никаких новых соединений.
Однако есть еще один шаг, который вы можете предпринять, чтобы помочь смягчить проблемы, часто встречающиеся вокруг этого:
Настройте MachineKey как постоянное значение, а неAutoGenerate
- это означает, что при перезапуске AppPool он будет использовать тот же ключ и сможет дешифровать сеансовые куки, viewstate и т. д.
Я предполагаю, что у вас есть антивирусный сканер или какой-то другой процесс индексации, который блокирует файл, как только вы копируете его туда.
Вы могли бы использовать app_offline.htm
это решение не является бесшовным, но вы можете использовать
<meta http-equiv="refresh" content="5" />
в файле htm, поэтому браузер автоматически обновляет без какого-либо JavaScript.
ура