Инфраструктура еды: как мы саппортим «Тануки»

vigszmdhwabpqlqr9bgrcx_ozaw.jpeg

Перефразируя одного известного исторического деятеля, важнейшим из всех сервисов для нас является доставка. Что бы мы делали в нынешней ситуации без роллов или пиццы на дом — представлять не хочется. Так получилось, что 2 года назад мы приняли на поддержку одну из крупнейших сетей — «Тануки». Месячная аудитория сайта — порядка миллиона человек. Это теперь, в 2020 году. В 2018-м, когда «Тануки» начали сотрудничество с нами, она была в 2 раза меньше. Мы обеспечили безболезненный переезд в новый дата-центр и полностью переделали инфраструктуру — благодаря чему, собственно, сайт и приложения способны без проблем выдерживать возросшую нагрузку.

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

В общем, сегодня мы хотим рассказать вам историю саппорта одного из крупнейших веб-проектов отечественной «индустрии гостеприимства».
Мы познакомились в конце марта 2018-го.

Международный женский день давно прошел, но ребята только-только справились с его последствиями. Всё довольно банально: накануне 8 марта трафик резко вырос, и сайт долгое время был недоступен. По-настоящему долгое, а не пару часов. Потому что трафик летел не только через основной сайт, но и поступал из приложения (есть для Android и iOS), а также агрегаторов («Яндекс. Еда», «Деливери Клаб», «Зака-зака»).

Что мы увидели


Технически проект оказался достаточно сложным:

  • Сайт — react-приложение с SSR (server side rendering).
  • Мобильные приложения — для iOS / Android.
  • API — с ним работают все приложения.
  • Внешние системы, в том числе, обработки заказов.

Система представляла собой серверы реверс-прокси: трафик на них шел через систему защиты от DDoS-атак и оттуда уже распределялся по бэкенд-серверам. На момент приемки был старый сайт и API для мобильных версий и стартовала разработка нового сайта. Разработка нового API велась на отдельных серверах.

Кластер БД представлял собой два сервера с мастер/мастер репликацией, где переключение в случае сбоя производилось на сетевом уровне за счет плавающего IP. Все приложения на запись работали с этим IP, в то время как на чтение были слейвы MySQL, размещенные на каждом сервере бэкенда — где приложение, соответственно, работало с localhost.

На приёмке мы увидели следующие проблемы:

  • Недостаточно надежный механизм балансировки в конфигурации БД. Мастер-мастер репликации приводили к частым сбоям.
  • Слейвы на каждом бэкенде — требовали большой объем дискового пространства. А любые манипуляции или добавление новых бэкенд-серверов требовали больших затрат.
  • Не было общей системы деплоя приложений — была самописная система деплоя через веб.
  • Не было системы сбора логов — вследствие чего достаточно сложно расследовать инциденты, в первую очередь, в работе с системой заказов, поскольку нет возможности определить, как был принят тот или иной заказ.
  • Отсутствовал мониторинг бизнес-показателей — не было возможности своевременно фиксировать снижение или полное отсутствие заказов.


После первичного аудита принятых на мониторинг серверов мы начали с формирования оперативного роадмапа. Изначально выделили два основных направления работ:

  1. Стабилизация работы приложений.
  2. Организация комфортной среды разработки для нового API и сайта.


Решения по первому направлению были, прежде всего, связаны со стабилизацией работы кластера MySQL. Отказываться от мастер-мастер репликации не хотелось, но и продолжать работать с плавающим IP было невозможно. Периодически наблюдались нарушения сетевой связанности, что приводило к нарушениям работы кластера.

Прежде всего, мы решили отказаться от плавающего IP в пользу прокси-сервера, где между мастерами будет контролируемо переключаться апстрим, так как в качестве прокси для MySQL мы задействовали nginx. Второй шаг — выделение двух отдельных серверов под слейвы. Работа с ними была также организована через прокси-сервер. И с момента реорганизации мы забыли о проблемах, связанных с работой с БД.

Далее мы замониторили заказы на уровне запросов в БД. Любое отклонение от нормы — в меньшую или большую сторону — сразу давало повод для начала расследования. Затем, на уровне логов, мы сформировали метрики для мониторинга внешних взаимодействий, в частности, с системой управления заказами.

Совместно с коллегами, по их запросам, производили донастройку всех систем до стабильной и быстрой работы. Это был и тюнинг MySQL, и обновление версий PHP. Кроме того, коллеги внедряли систему кэширования на базе Redis, что также способствовало снижению нагрузки на БД.

Все это было важно… Но главное для бизнеса — увеличение продаж. И в этом контексте большие надежды менеджеры компании возлагали на новый сайт. Для разработчиков же было необходимо получить стабильную и удобную систему для деплоя и контроля приложения.

В первую очередь, мы задумывались о конвейерах сборки и доставки приложения CI/CD, а также системах сбора и работы с логами.

Все репозитории клиента были размещены на self-hosted bitbucket-решении. Для организации пайплайнов был выбран jenkins.

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

После внедрения CI/CD занялись организацией сбора логов и работы с ними. В качестве основного был выбран стэк ELK, что позволило клиенту быстрее и качественнее проводить расследования в случае наступления инцидентов. И как результат — разработка приложения пошла быстрее.

