Як розгорнути додаток ASP.NET з нульовим простоєм


127

Для розгортання нової версії нашого веб-сайту ми робимо наступне:

  1. Створіть новий код та завантажте його на сервер.
  2. На поточному сервері видаліть увесь код живого з каталогу веб-сайтів IIS.
  3. Витягніть новий код zipfile в тепер порожній каталог IIS

Цей процес все сценарій і відбувається досить швидко, але все ж може бути 10-20 секунд простою, коли старі файли видаляються, а нові файли розгортаються.

Будь-які пропозиції щодо методу простою 0 секунд?


Чи не повинно бути це на ServerFault?
Даніель Родрігес

49
Можливо, але ServerFault не існував у вересні08 року
Карл Гленнон

3
Чи може IIS вказувати на папку symlink? Чи змінить симпосилання спричинить переробку IIS-процесу?
Ніл МакГуйган

будь-яке остаточне рішення з повним зразком сценарію вихідного коду?
Кікенет

Чи не можливо мати кілька пулів додатків і перемикати трафік з одного пулу додатків на інший?
Лука

Відповіді:


79

Вам потрібні 2 сервери та балансир навантаження. Ось в кроках:

  1. Увімкніть увесь трафік на сервері 2
  2. Розгортання на сервері 1
  3. Тестовий сервер 1
  4. Увімкніть увесь трафік на сервері 1
  5. Розгортання на сервері 2
  6. Тестовий сервер 2
  7. Поверніть трафік на обох серверах

Річ у тому, що навіть у цьому випадку у вас все ще будуть перезавантаження програми та втрата сеансів, якщо ви використовуєте "липкі сесії". Якщо у вас є сесії з базами даних або державний сервер, тоді все повинно бути добре.


4
Ви також можете налаштувати балансир завантаження, щоб він обслуговував існуючі сеанси для даного сервера, але не приймав нові. Це дозволяє уникнути відмови від сеансів. Однак ця методика вимагає дочекатися закінчення сеансів, і загалом ви захочете це сценарій.

35
Цей метод має тенденцію до падіння, коли кодовий перелік має структурні зміни в базі даних. Після оновлення БД для сервера 1 сервер 2 вибухне. Тепер ви можете створити резервну копію / відновити базу даних для тестування на сервері 1, але тоді у вас виникне проблема сортування даних, які змінювалися в прямій БД під час виконання паралельної копії.
EBarr

1
@AndreiRinea - як ви вважаєте, що це буде працювати в системі з високим обсягом OLTP? Або система не синхронізується, і ви втрачаєте дані, коли ви перетинаєте, або вам потрібно призупинити введення даних і написати сценарій для ідентифікації та переміщення перехідних даних до нової структури БД.
EBarr

9
@EBarr: і в будь-якому випадку технічно у вас все ще є нульовий час простою в додатку ASP.NET - питання не в тому, "як розгорнути на сервер sql db з нульовим простоєм".
Sklivvz

6
Їх головним є розробити таким чином, щоб ваші зміни в sql не були руйнівними. Вам часто доводиться робити будь-які руйнівні зміни sql у наступному випуску, як тільки він більше не використовується. З практикою це не важко.
Білер

60

Інструмент веб-розгортання Microsoft певною мірою підтримує це:

Вмикає підтримку транзакційної файлової системи Windows (TxF). Коли підтримка TxF включена, файлові операції є атомними; тобто вони або вдається, або повністю провалюються. Це забезпечує цілісність даних і запобігає існуванню даних або файлів у "напівповерховому" або пошкодженому стані. У MS Deploy TxF за умовчанням вимкнено.

Здається, транзакція призначена для всієї синхронізації. Також TxF є функцією Windows Server 2008, тому ця транзакційна функція не працюватиме з більш ранніми версіями.

Я вважаю, що можливо змінити ваш сценарій на час простою, використовуючи папки як версії та метабазу IIS:

  • для існуючого шляху / URL-адреси:
  • Скопіюйте новий (або модифікований) веб-сайт на сервер під
    • \ web \ app \ v2.1 \
  • Змініть метабазу IIS, щоб змінити шлях до веб-сайту
    • від \ web \ app \ 2.0 \
    • до \ web \ app \ v2.1 \

Цей метод пропонує наступні переваги:

  • Якщо нова версія має проблему, ви можете легко відкатати версію до версії 2.0
  • Для розгортання на декількох фізичних або віртуальних серверах ви можете використовувати свій сценарій для розгортання файлів. Після того, як всі сервери отримають нову версію, ви можете одночасно змінювати метабази всіх серверів, використовуючи інструмент веб-розгортання Microsoft.

