Оновлення веб-програми без простоїв


Відповіді:


44

Що ми, як правило, робимо на роботі:

  • перед оновленням коренем документа сервера є:
    • в /www/app-2009-09-01
    • але доступ до нього здійснюється через символічне посилання, що називається /www/application
  • ми ставимо цілу нову базу коду /www/app-2009-09-08
  • як тільки вся база коду з’явиться:
    • ми видаляємо старе символічне посилання
    • ми створюємо нове символічне посилання, яке все ще називається /www/application, але яке вказує на нові джерела:/www/app-2009-09-08
  • ми перезавантажуємо apache, щоб змусити модифікацію враховувати.

Весь цей процес виконується за допомогою автоматичного скрипту (єдина неавтоматична річ - це ми запускаємо його при необхідності). Це означає :

  • Все йде швидко (особливо перемикання символічного зв'язку, що є важливою частиною)
  • Немає ризику помилитися: сценарій добре перевірений і працює місяцями / роками


Ще одна перевага цього символічного попередження посилань полягає в тому, що дуже легко "відкатати" оновлення, якщо ми помітимо катастрофічну помилку лише після того, як випустимо нову версію джерел у виробництво: нам просто потрібно переключити символічні посилання назад.

Звичайно, це не заважає вам протестувати нову версію на вашому інсценірувальному сервері перед тим, як поставити її на виробництво - але, хто знає ... Іноді є справді велика помилка, яку ніхто не зміг побачити, поки тестування :-(
Наприклад, тому, що регулярно не проводиться тестування навантаження на постановочній машині.
(Я бачив, як "відкат" за 3 роки використовувався щось на зразок 4 або 5 разів - кожен раз, це врятував день - і веб-сайти ^^)


Ось якийсь короткий приклад: припустимо, у мене є цей VirtualHost у моїй конфігурації Apache:

<VirtualHost *>
        ServerName example.com
        DocumentRoot /www/application
        <Directory /www/application>
            # Whatever you might need here (this example is copy-pasted from a test server and test application ^^ )
            Options Indexes FollowSymLinks MultiViews +SymLinksIfOwnerMatch
            AllowOverride All
            php_value   error_reporting 6135
            php_value short_open_tag  on
        </Directory>
</VirtualHost>

Досить "стандартний" ... Єдине, що це /www/applicationне справжній каталог: це лише символічне посилання на поточну версію джерел.
Що означає, що коли ви поставили джерела на сервер, але ще не переключились, у вас вийде щось подібне:

root@shark:/www
# ll
total 8
drwxr-xr-x 2 root root 4096 2009-09-08 22:07 app-2009-09-01
drwxr-xr-x 2 root root 4096 2009-09-08 22:07 app-2009-09-08
lrwxrwxrwx 1 root root   19 2009-09-08 22:08 application -> /www/app-2009-09-01

Зауважте, що символіка вказує на "стару версію"

Тепер, коли нова версія була повністю завантажена на сервер, перейдемо до:

root@shark:/www
# rm /www/application
root@shark:/www
# ln -s /www/app-2009-09-08 /www/application

І тепер, /www/applicationвказує на нову версію джерел:

root@shark:/www
# ll
total 8
drwxr-xr-x 2 root root 4096 2009-09-08 22:07 app-2009-09-01
drwxr-xr-x 2 root root 4096 2009-09-08 22:07 app-2009-09-08
lrwxrwxrwx 1 root root   19 2009-09-08 22:09 application -> /www/app-2009-09-08

І нам просто потрібно перезапустити Apache:

root@shark:/www
# /etc/init.d/apache2 restart
 * Restarting web server apache2

Три кроки " видалити посилання; створити нове посилання; перезапустити апаш " слід зробити швидко; тобто автоматизованим сценарієм, а не людиною.

Використовуючи це рішення:

  • ви можете зайняти стільки часу, скільки потрібно для завантаження нової версії джерел: apache не буде використовувати їх до тих пір, поки символи не змінені
  • коли все в порядку, просто перемкніть симпосилання: воно піде швидше, ніж зміна навіть 1 або 2 файлів ... Це означає, що практично немає простоїв :-)

І якщо використовувати якийсь кеш-код опкоду, як APC, з параметром stat на 0, то, мабуть, це може означати ще менший ризик простою.


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


Сподіваюсь, це зрозуміліше :-)