«Страшнее двух пожаров…»


После решения достаточно сложных, но, тем не менее, стандартных задач, «Тануки» сказали нам то, что давно хотели сказать: «А давайте переедем!»

Смена ДЦ была вызвана экономическими факторами. Кроме того, клиент расширял свою инфраструктуру за счет дополнительных сервисов, которые уже были в новом ДЦ, — это также повлияло на принятие решения о переезде.

Миграция любой системы, а тем более, сложной — это процесс, требующий обстоятельного планирования и больших ресурсов.

Переезд проводился итерационно: на первом этапе были созданы реверс-прокси серверы в новом ДЦ. И поскольку только они обладают public ip — они же выступали и в качестве точек доступа в систему для администраторов.

Затем мы запустили все инфраструктурные сервисы — логирование и CI/CD. А Consul позволил организовать удобный, управляемый и достаточно надежный сервис взаимодействия между приложениями клиента.

Следующими мигрировали БД, Redis и брокер очередей, RabbitMQ. Тут было важно организовать всё так, чтобы они корректно регистрировались в протоколе обнаружения сервисов, который, в свою очередь, управлял работой ДНС. Отметим, что приложения работали не напрямую с БД, а через Haproxy, который позволяет удобно и балансировать между базами и переключаться в случае отказа.

На подготовительном этапе репликация БД между дата-центрами не поднималась. Пришлось просто перенести бэкапы. Следом начали настройку непосредственно приложений, а это организация всего взаимодействия через внутренний DNS — взаимодействия между приложением и БД/Redis/RabbitMQ/внешними сервисами (например, сервисами заказа). Естественно, на этом же этапе сразу подключались все механизмы CI/CD — и тут возникло второе изменение в архитектуре. Ранее менять настройки приложения через интерфейс возможности не было — только через редактирование файлов непосредственно в консоли. Тут же мы внедрили решение, позволяющее удобно управлять настройками- через веб интерфейс. Оно было основано на Hashicorp vault (в качестве бэкенда для него выступил Consul), что позволило построить удобные механизмы управления переменными окружения.

Следующий шаг — переключение сервисов на новый ДЦ. Поскольку работа всех систем организована по протоколу http, а все домены шли через систему защиты от DDoS-атак, то переключение сводилось к манипуляциям с апстримами непосредственно в интерфейсе этой системы.

Предварительно были организованы необходимые реплики из старого ДЦ в новый. И в согласованное окно работ было произведено переключение.

Как инфраструктура выглядит сейчас

qcpkfqmyvfy7wjcl9ayq80wd43s.jpeg

  • Весь трафик поступает на балансеры deac-web-ng-01 и deac-web-ng-02. Трафик до api6.tanuki.ru идет с приложения Тануки (на Android/iOS) не напрямую, а через Qrator.
  • На static сервере deac-web-back-02 находится основной сайт проекта tanuki.ru, сервер с лендингами.
  • Кластер бэкенда сейчас состоит из серверов: deac-web-back-01 (фронтенд), deac-web-back-02 (статика), сервера deac-web-back-03, deac-web-back-04, deac-web-back-05, deac-web-back-06 под приложения. На сервере deac-web-back-ersh-01 находится проект ersh.
  • БД: Mysql располагается на серверах deac-web-db-01, deac-web-db-04, deac-web-back-02, deac-web-back-ersh-01. Репликация баз данных идет с сервера deac-web-db-01 на deac-web-db-02 и deac-web-db-03, с сервера deac-web-db-02 на deac-web-db-04. С кластера backends чтение и запись базы данных идет на сервер deac-web-rabbit, а затем в кластер с базой данных серверов на запись и чтение идет на сервер deac-web-db-01 и только на чтение на сервера deac-web-db-02-deac-web-db-04.
  • Сервера deac-web-dev-01 и deac-web-stage выделены под разработку. На сервере deac-web-ops находится jenkins и bitbucket.


Схема прохождения заказа
Поступивший заказ проходит через Qrator (сразу отсеиваем атаки) и приходит на api6.tanuki.club (это back3–4–5 и 6). Далее он идет в Raiden на доставку заказа, едет в Redis (deac-web-rabbit) и едет в nginx (deac-web-rabbit), после чего уходит в БД.

Что изменилось для заказчика


  • Надежность системы: проблемы наблюдались в июле 2019-го — заказы не оформлялись в течении часа. Но это было до глобального переезда. В дальнейшем крупных инцидентов не наблюдалось.
  • Жизнь разработчиков: у них появилась удобная среда разработки, CI/CD.
  • Отказоустойчивость: инфраструктура сейчас выдерживает большой трафик. Например, в праздничные дни RPS достиг пика в 550 единиц.


Что дальше


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

Ещё один важный вопрос — это утилизация ресурсов и снижение затрат на содержание системы.

Всё это ведёт к необходимости пересмотра системы в целом. Первым шагом будет организация контейнеризации приложений. Затем планируется организация кластера Kubernetes. Но об этом мы расскажем в следующей статье. А пока — приятного аппетита :-)

© Habrahabr.ru