5
Я реалізував цей підхід, адаптувавши наші сценарії розгортання повноважень. Частину сценарію, яка змінює папку сайту IIS, ви можете побачити тут: stackoverflow.com/questions/330608/… Дякую за покажчик.
Карл Гленнон

17
На жаль, цей метод не враховує структурних змін у БД. Після оновлення БД для v2.1 вибухне v.2.0.
EBarr

8
Використання TxF тут непосильне, IMO. Нічого не завадить мати одночасно і v2.0, і v2.1 у файловій системі. Велика зміна відбувається, коли v2.1 виходить в Інтернет, і до того часу транзакція TxF була здійснена. Нульовий час простою дійсно трапляється через те, як IIS переходить зі старого AppPool на новий, а не через TxF.
RickNZ

5
Інша проблема з цим полягає в тому, якщо велика кількість даних користувачів зберігається в папках папок додатків.
Кенні Евітт

4
Це не 0 секунд розгортання, оскільки новий додаток потрібно запустити.
usr

12

Ви можете домогтися розгортання нульового простою на одному сервері, використовуючи маршрутизацію запитів додатків в IIS як балансир завантаження програмного забезпечення між двома локальними веб-сайтами IIS в різних портах. Ця стратегія відома як синьо-зелена стратегія розгортання, де лише один із двох сайтів є доступним в балансирі навантаження в будь-який момент. Розгорніть на "знищеному" сайті, прогрійте його та введіть його в балансир завантаження (зазвичай, пройшовши перевірку стану заявки на запит про подання заявки), а потім вийдіть із "пулу" оригінальний веб-сайт, який був вгору зробивши його перевірку здоров'я).

Повний підручник можна знайти тут.


7

Я нещодавно пережив це, і рішення, до якого я придумав, було створити два сайти, створені в IIS, і переключитися між ними.

Для моєї конфігурації у мене був веб-каталог для кожного сайту A і B, наприклад: c: \ Intranet \ Live A \ Interface c: \ Intranet \ Live B \ Interface

У IIS у мене є два однакових сайти (однакові порти, аутентифікація тощо), кожен з яких має власний пул додатків. Один із сайтів працює (A), а інший зупиняється (B). також у прямому ефірі є заголовок живого хоста.

Якщо мова йде про розгортання в реальному часі, я просто публікую його на місці STOPPED. Оскільки я можу отримати доступ до сайту B за допомогою його порту, я можу попередньо розігріти його, щоб перший користувач не спричинив запуск програми. Потім за допомогою пакетного файлу я копіюю заголовок живого хоста в B, зупиняю A і запускаю B.


1
Це допомагає в простої через копію файлу, але має таку ж проблему, як і @Sklivvz - як тільки кодовий перелік має структурні зміни в базі даних, сайт починає бурхливо.
EBarr

Це здалося мені інтуїтивно зрозумілим, але чому не існує простого, вбудованого способу зробити це?
Петрус Терон

3
@Ebarr тоді не розгортайте руйнівні зміни sql. Наприклад, якщо вам потрібно видалити стовпчик, зробіть це в наступному випуску, коли він більше не використовується A або B.
Bealer

@Bealer - погоджено (із застереженням). Існує ціла серія цих питань щодо "простоїв під час кодових ролей". Мені ще потрібно знайти одну, яка б справді обговорювала реальність розвитку схеми БД. Caveat - є різноманітні ускладнення, які виникають разом із двофазними змінами схеми. Один із прикладів - безліч бармів ORM, якщо визначення таблиці відрізняється від визначення, яке воно розуміє (нові або відсутні колонки).
EBarr

2
@Rob Як можна "попередньо прогріти" сайт, якщо він зупинений?
Ендрю Джи

7

За допомогою класу ServerManager Microsoft.Web.Administration ви можете розробити власний агент розгортання.

Трюк полягає в зміні PhysicalPath VirtualDirectory, що призводить до атомного перемикання в Інтернеті між старими та новими веб-додатками.

Майте на увазі, що це може призвести до того, що старі та нові додатки виконуватимуться паралельно!

Проблема полягає в тому, як синхронізувати зміни до баз даних тощо.

Опитуючи існування AppDomains зі старими або новими PhysicalPaths, можна виявити, коли припиняються старі AppDomain (ів) і якщо запускаються нові AppDomain.

