Редизайн новостного портала

Индустрии
Медиа и развлечения
Компетенции
Разработка, Мобильная разработка, UI/UX-дизайн
Технологии
.NET, Angular, ElasticSearch, RabbitMQ

Клиент


Наш заказчик — крупное региональное деловое издание. У него есть новостной сайт и активные группы в соцсетях; несколько раз в неделю выходит печатная версия. Ряд материалов предоставляется по платной подписке.

Кроме того, медиакомпания ведёт несколько подпроектов, посвящённых отдельным аспектам экономики региона.

Задачи


Новостной портал и сайты подпроектов создавались более 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.

Схема CI/CDСхема CI/CD — от начала разработки нового функционала до его развёртывания в рабочем окружении

Результат


Мы создали удобный, быстрый, динамически обновляющийся новостной портал с современным дизайном и несколько небольших сайтов подпроектов с единой авторизацией. Использование технологии PWA позволило обеспечить быструю загрузку и удобный интерфейс для пользователей на любых устройствах. Согласно информации сервиса «Яндекс Метрика», время загрузки страниц снизилось на 75%. Помимо удовлетворённости пользователей, скорость загрузки положительно влияет и на SEO: поисковые системы учитывают её при ранжировании сайтов в выдаче, что особенно важно для онлайн-СМИ.

Со стороны серверной части (бэкенда) мы сохранили всю существующую бизнес-логику и функциональность системы, но провели реструктуризацию архитектуры, базы данных и кода, применив современные подходы и технологии. Мы также сделали процесс разработки и развёртывания новых версий более управляемым и автоматизировали многие рутинные бизнес-процессы. Это упростило поддержку и дальнейшее развитие системы.

Весь контент перенесён в облачное хранилище — это дополнительно ускорило его загрузку. При этом реструктуризация системы и использование современных технологий позволили снизить затраты на использование инфраструктуры в полтора раза, а использование балансировщика нагрузки сделало систему более отказоустойчивой и масштабируемой. Запланированное или внезапное отключение одной из виртуальных машин не сказывается на скорости работы сайта с точки зрения пользователей, равно как и пиковые нагрузки (наплыв посетителей на сайт).