Обновление сайта .NET без перезагрузки

13

Я использовал для разработки веб - сайтов в PHPи , ASP classicи если что - то нужно изменить. Вы можете просто изменить один / несколько файлов, и никто не заметит. Возможно, если кто-то запросит измененный файл во время загрузки, но это всего лишь полсекунды. Для большинства небольших сайтов это не проблема.

Но последние сайты создаются с C# MVCучетом изменений, и когда вы вносите изменения в код, вам необходимо перестроить свой веб-сайт и загрузить измененные DLLфайлы. Но когда вы измените свои DLLфайлы, он перезагрузит ваш сайт и сбросит все активные sessions. Он также должен перезагрузить все, а на больших сайтах загрузка может занять несколько минут. Все, кто просматривал сайт, заметят это и должны снова войти в систему.

Основные обновления сайта не так часто, так что это не проблема. Но у нас есть регулярные «небольшие» обновления для рекламных акций. Например, «Заполните эту форму и получите бесплатное членство в течение трех месяцев» или «Первые 10, кто загрузит изображение ... получит цену». Я думаю, что вы получите дрейф. Некоторые рекламные акции похожи и могут обрабатываться с помощью модуля, который показывает правильную информацию в зависимости от настроек, но довольно часто это требует специального кода.

Я думал о системе , в которой каждое продвижение является его собственный DLLфайл на основе интерфейса, а затем загрузите DLLдинамически , используя Type.GetType, Activator.CreateInstanceи InvokeMember. Хотя это может сработать, мне интересно, если это правильный путь.

Поэтому мой вопрос: как вы обновляете .NETсайт на лету, не перезагружая весь сайт и не сбрасывая сеанс (например, перезапуск пула приложений).

Хьюго Делсинг
источник
В ответ на ваш комментарий о вознаграждении: большие веб-сайты, над которыми я работаю, обрабатывают небольшие изменения в коде так же, как они обрабатывают большие изменения в коде: с помощью балансировщиков нагрузки и вне сеансов процесса - потому что весь код, развернутый для работы в реальном времени, должен пройти процесс проверки / подписки, и мы не можем просто удалить код на серверах. Я думаю, что наши определения «большой» могут не совпадать;)
Жаф - Бен Дугид

Ответы:

11

Изучите «Инициализация приложения» IIS 7.5, Windows 2008 R2 (сложнее в настройке) IIS 8, Windows 2012

Инициализация приложения позволяет любому приложению (пул приложений, а не сайт) перезапускаться, чтобы перекрываться и использовать старое, продолжая работать предыдущее приложение при прогреве запуска нового приложения. После запуска нового приложения (определяется URL-адресами, которые вы можете установить) оно начнет использовать новое приложение и завершит работу предыдущего. Использование инициализации приложения в сочетании с методами, обеспечивающими сохранение сеанса при перезапусках пула приложений, может обеспечить беспроблемную перезагрузку сайта. (У Zhaph есть хорошее примечание о ключе машины.)

В дополнение к вышеприведенным ссылкам для настройки инициализации приложения вы захотите посмотреть, что вызывает перезапуск сайта - поскольку при перезапуске сайта не используется инициализация приложения, перезапуск сайта не будет проходить без проблем.

Вы можете настроить IIS таким образом, чтобы обновление DLL не вызывало немедленного перезапуска сайта или изменений в файле web.config (высокие значения ChangeNotification в файлах httpRuntime и внешних файлах конфигурации в зависимости от вашего сайта).

В результате вы можете обновить DLL / код без перезапуска сайта, а затем принудительно перезапустить приложение, которое будет использовать фоновый прогон AppInitialization для плавного изменения кода.

Выполнение этих вещей в концерте работает довольно хорошо для бесшовных перезапусков.

jeffreypriebe
источник
Хороший набор шагов там - конечно, кое-что, чтобы рассмотреть :)
Zhaph - Бен Duguid
Это похоже на то, что я искал. Собираюсь попробовать и настроить. Спасибо
Хьюго Делсинг
@HugoDelsing Надеюсь, это отлично сработает.
Jeffreypriebe
Спасибо, это то, что я в конечном итоге использовал, и это прекрасно работает.
Хьюго Делсинг
@HugoDelsing Рад слышать, что это сработало и для вас.
Jeffreypriebe
5

Есть несколько способов справиться с тем, что вы просите, и несколько разных аспектов вашего вопроса:

Обрабатывать небольшие обновления для рекламных акций