Це теж своєрідний обмін сервером. :-)
Wim ten Brink

mod_rewrite для управління символічними посиланнями?

@gAMBOOKa: ні: лише питання документа DocumentRoot (або VirtualHost DocumentRoot) Apache, що є / www / application ;; тобто символічне посилання - незалежно від того, куди це вказує.

2
Страхітлива відповідь. Ще одна порада: ви можете змусити символічне посилання відбуватися, не скасовуючи його. Як цитується: "Три кроки ... слід зробити швидко; тобто за допомогою автоматизованого сценарію, а не від людини". Команда mv є атомною операцією, тому ви можете створити символьне посилання на зразок 'ln -s / www / app-2011-01-28 / www / application-temp', а потім зробити 'mv -T / www / application-temp / www / додаток '.

1
Існує щось, що не було охоплено методом symlink. Ваш спосіб працює з Apache + mod_php, але він може вийти з ладу на lighttpd + fastcgi. На веб-сайті з високим трафіком запит подаватиметься посеред заміни посилання, що залежність від php-коду не вдасться у змішаній версії.
Денніс С

2

Ви не можете взяти існуючий код та перенести проект в окремий тестовий php-файл та використовувати його під час оновлення? Я маю на увазі те, що у вас повинен бути тестовий сервер і виробничий сервер, щоб, коли вам доведеться робити оновлення, у вас не виникало простоїв.


1

Налаштуйте другий сервер із оновленою базою коду та переключіть їх якомога швидше. :-)

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


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

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

1
Це в списку ToDo, але це довгострокова мета. Ми молодий стартап, тому організація в команді розробників, звичайно, потребує певного часу. = D

1

По-перше, я часто використовую і люблю метод, подібний до відповіді Паскаля МАРТІНА.

Ще один метод, який мені також подобається, - це використовувати мій SCM для просування нового коду. Точний процес залежить від вашого типу SCM (git vs svn vs ...). Якщо ви використовуєте svn, я люблю створювати гілку "в Інтернеті" або "Виробництво", яку я оформлюю як корінь документа на сервері. Потім, коли я хочу висунути новий код з іншої гілки / тегу / магістралі, я просто фіксую новий код у "онлайн" гілці та запускаю оновлення svn у корені документа. Це дозволяє зробити дуже легкі відкази, оскільки існує повний журнал ревізій того, що відбулося вгору / вниз на сервері та хто це робив і коли. Ви також можете легко запустити цю "гілку" в тесті, щоб перевірити додаток, яке ви збираєтеся натиснути.

Процес схожий на git та інші стилі SCM, щойно модифікований, щоб бути більш природним для їх стилю роботи.

Хочете отримати / опитувати замість того, щоб натискати оновлення? Просто маєте роботу з cron або іншим, розумнішим механізмом, автоматично запускайте оновлення svn.

Додатково: Ви також можете використовувати цей процес для резервного копіювання файлів, які ваша програма записала на диск. Просто створіть роботу cron або якийсь інший механізм запустити svn commit. Тепер файли, створені вашою програмою, резервні копії у вашому SCM, ревізійна реєстрація тощо (наприклад, якщо користувач оновлює файл на диску, але хоче відновити його, просто натисніть стару версію).


0

Я використовую подібний підхід і до Паскаля МАРТІНА. Але замість завантаження декількох версій мого додатка на виробничий сервер, я зберігаю "збірки" позаду свого брандмауера, кожна в окремому каталозі з номером збірки та датою. Коли я хочу завантажити нову версію, я використовую простий скрипт, який включає "rsync -avh --delay-updates". Прапор "затримка = оновлення" буде завантажувати все (що відрізняється) у тимчасову папку до тих пір, поки всі оновлення не знайдуться, а потім перенести все одразу в кінці передачі на правильні шляхи, щоб додаток ніколи не знаходився в пів-старий-напів-новий стан. Це має такий же ефект, як і метод, описаний вище, за винятком того, що я зберігаю лише одну версію програми на виробничому майданчику (найкраще мати лише голі необхідні файли на виробничому сервері, IMO).

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