Это приложение PHP. Как я могу минимизировать время простоя при обновлении всей кодовой базы?
Это приложение PHP. Как я могу минимизировать время простоя при обновлении всей кодовой базы?
Ответы:
Что мы обычно делаем на работе:
/www/app-2009-09-01
/www/application
/www/app-2009-09-08
/www/application
, но которая указывает на новые источники:/www/app-2009-09-08
Весь этот процесс выполняется с помощью автоматического скрипта (единственная неавтоматическая вещь - мы запускаем его при необходимости). Это означает :
Другое преимущество этой условной ссылки состоит в том, что «откатить» обновление очень легко, если мы заметим катастрофическую ошибку только после запуска новой версии исходных кодов: нам просто нужно переключить символические ссылки обратно.
Конечно, это не мешает вам тестировать новую версию на своем промежуточном сервере, прежде чем запускать ее в производство - но, кто знает ... Иногда существует действительно большая ошибка, которую никто не смог увидеть, пока testing :-(
Например, потому что на промежуточной машине регулярно не проводится нагрузочное тестирование.
(Я видел, что «откат» использовал что-то вроде 4 или 5 раз за 3 года - каждый раз, это спас день - и сайты ^^)
Вот небольшой пример: предположим, у меня есть 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 » должны быть выполнены быстро; то есть автоматическим сценарием, а не человеком.
Используя это решение:
И если использовать какой-нибудь opcode-кеш, такой как APC, с опцией stat в 0, это может означать еще меньший риск простоя, я полагаю.
Конечно, это «простая» версия - например, если у вас есть загруженные файлы, вам нужно будет использовать другую символическую ссылку или VirtualHost или что-то еще ...
Надеюсь, это более понятно :-)
Разве вы не можете взять существующий код и перенести проект в отдельный тестовый php-файл и использовать его при обновлении? Я имею в виду, что у вас должен быть тестовый сервер и рабочий сервер, чтобы при обновлении не было простоев.
Настройте второй сервер с обновленной кодовой базой и переключите их как можно быстрее. :-)
Если это невозможно, убедитесь, что ваша кодовая база разделена на десятки более мелких частей. Тогда время простоя будет ограничено только одним подразделением за раз. Меньшие кодовые блоки легче заменить, и большинство просто продолжит работать без проблем. Просто попробуйте сначала в тестовой среде!
Во-первых, я часто использую метод, похожий на ответ Паскаля МАРТИНА.
Другой метод, который мне также нравится, - это использовать мой SCM для добавления нового кода. Точный процесс зависит от вашего типа SCM (git vs svn vs ...). Если вы используете svn, мне нравится создавать «онлайн» или «производственную» ветку, которую я извлекаю как корневой документ на сервере. Затем, когда я хочу отправить новый код из другой ветви / тега / транка, я просто фиксирую новый код в «онлайн» ветви и запускаю svn update в корне документа. Это позволяет выполнять очень простые откаты, поскольку имеется полный журнал изменений того, что было сделано на сервере, кто и когда это сделал. Вы также можете легко запустить эту «онлайн» ветку в тестовом окне, что позволит вам проверить приложение, которое вы собираетесь запустить.
Процесс похож на git и другие стили SCM, только что измененный, чтобы быть более естественным для их стиля рабочего процесса.
Хотите вытащить / опросить вместо того, чтобы выдвигать обновления? Просто запустите cron или другой, более умный механизм, который автоматически запускает svn update
Дополнительно: вы также можете использовать этот процесс для резервного копирования файлов, которые ваше приложение записало на диск. Просто запустите cron или какой-нибудь другой механизм, запустите svn commit. Теперь файлы, созданные вашим приложением, сохраняются в SCM, регистрируются ревизии и т. Д. (Например, если пользователь обновляет файл на диске, но хочет, чтобы вы вернули его, просто нажмите старую ревизию).
Я использую аналогичный подход к Паскалю Мартину тоже. Но вместо того, чтобы загружать несколько версий моего приложения на рабочий сервер, я сохраняю «сборки» за брандмауэром, каждая в отдельном каталоге с номером сборки и датой. Когда я хочу загрузить новую версию, я использую простой скрипт, который включает в себя «rsync -avh --delay-updates». Флаг «задержка = обновления» будет загружать все (что отличается) во временную папку до тех пор, пока не появятся все обновления, а затем переместит все сразу по окончании передачи на их правильные пути, чтобы приложение никогда не находилось в наполовину старое наполовину новое государство. Это имеет тот же эффект, что и описанный выше метод, за исключением того, что я храню только одну версию приложения на производственном сайте (лучше всего иметь только основные файлы на рабочем сервере, IMO).