Что вам действительно нужно, так это система управления контентом или аналогичная, которая позволяет редактировать контент на лету (например, Wordpress / Drupal или с точки зрения .NET N2 CMS, Umbraco, Orchard и т. Д.), Однако есть некоторые вещи, которые вы могли бы попробовать, если вы не пошли по этому пути.

Поскольку ASP.NET действительно перезагружается, только если вы касаетесь файлов определенных типов (в основном, web.config (s), содержимого папок /bin/и /app_code/) и имеет настраиваемое ограничение для «других изменений файла» (в основном, после того, как вы изменили во многих файлах на вашем сайте пул приложений будет перезапущен - NumRecompilesBeforeAppRestart) вы можете посмотреть что-то, где вы проверяете другую папку на наличие статических (то есть .html) файлов, которые вы извлекаете и отображаете по мере необходимости, или используете LoadControlметод, который принимает строковый путь к .ascxуправления пользователя и динамически загружает его - как вы определяете для показа другой вопрос больше подходит для StackOverflow - однако я рекомендовал бы решение на основе именования конвенции.

Вы также можете использовать что-то вроде платформы Managed Extensibility Framework (MEF - которая была полной частью .NET Framework начиная с версии 4), которая позволяет вам писать архитектуру на основе плагинов и указывать папку за пределами вашего /bin/каталога для мониторинга. новые .DLLs - хотя я не пробовал этого, чтобы увидеть, удастся ли избежать проблемы с перезапуском приложения, я использовал это для хорошего эффекта в веб-среде для добавления общих функций на сайт.

Если это не подходит, единственная другая опция, о которой я могу подумать, это добавить элементы управления как «код впереди», как мы это делали в классическом ASP - то есть с <script runat="server">блоком вместо скомпилированного класса «код позади» который содержит логику для запуска управления - это устранит необходимость в изменении DLL, за счет некоторой потери производительности первого времени , как элемент управления составлен на лету - опять вам нужно , чтобы сбалансировать это с NumRecompilesBeforeAppRestartесли вы Вы делаете много маленьких изменений.

Как сохранить сеансы при перезапуске приложения?

Возможно, этот вопрос легче решить и включает три ключевых шага:

  1. Сконфигурируйте MachineKey (IIS7, но по-прежнему имеет значение 8), чтобы он был постоянным значением, а не AutoGenerate- это означает, что при перезапуске AppPool он будет использовать тот же ключ и, таким образом, сможет дешифровать куки сеанса, представление состояния и т. Д. До переработка.
  2. Либо настройте сервер состояний, либо настройте базу данных для хранения состояния сеанса .
  3. Переключитесь с использования InProcна StateServerили SQLServerв элементе SessionState в вашем web.config.

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

Тем не менее, если вы находитесь в положении, в котором «перезапуск приложения после развертывания занимает« несколько минут », вы можете рассмотреть возможность перехода в среду с балансировкой нагрузки или, по крайней мере, горячую замену« Staging / Live ». (например, предоставляемый Azure / AWS / и т. д.) - таким образом вы можете отключить сервер во время его обновления или подготовить его с новым кодом, а затем заменить его - при условии, что вы предприняли шаги для решения проблемы общего доступа сеансы (см. выше), это будет работать нормально, без последствий для ваших пользователей.

Жаф - Бен Дугид
источник
Спасибо за ваш длинный ответ. К сожалению, CMSне то, что я хочу. Я не хочу изменять контент, я хочу изменить код. Часть о сессиях была только примером. Его изменение не решит проблему неактивности сайта в течение минуты или двух при перезагрузке DLLфайлов. Эта MEFчасть была интересной, но это решение сторонней системы, о котором я думал. Так что +1 за усилия, но, к сожалению, это не совсем ответ на мой вопрос.
Хьюго Делсинг
1
Я обновил свой ответ, чтобы устранить некоторые из этих моментов: MEF был выпущен MS и является полной частью .NET Framework начиная с v4. Вы можете попытаться использовать код впереди для своих новых элементов управления, в качестве альтернативы принять настройку с балансировкой нагрузки / промежуточной работой, которая позволила бы запустить сервер и запустить его, а затем заменить его.
Zhaph - Бен Дугид
1
Я обрисовал альтернативное решение, использующее инициализацию приложения. Преимущество заключается в том, что весь код и настройка сервера «нормальны» без специальных средств балансировки нагрузки или динамической загрузки, что упрощает вашу рабочую среду. Конечно, установка балансировки нагрузки / промежуточной работы может быть полезна по другим причинам.
Джеффриприб