Щоб змусити запустити AppDomain, ви повинні зробити HTTP-запит (IIS 7.5 підтримує функцію автоматичного запуску)

Тепер вам потрібен спосіб блокувати запити на новий AppDomain. Я використовую іменований mutex - який створений та належить агенту розгортання, чекав Application_Start нового веб-додатка, а потім випускається агентом розгортання після того, як буде зроблено оновлення бази даних.

(Я використовую файл маркера у веб-додатку, щоб активувати функцію очікування mutex). Після запуску нового веб-додатка я видаляю файл маркера.


6

Добре, тому що всі хочуть відповісти, яку я написав ще в 2008 році * ...

Я розповім, як ми це робимо зараз у 2014 році. Ми вже не використовуємо веб-сайти, оскільки зараз ми використовуємо ASP.NET MVC.

Нам, звичайно, не потрібен балансир завантаження і два сервери для цього, це добре, якщо у вас є 3 сервери для кожного веб-сайту, який ви підтримуєте, але це загальний перевибір для більшості веб-сайтів.

Крім того, ми не покладаємось на останнього майстра від Microsoft - занадто повільне і занадто приховане магія і занадто схильне до зміни його імені.

Ось як ми це робимо:

  1. У нас є крок створення повідомлення, який копіює згенеровані DLL-файли у папку "bin-pub".

  2. Ми використовуємо програму Beyond Compare (яка є чудовою **) для перевірки та синхронізації змінених файлів (через FTP, оскільки це широко підтримується) аж до виробничого сервера

  3. На веб-сайті у нас є захищена URL-адреса, яка містить кнопку, яка копіює все, що знаходиться у «bin-pub», на «bin» (спочатку робимо резервну копію, щоб увімкнути швидкий відкат). У цей момент додаток перезавантажується. Тоді наша ORM перевіряє, чи є якісь таблиці чи стовпці, які потрібно додати та створює їх.

Це всього лише мілісекунд простою. Перезапуск програми може зайняти секунду або дві, але під час перезавантаження запити буферизовані, тому фактично просто нульовий час простою.

Весь процес розгортання займає від 5 секунд до 30 хвилин, залежно від того, скільки файлів змінено і скільки змін потрібно переглянути.

Таким чином, вам не потрібно копіювати весь веб-сайт у інший каталог, а лише папку бін. Ви також маєте повний контроль над процесом і точно знаєте, що змінюється.

** Ми завжди робимо очне яблуко змін, які ми впроваджуємо - як подвійна перевірка в останню хвилину, тому ми знаємо, що перевірити і чи готові щось зламати. Ми використовуємо програму "Більше порівняння", оскільки вона дозволяє легко відрізняти файли через FTP. Я б ніколи не робив цього без BC, ви не маєте поняття, що ви переписуєте.

