Задача:

перенести работающий проект с одного сервера на другой.

Имеем:

рабочий сервер, новый сервер сконфигурированный и настроенный для работы проекта.

Я не буду вникать в тонкости настройки сервера, так как это может быть в принципе любой сервер под любой ОС. Главное что бы у вас был полный доступ ко всей системе. Т.е. права администратора. А так же сервер должен быть готовым в любой момент принять посетителей. Т.е. должны быть настроены виртуалы, установлена СУБД, ВЕБ сервер и т.д.

Первый способ простой:

Вешаем на рабочем сервере страницу с надписью «Мы переезжаем, приходите завтра» и поехали!

Собственно лучше всего начать со скриптов. Было бы идеально, если бы у вас был SVN или CVS. В этом случае скрипты залить можно в один клик. В принципе по FTP так же можно легко залить, но если вам будет необходимо что-то подправить и быстро перезалить, то, возможно, будет немного проблематично в спешке залить все измененные файлы особенно если они разбросаны по разным директориям.

После заливки скриптов переходим к базе. Если ваша база не гигабайтных/терабайтных размеров, то можно попробовать сделать тестовую базу и залить туда весь дамп. Если дамп все-таки уж сильно большой, то можно залить только структуру и необходимые таблицы (что бы система «запустилась») в тестовую базу и тестировать на ней. Это нужно для промежуточного тестирования перед тем как открыть сайт для посетителей. Кроме тестовой базы создайте рабочую и залейте туда весь дамп но в настройках оставьте использование тестовой базы.

Виртуальный хост. Его следует настраивать так, что бы он мог работать с двумя разным доменами. Зачем? Опять же для тестирования. К примеру ваш сайт site.com сейчас закрыт, но вам же нужно убедиться что на новом сервере все будет хорошо? Вот для этого и нужен второй домен. Где его взять – это уже второй вопрос. Если у вас нет поддоменов – то можно на время добавить test.site.com и его прописать на новый сервер. Ну или же просто пропишите в хостах (в свой ОС) любой домен и это должно работать. Так же нужно заметить, что ваши скрипты должны быть правильно настроены для этого домена (если конечно они привязываются к доменам).

Переливка контента. Если на вашем сайте есть пользовательский контент, его нужно так же перелить на новый сервер. Сделать это можно различными способами в зависимости от вашей ОС и ваших навыков. Не буду подробно останавливаться на этой, в общем-то, тривиальной задаче.

Если все прошло успешно – пробуйте зайти на тестовый домен. В этом случае при правильной конфигурации сайт должен работать корректно. Сделайте полную проверку системы – зарегистрируйте пользователя, проверьте отправку почты, аплоад файлов, работу служб, кронов, демонов и т.д. если все хорошо – переключите скрипты на реальную базу и можно менять ДНС (IP у реального домена). По мере того как будет проходить апдейт по ДНС серверам на ваш новый сервер будут прибывать все новые и новые посетители. Не забудьте на новом сервере убрать страничку с надписью. Она тут совсем ни к чему :)

Примерное время – от 30 минут до 3-4 часов (без учета времени обновления ДНСов)

Далее веселее…


Второй способ – переезд на лету без закрытия сайта.

Более сложный и требует изменения скриптов, а так же настройки репликации базы. И некоторых манипуляций с системой. Так же требует бОльших временных затрат и хороших навыков в администрировании системы. Лучше это делать совместно с системным администратором.

Начало такое же, как и в первом случае – настройка виртуалов, СУБД, ВЕБ сервера и т.д. Только сайт не закрываем! Пусть посетители ходят. Далее веселее – правим скрипты. Нам необходимо добавить глобальную константу которая будет содержать момент времени, с которого начнется наш переезд. Мы будем опираться на эту константу во многих местах проекта, так что она должна быть видима везде. Хочу заметить – эта константа нужна лишь в том случае, если в системе используется контент пользователей. К примеру, пользователи заливают картинки, аватарки, музыку и т.д. В этом случае нам нужно знать – с какого момента мы начинаем переезжать и новый контент должен заливаться на новый сервер, а старый оставаться там где он есть. Если мы просто запустим копирование текущего контента на новый сервер, то никто нам не даст гарантии, что пока мы все скопируем, у нас не появиться ничего нового. Кто-то может уже догадался что нужно делать с константой. Но я поясню подробней – к примеру, мы должны начать переезд в 00:00:00 01-03-2009. К этому моменту весь пользовательский контент должен сохраняться на старом сервере, после этого момента – на новом. Для этого придется править скрипты во всех местах где загружается контент. Нам нужно добавить проверку на время и если время сервера меньше чем время константы – оставлять контент там где он есть, если больше – заливать на новый сервер. Заливку можно сделать различными способами. Можно смонтировать NFS или drbd (под * nix). Можно заливать контент по FTP, SCP или другими способами. Конечно вы должны заботить о безопасности и устойчивости системы, поэтому выбор средства доставки контента опять же зависит от конкретной ситуации. Но как понять, какой контент где? И как новый контент отделить от старого? Хорошо если у вас в базе храниться время добавления контента – это очень сильно облегчает задачу, если же этого нет… то нужно исходить из текущей ситуации – если СУБД поддерживет глобальные ID объектов (OID), то можно по ним получить первый ID после указанной даты (опять же автоматически) или же попытаться получить ID для каждой таблицы где хранится контент по отдельности и привязываться уже к ним. К примеру эту проблемы мы решили. Что дальше? Дальше нам нужно настроить вспомогательный домен для нового сервера. К примеру ваш сайт пусть будет все тот-же site.com использует поддомены для доступа к контенту: video.site.com, audio.site.com и т.д. это так же облегчит нам жизнь. Добавляем поддомен: new.site.com и в нем прописываем все наши поддомены: video.new.site.com, audio.new.site.com ну или наоборот – для каждого поддомена прописываем еще один: new.video. site.com, new.audio.site.com и т.д. главное что бы они указывали на новый сервер и по этому адресу был новый контент. И осталось самое малое – заменить все ссылки на контент в зависимости от нашей константы – т.е. после даты X часть ссылок будет указывать на новый контент, а часть на старый. Если у вас пути прописаны в одном месте и доступны глобально – то не составит большого труда заменить ссылки налету если же все ссылки вбиты гвоздями в шаблоны… ну вы сами понимаете кто вы теперь :) Но не все так просто как кажется. Вам придется поправить все места, где выводиться контент… К сожалению их может быть очень много. Хорошо если у вас хорошая архитектура проекта и на все сущности есть классы с методами получения объектов из базы. Можно на время грубо вписаться в эти методы и там делать проверку. К примеру, вы получаете объект audio только в методе retrieve в классе Audio. В таком случае можно добавить свою проверку в этот метод и изменить ваш базовый URL. Но если на вашей странице будет список из старого и нового контента, то придется править шаблон конкретно этой страницу. Увы.

