Наша команда занимается удаленным администрированием серверов и не так давно к нам обратились представители сервиса WebConsult с задачей построить легко масштабируемую серверную архитектуру, которая будет выдерживать серьезные нагрузки. Мы решили, что возможно это будет интересно пользователям Хабрахабра, которые так или иначе связаны с администрированием Highload проектов. Проект оказался быстрорастущим и имеющаяся на тот момент структура уже работала на пределе, поэтому нам пришлось в ускоренном режиме запускать новую.
Чтобы сделать это быстро, мы постарались максимально распределить задачи между всеми нашими администраторами. Для этого мы использовали систему управления проектами и задачами — Redmine и там же поддерживали связь с разработчиками проекта, которые оперативно отвечали на наши вопросы и выполняли необходимые доработки в коде.
Чтобы понимать суть поставленной перед нами задачи, давайте разберемся, в чем состоит принцип работы проекта. WebConsult представляет собой систему, с помощью которой посетители сайта могут связаться с менеджером магазина или компании и задать интересующие их вопросы в реальном времени. Менеджеры со своей стороны, на выбор, используют два варианта консультирования — через панель открытую в браузере или через любой привычный Jabber-клиент. В свою очередь посетители сайтов, где установлена система, видят кнопку вызова консультанта, которая подгружается с сервера WebConsult (а это значит, что скорость работы сервиса очень важна). Поскольку кнопка загружается несколько миллионов раз за сутки, это создает значительную нагрузку на веб-серверы. Также серьезную часть нагрузки составляют именно операторы, которые пользуются основным способом консультирования — через веб-клиент. В данном случае, от тысяч консультантов находящихся одновременно в онлайне через определенное количество секунд приходят HTTP-запросы на предмет обновлений (новый клиент, сообщение, изменение различных статусов) это тоже потребляет огромное количество ресурсов HTTP-серверов и серверов БД.
Давайте перейдем к рассмотрению построенной нами архитектуры. В основе всего лежит балансировка на уровне DNS (round-robin), которая передает трафик на два фронта (это удобно в том числе для случаев, когда один из серверов кратковременно недоступен — современные браузеры перекидывают запрос автоматически на второй сервер). Фронты же в свою очередь проксируют трафик с помощью nginx на HTTP-серверы — web1, web2, web3 и так далее.
Под каждую отдельную задачу мы старались создать свой контейнер OpenVZ, чтобы изолировать логические части проекта друг от друга, а так же иметь возможность быстро выделить контейнер на отдельный физический сервер. Почему нами выбрана именно эта виртуализация, мы описывали в одной из прошлых статей.
С целью экономии трафика и оптимизации нагрузки вся проходящая статика кэшируется средствами nginx. В прежней архитектуре для хранения файлов и исходного кода использовался NFS, но от него было принято решение отказаться ввиду того, что это оказывало дополнительную нагрузку. Вместо этого, мы стали отлавливать запросы на загрузку статики (аватары консультантов, логотипы компаний) и перенаправлять их на один сервер. NGINX настроен так, что если не находит картинки локально, то ищет их на других веб-серверах с помощью try_files $uri servers, а в именованном локейшене servers прописан перебор веб-серверов. Также статика несколько раз в сутки синхронизируется с другими серверами, что делает их доступными локально.
Важной частью проекта WebConsult является работа с клиентами на сайте через Jabber. В качестве XMPP-сервера используется Openfire с рядом самописных модулей, которые позволяют интегрироваться с внутренней структурой проекта и передавать сообщения из Jabber в HTTP и обратно. Для удобства клиентов, стояла задача сделать возможность подключения к jabber-серверу не только по прямому домену jabber.consultsystems.ru, но и через главный домен consultsystems.ru. Для этого необходимо было организовать проксирование портов. Мы решили заменить ранее используемый rinetd на более продвинутое решение и применили для этой задачи HAProxy, который пробрасывает порты 5222, 5223 в режиме TCP.
Поскольку WebConsult — проект, который постоянно дорабатывается и расширяется, нужно было придумать решение позволяющее разработчикам видеть внесенные изменения на сервере в своей собственной «песочнице» (sandbox), чтобы клиенты замечали их только после того, как все протестировано и выполнен финальный деплой. Для этого был создан отдельный контейнер OpenVZ с минимальным количеством выделенных ресурсов, где запущена версия сайта для тестирования и отладки. В качестве системы контроля версий был выбран GIT, как привычное и современное решение. В итоге получилось, что разработчики могут вводить новые функции, тестировать их на отдельном сервере, а после того, как все готово произвести деплой обновленной версии проекта в продакшн, что практически исключает возможность сбоя и ошибок в рабочей копии проекта. Так же, для удобства, мы написали небольшой плагин для Redmine, который дает возможность разрешенным пользователям делать деплой нажатием на кнопку.
В качестве сервера БД мы выбрали Percona Server, как более производительный вариант mysql-сервера.
Memcached служит для центрального хранения пользовательских сессий. Доступ к нему открыт только для вебов правилами iptables.
В результате у нас получилась структура, которая легко горизонтально масштабируется добавлением новых веб-серверов путем «клонирования» существующего контейнера OpenVZ и переносом его на новую машину. Что касается масштабируемости БД, то в данный момент, со всем справляется один мощный сервер, а в будущем будет применена репликация. Также часть «тяжелых» функций, для которых сейчас используется MySQL, будет переведена на NoSQL решения, например Redis, что серьезно разгрузит серверы. Еще очень важной в данный момент задачей является перевод чата на web-сокеты, с целью отказаться от выполнения регулярных HTTP-запросов и вместо этого держать постоянное соединение с сервером – работы в этом направлении уже ведутся.
Спасибо за внимание, если у вас есть вопросы или предложения – будем рады обсудить в комментариях.
Чтобы сделать это быстро, мы постарались максимально распределить задачи между всеми нашими администраторами. Для этого мы использовали систему управления проектами и задачами — Redmine и там же поддерживали связь с разработчиками проекта, которые оперативно отвечали на наши вопросы и выполняли необходимые доработки в коде.
Чтобы понимать суть поставленной перед нами задачи, давайте разберемся, в чем состоит принцип работы проекта. WebConsult представляет собой систему, с помощью которой посетители сайта могут связаться с менеджером магазина или компании и задать интересующие их вопросы в реальном времени. Менеджеры со своей стороны, на выбор, используют два варианта консультирования — через панель открытую в браузере или через любой привычный Jabber-клиент. В свою очередь посетители сайтов, где установлена система, видят кнопку вызова консультанта, которая подгружается с сервера WebConsult (а это значит, что скорость работы сервиса очень важна). Поскольку кнопка загружается несколько миллионов раз за сутки, это создает значительную нагрузку на веб-серверы. Также серьезную часть нагрузки составляют именно операторы, которые пользуются основным способом консультирования — через веб-клиент. В данном случае, от тысяч консультантов находящихся одновременно в онлайне через определенное количество секунд приходят HTTP-запросы на предмет обновлений (новый клиент, сообщение, изменение различных статусов) это тоже потребляет огромное количество ресурсов HTTP-серверов и серверов БД.
Балансировка
Давайте перейдем к рассмотрению построенной нами архитектуры. В основе всего лежит балансировка на уровне DNS (round-robin), которая передает трафик на два фронта (это удобно в том числе для случаев, когда один из серверов кратковременно недоступен — современные браузеры перекидывают запрос автоматически на второй сервер). Фронты же в свою очередь проксируют трафик с помощью nginx на HTTP-серверы — web1, web2, web3 и так далее.
Виртуализация
Под каждую отдельную задачу мы старались создать свой контейнер OpenVZ, чтобы изолировать логические части проекта друг от друга, а так же иметь возможность быстро выделить контейнер на отдельный физический сервер. Почему нами выбрана именно эта виртуализация, мы описывали в одной из прошлых статей.
Веб-сервер NGINX
С целью экономии трафика и оптимизации нагрузки вся проходящая статика кэшируется средствами nginx. В прежней архитектуре для хранения файлов и исходного кода использовался NFS, но от него было принято решение отказаться ввиду того, что это оказывало дополнительную нагрузку. Вместо этого, мы стали отлавливать запросы на загрузку статики (аватары консультантов, логотипы компаний) и перенаправлять их на один сервер. NGINX настроен так, что если не находит картинки локально, то ищет их на других веб-серверах с помощью try_files $uri servers, а в именованном локейшене servers прописан перебор веб-серверов. Также статика несколько раз в сутки синхронизируется с другими серверами, что делает их доступными локально.
Jabber
Важной частью проекта WebConsult является работа с клиентами на сайте через Jabber. В качестве XMPP-сервера используется Openfire с рядом самописных модулей, которые позволяют интегрироваться с внутренней структурой проекта и передавать сообщения из Jabber в HTTP и обратно. Для удобства клиентов, стояла задача сделать возможность подключения к jabber-серверу не только по прямому домену jabber.consultsystems.ru, но и через главный домен consultsystems.ru. Для этого необходимо было организовать проксирование портов. Мы решили заменить ранее используемый rinetd на более продвинутое решение и применили для этой задачи HAProxy, который пробрасывает порты 5222, 5223 в режиме TCP.
Разработчикам
Поскольку WebConsult — проект, который постоянно дорабатывается и расширяется, нужно было придумать решение позволяющее разработчикам видеть внесенные изменения на сервере в своей собственной «песочнице» (sandbox), чтобы клиенты замечали их только после того, как все протестировано и выполнен финальный деплой. Для этого был создан отдельный контейнер OpenVZ с минимальным количеством выделенных ресурсов, где запущена версия сайта для тестирования и отладки. В качестве системы контроля версий был выбран GIT, как привычное и современное решение. В итоге получилось, что разработчики могут вводить новые функции, тестировать их на отдельном сервере, а после того, как все готово произвести деплой обновленной версии проекта в продакшн, что практически исключает возможность сбоя и ошибок в рабочей копии проекта. Так же, для удобства, мы написали небольшой плагин для Redmine, который дает возможность разрешенным пользователям делать деплой нажатием на кнопку.
База данных
В качестве сервера БД мы выбрали Percona Server, как более производительный вариант mysql-сервера.
Memcached служит для центрального хранения пользовательских сессий. Доступ к нему открыт только для вебов правилами iptables.
Масштабирование
В результате у нас получилась структура, которая легко горизонтально масштабируется добавлением новых веб-серверов путем «клонирования» существующего контейнера OpenVZ и переносом его на новую машину. Что касается масштабируемости БД, то в данный момент, со всем справляется один мощный сервер, а в будущем будет применена репликация. Также часть «тяжелых» функций, для которых сейчас используется MySQL, будет переведена на NoSQL решения, например Redis, что серьезно разгрузит серверы. Еще очень важной в данный момент задачей является перевод чата на web-сокеты, с целью отказаться от выполнения регулярных HTTP-запросов и вместо этого держать постоянное соединение с сервером – работы в этом направлении уже ведутся.
Спасибо за внимание, если у вас есть вопросы или предложения – будем рады обсудить в комментариях.