* Прокрутіть донизу, щоб побачити це :( BTW я більше не рекомендую веб-сайти, оскільки вони повільніше будуватись і можуть погано працювати з половиною складених тимчасових файлів. Ми використовували їх у минулому, оскільки вони дозволяли більш спритний файл-за-файлом розгортання. Дуже швидко виправити незначну проблему, і ви зможете точно побачити, що ви розгортаєте (якщо ви, звичайно, використовуєте "Більше порівняння" - інакше забудьте це).


Але, ви все одно матимете простої, оскільки пул додатків переробляється.
testpattern

Ні, немає простоїв, оскільки запити автоматично завантажуються IIS під час перезавантаження програми
Майк Нелсон

5

Єдиний метод нульового простою, який я можу припустити, передбачає хостинг на щонайменше двох серверах.


1

Я хотів би трохи уточнити відповідь Джорджа для одного сервера:

  1. Використовуйте проект веб-розгортання, щоб попередньо скласти сайт в єдину DLL
  2. Створіть новий сайт та завантажте його на сервер
  3. Розпакуйте її в нову папку, розташовану в папці з правильними дозволами для сайту, тому розпаковані файли правильно успадковують дозволи (можливо, e: \ web, з папками v20090901, v20090916 тощо)
  4. Використовуйте IIS Manager для зміни назви папки, що містить сайт
  5. Зберігайте стару папку деякий час, щоб ви могли повернутися до неї у разі проблем

Етап 4 призведе до повторної переробки робочого процесу IIS.

Це просто нульовий час простою, якщо ви не використовуєте сеанси InProc; замість цього скористайтеся режимом SQL (ще краще, повністю уникайте стану сеансу).

Звичайно, це дещо більше, якщо є декілька серверів та / або змін у базі даних ....


1
Те саме питання, що і @Sklivvz - Цей метод випадає, як тільки кодовий рулон має структурні зміни в базі даних.
EBarr

3
Ось чому я сказав, що це більше стосується змін у БД ... Розгортання коду зі структурними змінами в БД - це не лише проблема розгортання; також має бути підтримка в коді, і, мабуть, і в БД.
RickNZ

1

Щоб розширити відповідь sklivvz, яка покладалася на те, що якийсь балансир завантаження (або просто резервна копія на одному сервері)

  1. Спрямуйте весь трафік на Сайт / сервер 2
  2. За бажанням зачекайте трохи, щоб гарантувати, що якомога менше користувачів має відкладені робочі процеси у розгорнутій версії
  3. Розгорніть на Site / Server 1 і максимально розігрійте його
  4. Виконувати міграції бази даних трансакційно (прагніть зробити це можливим)
  5. Негайно направляйте весь трафік на Сайт / Сервер 1
  6. Розгортання на сайті / сервері 2
  7. Прямий трафік на обидва сайти / сервери

Можна ввести трохи тестування димом, створивши знімок / копію бази даних, але це не завжди можливо.

Якщо можливо і потрібно, використовуйте "різниці маршрутів", такі як різні URL-адреси орендаря: s (customerX.myapp.net) або різні користувачі, щоб спочатку розгорнутись до групи невідомих морських свинок. Якщо нічого не виходить, відпустіть усіх.

Оскільки відбувається міграція баз даних, відкат до попередньої версії часто неможливий.

Існують способи зробити додатки грати приємніше в таких сценаріях, як-от використання черг подій та механізми відтворення, але оскільки ми говоримо про розгортання змін у тому, що використовується, насправді немає дурного способу підтвердження.


1

Ось як я це роблю:

Абсолютні мінімальні системні вимоги:
1 сервер з

  • 1 балансир завантаження / зворотний проксі (наприклад, nginx), що працює на порт 80
  • 2 ASP.NET-Core / моно-зворотний-проксі / fastcgi-chroot-jails або докер-контейнери, які прослуховують два різних порти TCP
    (або навіть лише два додатки з реверс-проксі на 2 різних портах TCP без жодної пісочної скриньки)

Робочий процес:

почати myupdate транзакції

try
    Web-Service: Tell all applications on all web-servers to go into primary read-only mode 
    Application switch to primary read-only mode, and responds 
    Web sockets begin notifying all clients 
    Wait for all applications to respond

    wait (custom short interval)

    Web-Service: Tell all applications on all web-servers to go into secondary read-only mode 
    Application switch to secondary read-only mode (data-entry fuse)
    Updatedb - secondary read-only mode (switches database to read-only)

    Web-Service: Create backup of database 
    Web-Service: Restore backup to new database
    Web-Service: Update new database with new schema 

    Deploy new application to apt-repository 
    (for windows, you will have to write your own custom deployment web-service)
    ssh into every machine in array_of_new_webapps
    run apt-get update
    then either 
    apt-get dist-upgrade
    OR
    apt-get install <packagename>
    OR 
    apt-get install --only-upgrade <packagename>
    depending on what you need
    -- This deploys the new application to all new chroots (or servers/VMs)

    Test: Test new application under test.domain.xxx
    -- everything that fails should throw an exception here
    commit myupdate;

    Web-Service: Tell all applications to send web-socket request to reload the pages to all clients at time x (+/- random number)
    @client: notify of reload and that this causes loss of unsafed data, with option to abort 

    @ time x:  Switch load balancer from array_of_old_webapps to array_of_new_webapps 
    Decomission/Recycle array_of_old_webapps, etc.

catch
        rollback myupdate 
        switch to read-write mode
        Web-Service: Tell all applications to send web-socket request to unblock read-only mode
end try 

-7

Я б запропонував зберегти старі файли там і просто перезаписати їх. Таким чином час простою обмежується часом перезапису однофайлів, і одночасно не вистачає лише одного файлу.

Не впевнений, що це допомагає у "веб-додатку", хоча (я думаю, ви говорите, що це ви використовуєте), саме тому ми завжди використовуємо "веб-сайти". Також при розгортанні "веб-сайтів" не перезапускається ваш сайт і не припиняються всі користувацькі сеанси.


Привіт Майку, можливо, ви захочете видалити цю відповідь.
Sohail Ahmed
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.