Что бы избежать такой ситуации – добавьте всего одно поле в таблицы контента (лучше подумать над этим на стадии архитектурирования), которое будет указывать откуда брать этот контент. К примеру поле storage (smallint) содержит 1,2,3… а в шаблонах вы просто на основании этого подставите необходимый урл – для 1 – vid1.site.com, для 2 – vid2.site.com и т.д. Так же рекомендуется делать нечто подобное для распределения контента по нескольким серверам на рабочем проекте с высокой нагрузкой. Но это уже другая история.

UPD: избежать этих танцев с буном в некотором случае можно проксированием — все запросы к контенту заворачиваються на новый сервер и там, если контент не найден проксируются на старый. Спасибо mgyk за подсказку.

Итак, на данный момент мы решили проблему с распределением контента и подстановкой правильных ссылок в зависимости от временной константы. Далее база.

Проблема та же – нужно иметь возможность использовать 2 базы параллельно. Очень хорошо, если у вас уже есть кластер. С ним мы решаем одну важную проблему – сервер репликации у нас есть. Если этот сервер поддерживает мастер-мастер да еще и можно добавлять сервера «на лету» то это просто супер. Все что нам нужно – это поднять безопасный канал между серверами и через него настроить репликацию. На живом сервере подымаем мастер, настраиваем репликацию с нашим рабочим сервером и он затягивает (по крайней мере должен) всю базу сам + постоянно поддерживает её в актуальном состоянии что очень важно. На данный момент он работает как «slave» т.е. только синхронизируется с основной базой.

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

Если же репликация невозможна, то тогда мы зашли в тупик…

Возможно, многие скажут, что репликация не самый лучший способ. Да, возможно это так. Это будет немого тормозить, а в режиме реал-тайм это будет нагружать всю систему, но это на самом деле не на долго. Всего на несколько часов, пока вы не перельете основной контент и не обновяться все ДНСы. У меня уходило не более 30 часов.

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

Начинаем плавный переход – добавьте IP нового сервера в ваш основной домен. По мере того как будет обновляться зона, к вам пойдут пользователи на новый сайт. Это нужно начинать делать после наступления заветной даты. Так же убедитесь, что весь новый контент со старого сервера заливается на новый и база работает как нужно. Сейчас она может тормозить. Все зависит от канала, но если вы не храните в ней картинки, музыку, видео и т.д., то синхронизация не будет напрягать.

Как только вы убедились что все идет как нужно, начинайте переливать старый контент. Просто сделайте его копию. Не переживайте, он уже не измениться. Конечно, если все работает так, как нужно. Как только зальется весь контент – убирайте старый IP у домена. Должен остаться только новый. По мере обновления зоны все пользователи перейдут на новый сервер. Примерно через сутки повесьте на всякий случай на старом сервере в виртуале для домена страничку с просьбой обновить ДНС кеш. Это если у кого-то он закешировался. Остановите сервер репликации на новом сервере. Залейте старые скрипты без проверок. Если все нормально – поздравляю – вы на новом сервере. Если что-то пошло не так – я не виноват :)

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

Так же будьте внимательны когда будете вносить изменения в скрипты – они не должны пытаться заливать контент на новом сервере. Для этого необходимо сделать дополнительную проверку на предмет их местонахождения. Например добавить какой-то файл, который будет только на новом сервере и если он есть – значит не отправлять контент.

Собственно на этом все.

Спасибо за внимание и инвайт, надеюсь это кому-то поможет.