Клиент
Наш заказчик — крупное региональное деловое издание. У него есть новостной сайт и активные группы в соцсетях; несколько раз в неделю выходит печатная версия. Ряд материалов предоставляется по платной подписке.
Кроме того, медиакомпания ведёт несколько подпроектов, посвящённых отдельным аспектам экономики региона.
Задачи
Новостной портал и сайты подпроектов создавались более 15 лет назад и перестали отвечать требованиям пользователей — дизайн устарел, а сайт работал медленно.
Имелись и внутренние проблемы — сайты и вся инфраструктура полагались на устаревшие технологии, дорабатывались хаотично, а рефакторинг практически не проводился. Из-за этого поддержка сайта была сильно затруднена. Назрело понимание, что система нуждается в серьёзной переработке.
Когда заказчик поставил нам задачу редизайна всех сайтов, стало окончательно ясно, что в текущем состоянии крайне сложно менять что-либо в интерфейсе. Поэтому по согласованию с заказчиком было решено:
- провести полную реструктуризацию всей системы и базы данных;
- перевести клиентскую часть на фреймворк Angular.
Решение
Практически всю архитектуру нужно было разработать с нуля, но с оглядкой на старую систему, чтобы не потерять необходимый функционал. После анализа поставленных задач и существующих проблем мы запланировали следующие основные шаги:
- реструктурировать базу данных;
- портировать клиентскую часть (интерфейс) сайтов на последнюю версию Angular в соответствии с новыми макетами дизайна, но с сохранением существующей бизнес-логики;
- портировать серверную часть на последние версии фреймворка.NET, преобразовать приложение из MVC в профильное Web API;
- переписать дополнительные службы — планирование публикаций, email-рассылки, push-уведомления и др.;
- создать необходимую инфраструктуру для работы сайта и автоматизации процессов (хранилища NPM- и NuGet-пактов, SQL Server, ElasticSearch, RabbitMQ и пр.) с использованием облачных технологий, в том числе хранение медиа-файлов в облаке (Object Storage);
- автоматизировать процесс развёртки новых версий на тестовый и рабочие сервера;
- перенести существующие данные в новую инфраструктуру «за одну ночь».
База данных
Помимо переработки схемы данных (реструктуризация, пересмотр индексов, связей по внешним ключам и др.), мы пересмотрели подход к организации взаимодействия кода с базой данных (БД).
Было принято решение использовать ORM EntityFramework, что позволило перенести бизнес-логику из базы данных в код приложения и автоматизировать обновление схемы БД (для удобства дальнейшей разработки).
Кроме того, для минимизации времени простоя сайта при переходе на новую инфраструктуру была разработана утилита для быстрого переноса данных из старой БД в новую с учётом всех структурных изменений.
Клиентская часть (интерфейс)
Мы переработали дизайн сайта с учётом современных лучших практик UX. Поскольку всё большая доля пользователей интернета просматривает сайты с мобильных устройств, мы реализовали каждый сайт в виде прогрессивного веб-приложения (Progressive Web Application). Такое приложение выглядит и работает на смартфоне практически как нативное. Приложение (сайт) полностью кэшируется в браузере, передача данных по сети минимальна (только запросы к API и облачному хранилищу для загрузки контента), а значит сайт работает быстро даже при низкой скорости соединения.
Мы настроили рендеринг HTML-страниц на стороне сервера при первичной загрузке сайта. Это позволяет ускорить начальную загрузку сайта при низкой скорости интернета и способствует правильному отображению превью в ссылках на страницы сайта из социальных сетей. Это также соответствует лучшим SEO-практикам, поскольку не все поисковики умеют правильно обрабатывать скрипты, и многие из них учитывают скорость загрузки страницы при её ранжировании.
Для обработки ошибок доступа к сети Интернет реализована система уведомлений пользователя об отсутствии подключения к сети и серии повторных попыток загрузки данных.
Наконец, мы настроили единую авторизацию: залогинившись на любом сайте компании, пользователь автоматически получает доступ ко всем остальным.
Серверная часть (Web API)
Мы в сжатые сроки разработали все службы, необходимые для работы и поддержки сайтов:
- несколько Web API, служащих источником данных для клиентской части и использующих такие техники и технологии, как кэширование данных, валидация запросов, проверка работоспособности (health-check) и др.;
- полнотекстовый поиск по сайту (ElasticSearch);
- логирование полезной информации и ошибок в Elastic Stack;
- глобальная обработка ошибок;
- аутентификация, авторизация (в том числе через внешние провайдеры по протоколу OAuth) и ограничение доступа к методам контроллеров по ролям, а также наличию подписки;
- взаимодействие со службами с помощью очередей RabbitMQ — например, отправка задач на отложенное выполнение.
Кроме того, для автоматизации бизнес-процессов был создан ряд служб, решающих регулярные задачи:
- генерация XML-файлов для RSS-каналов по расписанию;
- отправка email-рассылок и push-уведомлений;
- интеграция с банком, онлайн-кассами и ОФД, в том числе рекуррентные платежи (автоплатежи);
- индексирование в ElasticSearch по мере выхода новых материалов.
Инфраструктура и DevOps
Архитектура и инфраструктура планировались и реализовывались при тесном взаимодействии с системными администраторами заказчика.
Части кода, содержащие общую бизнес-логику, вынесены в отдельные NPM- и NuGet пакеты, что позволяет использовать их в разных приложениях (сайтах, службах), упрощает процесс доработки, обновления и тестирования, а также снижает вероятность ошибок.
Для обеспечения отказоустойчивости все сайты и инфраструктура размещены за балансировщиком нагрузки с гибким управлением и автоматическим мониторингом работоспособности серверов. Все ошибки и события, происходящие на сервере, логируются в Elastic Stack, развёрнутый на отдельной виртуальной машине.
Для хранения и управления исходным кодом выбран GitLab. В нём также реализовано хранение NPM- и NuGet-пакетов и CI/CD — автоматическая сборка и развёртывание новых версий системы в рабочем окружении. Для управления процессом развёртывания используется Octopus Deploy.
Результат
Мы создали удобный, быстрый, динамически обновляющийся новостной портал с современным дизайном и несколько небольших сайтов подпроектов с единой авторизацией. Использование технологии PWA позволило обеспечить быструю загрузку и удобный интерфейс для пользователей на любых устройствах. Согласно информации сервиса «Яндекс Метрика», время загрузки страниц снизилось на 75%. Помимо удовлетворённости пользователей, скорость загрузки положительно влияет и на SEO: поисковые системы учитывают её при ранжировании сайтов в выдаче, что особенно важно для онлайн-СМИ.
Со стороны серверной части (бэкенда) мы сохранили всю существующую бизнес-логику и функциональность системы, но провели реструктуризацию архитектуры, базы данных и кода, применив современные подходы и технологии. Мы также сделали процесс разработки и развёртывания новых версий более управляемым и автоматизировали многие рутинные бизнес-процессы. Это упростило поддержку и дальнейшее развитие системы.
Весь контент перенесён в облачное хранилище — это дополнительно ускорило его загрузку. При этом реструктуризация системы и использование современных технологий позволили снизить затраты на использование инфраструктуры в полтора раза, а использование балансировщика нагрузки сделало систему более отказоустойчивой и масштабируемой. Запланированное или внезапное отключение одной из виртуальных машин не сказывается на скорости работы сайта с точки зрения пользователей, равно как и пиковые нагрузки (наплыв посетителей на сайт).