15 апреля прошел конкурс «Мисс Россия» 2017. После полной переделки сайта скорость загрузки страниц стала укладываться одну секунду даже в моменты пиковых нагрузок. Наши партнёры из Byndyusoft в лице Александра Бындю (@alexanderbyndyu), архитектора всей системы, рассказали, как им это удалось, поделились деталями переноса платформы в облако, а также рассказали, почему им пришлось поменять всю внутреннюю инфраструктуру проекта.



Справка о компании: Byndyusoft — это компания, которая реализует проекты на платформе .NET для различных предметных областей по всему миру.

О конкурсе


Национальный конкурс «Мисс Россия» — крупнейший проект страны в области красоты. В настоящее время конкурс проходит при поддержке Министерства культуры Российской Федерации. В этом году конкурс отпраздновал свое 25-летие.

Отборочные туры «Мисс Россия» проводятся в 85 субъектах Российской Федерации, ежегодно в кастингах принимает участие более 75 000 девушек.

Конкурс «Мисс Россия» обладает уникальными правами на представление нашей страны на крупнейших международных конкурсах красоты «Мисс Мира» и «Мисс Вселенная».



Особенность сайта конкурса в том, что 97% трафика и 100% голосования проходит в течение двух недель в апреле. По сравнению с апрельской нагрузкой весь остальной год проходит без нагрузок.



В чем проблема



За последние несколько лет сайт «Мисс Россия» постоянно доделывали и переделывали, обновляли каждый год к новому конкурсу. К 25-летнему юбилею «Миссия Россия» доехала с дизайном от Студии Лебедева, который жил на CMS «Плеск».

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

Сайт хостился на выделенном сервере. Добавление железа в сервер перестало приносить пользу. Когда заказчик провел нагрузочное тестирование, сайт упал на 150 запросах в секунду.


Нагрузочные тесты первой версии

Первая попытка

Сначала заказчики попробовали перенести сайт с выделенного сервера в облако — скопировали виртуалку и запустили ее на Azure. Несмотря на возросшую мощность и надежду на «облака», быстродействие упало, сайт ложился при 90 запросах в секунду.


Первая версия на Azure

Сайт конкурса нельзя было горизонтально масштабировать. Добавляешь в 5 раз больше железа, а производительность возрастает на 30%; наращиваешь еще в два раза больше — она увеличивается еще на 2%. Типичная проблема монолитных систем.


Архитектура старой версии

Конечно, со старой «Мисс Россией» можно было бы повозиться. Например, добавить CDN или поднять несколько виртуалок через балансировщик. Но каждый такой ход упирался бы в проблемы старого кода и CMS, а желаемой гибкости по масштабированию все равно бы не принес.
Стало понятно, что его нужно переделывать полностью под новую архитектуру и облачную инфраструктуру.

Вторая попытка

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

Верстка

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

  1. В 2..13 раз меньше запросов на страницу.
  2. В 5..16 раз меньше трафика.
  3. В 8 раз меньше времени на полную загрузку.

Проанализировали Метрику и оказалось, что 60% посетителей ходят через мобильные устройства. Переверестали сайт, чтобы всё стало адаптивно и респонсивно.

Было



Стало



Архитектура


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

Для новой архитектуры мы взяли за основу идеи, которые бы привели к достижению бизнес-целей:

  1. Разделить приложение на (микро)ответственности.
  2. Каждая часть будет идеально выполнять свою роль.
  3. Каждая часть будет сама заботиться о масштабировании.
  4. Тотальная автоматизация.

В итоге пришли к такой архитектуре:



Новая архитектура



Раньше все запросы с сайта попадали в блок монолита, который отвечал за обработку голосов и формирование контента. При перегрузке одного модуля другие тоже начинали тормозить. Теперь каждая часть работает и масштабируется независимо.

Новый результат нагрузочного тестирования внушал оптимизм:

  1. Нагружали через сеть с пропускной способностью 1Гбит/с.
  2. После ~5450 RPS видим первые проблемы с ответами сервера.
  3. Время ответа не превышало 1000 мс




Технологии


Azure предоставляет выбор в технологиях и решениях. Например, какой CDN взять? Akamai или Verizon? Мы ставили эксперименты и выбрали наиболее подходящие инструменты, по дороге найдя пару критичных проблем.

.NET Core и Kestrel

Новый сайт конкурса написан на .NET Core. Мы уже полгода работаем с ним в продакшене на других проектах — проблем не наблюдаем.

Единственная неприятная проблема возникла с Kestrel, который под нагрузкой начинал отвечать кодом 502.3. При этом приложение падало и не оживало до перезапуска.

Проблема была в версии Kestrel версии 1.1.0. Описание в Issue323 и Issue311. Нам повезло, что за две недели до начала конкурса вышел пакет Microsoft.AspNetCore.Server.Kestrel версии 1.1.1 и проблема ушла.

CDN

Мы выбирали между Akamai и Verizone. Выбрали Akamai, т.к. у них есть кэш-сервера в России, что важно для аудитории конкурса.

CDN в целом использовал стандартный подход:

  1. Картинки кэшируются на 7 суток, HTML обновляется 1 раз в час.
  2. JavaScript и CSS новых версий автоматом попадают в CDN, каждая версия кэшируется отдельно.
  3. Включено сжатие.
  4. Можно вручную сбросить кэш.

Если вы хотите кэшировать HTML, то обратите внимание, что CDN Akamai поддерживает только домены 3-го уровня. Для кэширования нам пришлось сделать редирект с missrussia.ru на www.missrussia.ru.

WebApp

Мы развернули основной сайт и API в отдельных WebApp. При изменении нагрузки у нас был выбор по способу масштабирования:

  • Scale Up: повышать/понижать мощность сменой тарифа.
  • Scale Out: увеличивать кол-во инстансов. При этом Azure сам балансирует нагрузку между работающими копиями сервиса.

Во время конкурса оба WebApp работали на тарифе S3, после конкурса на тарифе S1, чтобы не жечь деньги, когда нагрузки нет.

Service Bus

Мы выбирали очередь между Service Bus и Storage Queues. Вот что нам требовалось:

  1. Обмен сообщениями небольшого размера с коротким временем обработки.
  2. Отсутствие необходимости в транзакциях и поддержки очередности обработки сообщений.
  3. Наличие клиента под .NET Core.

Выбрали Service Bus с клиентом .NET Standard client library for Azure Service Bus.

Если очередь работает медленно и падает при отправке сообщения, то проверьте, что вы:

  • Подняли очереди в том же регионе, что и сервисы, которые читают и публикуют сообщения.
  • Зарегистрировали клиент ServiceBus как Singleton, чтобы каждый раз не поднимать коннект.

WebJob и проверка голосов

При решении задачи с голосованием нужно было учесть, что наплывы голосующих не влияли на скорость отклика основного сайта. Кроме этого, важно было усилить алгоритмы отсева ботов, потому что в прошлые года “накрутки” голосов были проблемой. То есть система голосования должна работать быстрее и при этом делать более сложный анализ.

Мы разнесли во времени определение качества голоса и инкремент голоса. Когда человек голосует, ему всегда отвечают: «Спасибо, Ваш голос учтен!». В этот момент формируется сообщение о голосе, сообщение отправляется в очередь, где оно ждет свой черед на разбор в сервисе обработки голосов. Обработанные голоса попадают в базу данных, а затем, спустя несколько часов, на сайт. Счетчик голосов прибавляется разом на сотни и тысячи единиц.

Такой подход позволил нам убрать обратную связь для тех, кто пытался подобрать параметры вызова API для «накрутки» голосов. Теперь им стало непонятно как отреагировала система на POST-запрос, сформированный вручную.

С точки зрения горизонтального масштабирования решение тоже отличное. Очередь Service Bus масштабируется горизонтально, а чтобы ускорить тяжелый разбор голоса, достаточно поднять несколько десятков сервисов обработки голоса. В Azure поднять несколько WebJob-ов можно как вручную парой кликов мышкой или в автоматическом режиме.

Есть технический нюанс, почему для сервиса обработки голосов мы выбрали WebJob, а не Service Fabric.

Для работы через Service Fabric под .NET Core нужно устанавливать SDK из специального репозитория Ubuntu. Это создает проблемы и при деплое и при разработке. А WebJob готов к работе с .NET Core без лишних движений.

Чистый PaaS

Весь проект сделали два наших разработчика за четыре недели. Получилось так быстро отчасти благодаря тому, что вся инфраструктура накликана мышкой в веб-интерфейсе Microsoft Azure — это чистый PaaS. Мы не создали и не настроили ни одной виртуальном машины.

Масштабирование вертикальное и горизонтальное тоже делалось мышкой.

Микросервисы

Хоть проект небольшой и микро-ответственностей всего три, но мы придерживались основных идей микросервисной архитектуры. В проекте мы выделили три микросервиса: обработчик голосов (сервис), приемщик голоса (API), формирователь контента (Web).

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

Если бы после обработки голоса мы хотели посылать девушке СМС с поздравлением, что за нее проголосовали, то на схеме появился бы еще один микросервис, подключенный к Service Bus. Этот микросервис потреблял бы события, которые для него формировали в момент завершения обработки голоса. Таким образом, архитектура расширяема почти бесконечно.

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

Результат


Скорость сайта

Сайт работает быстро и гладко, даже на мобильных. Весь контент кешируется в CDN, которая справилась с 5500 запросов в секунду. Кэширование в браузере, в CDN и в веб-приложении позволило 99,7% пользователей открыть страницу конкурса Мисс Россия менее, чем за одну секунду.



Гибкость нагрузки

За счет гибкости выделения мощностей в Azure стоимость новой инфраструктуры во время голосования (две недели в году) равна стоимости выделенного сервера под предыдущую версию сайта. Зато после голосования мы сняли ненужные мощности в пару кликов и стоимость стала в 3 раза дешевле.

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

Голосование

Голосование отработало 100% запросов, ни один пользователь не получил 500-ошибку. Из 750К голосов алгоритм отсеял примерно 500К в качестве ботов, а остальные голоса были зачтены девушкам.

Организаторы конкурса получали прозрачную отчетность о ходе голосования: кто и сколько голосов получил, кто пытался накрутить результаты.

Выводы

Грамотная архитектура позволила:

— Давать больше ресурсов на нагруженные части, меньше на ненагруженные.
— Убрать влияние частей системы друг на друга.
— Под каждую часть выделяются ресурсы только тогда, когда это требуется.

Дополнительные материалы по теме архитектуры:



Автор материала


Александр Бындю (@alexanderbyndyu) — Владелец компании Byndyusoft, эксперт в Agile и Lean, IT-архитектор.
Поделиться с друзьями
-->

Комментарии (68)


  1. Bonart
    28.04.2017 11:56
    +6

    С каких это пор собственно масштабируемость — "проблема монолита"?
    Неудачно спроектированное будет плохо масштабироваться независимо от "монолитности" или "микросервисности".
    Необходимость селективного горизонтального масштабирования, оправдывающего внесение дополнительных межсервисных коммуникаций, не показана.
    "Независимые" микросервисы с общей базой данных — это хуже монолита по построению, в такой конфигурации успешно объединены проблемы и устранены достоинства обоих подходов.
    Про "автономность" тоже одна реклама. Конечного пользователя (если он голосует) очень мало заботит тот факт, что при аварии с одним микросервисом другие продолжат работу.
    Проблема-то в том, что вариант использования с голосованием накроется медным тазом при отказе любого компенента, а значит про "независимость" речь не идет — даже при идеально пришитых пуговицах костюм все равно не айс.
    А механизм голосования, в котором пользователь сознательно дезинформируется про "ваш голос учтен" (а счетчики изменятся неизвестно когда) — чистейшая как слеза задняя дверь под произвольные накрутки от организаторов.


    Итого: статья вместо грамотной архитектуры демонстрирует недобросовестную рекламу.


    1. AlexanderByndyu
      28.04.2017 12:54

      С каких это пор собственно масштабируемость — «проблема монолита»?


      Горизонтальное масштабирование — это проблема монолита.

      Неудачно спроектированное будет плохо масштабироваться независимо от «монолитности» или «микросервисности»


      Это точно :)

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


      Каждый из трех сервисов масштабируется независимо горизонтально и вертикально. Чтобы увидеть необходимость приведу пример, когда у нас забилась очередь (Якутия активно пошла голосовать, они очень дружные) мы потянули ползунок и докинули сервисов обработки голосов.

      «Независимые» микросервисы с общей базой данных — это хуже монолита по построению, в такой конфигурации успешно объединены проблемы и устранены достоинства обоих подходов.


      Об общей базе я написал, видимо не достаточно подробно. В данном случае база это не совсем база. Это продажа юнитов к хранилищу. По сути в этом хранилище три «СУБД», но подписка на одну облачную «БАЗУ». Обновление и масштабирование можно сделать независимым, но для этого надо купить три подписки на облачную базу, что в случае этого проекта будет неоправданными расходами. А вообще мы обычно делаем каждому микросервису своё хранилище и DWH для аналитики по всем СУБД.

      Про «автономность» тоже одна реклама.


      Здесь что-то про эмоции, не понял вопрос.

      Проблема-то в том, что вариант использования с голосованием накроется медным тазом


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


      1. Bonart
        28.04.2017 13:21

        Горизонтальное масштабирование — это проблема монолита.

        Вообще-то… нет.
        Проблема монолита — селективное горизонтальное масштабирование, когда с одной стороны компоненты нагружены сильно неравномерно, а с другой — приходится платить за масштабирование всей системы.
        Соответственно, решение о выделении микросервисов должно иметь в основе именно такие данные — асимметрию загрузки сайта-валидатора-счетчика и дороговизну масштабирования всего этого целиком.
        Насколько я вижу, о таком анализе для конкурса "Мисс Россия" в статье ничего нет — только готовое решение.


        Каждый из трех сервисов масштабируется независимо горизонтально и вертикально. Чтобы увидеть необходимость приведу пример, когда у нас забилась очередь (Якутия активно пошла голосовать, они очень дружные) мы потянули ползунок и докинули сервисов обработки голосов.

        И насколько это дешевле по сравнению с (хорошо спроектированной) монолитной системой?


        Здесь что-то про эмоции, не понял вопрос.

        Давайте развернуто. Если я пользователь и я хочу проголосовать, то мне необходимо, чтобы все три компонента работали:


        1. Сайт
        2. Валидатор
        3. Счетчик
          Неработоспособность чего-то одного лишает меня голоса де-факто. И для меня как пользователю никакого толку, что все остальное работает.

        PS: жалко, что не стали отвечать про разрыв обратной связи — вы ее порвали не только и столько для ботоводов, сколько для обычных пользователей. Я голосую онлайн, мне сообщили что мой голос учтен, а счетчик не сдвинулся ни на миллиметр. То, что я подумаю про организаторов, немного предсказуемо.


        1. AlexanderByndyu
          28.04.2017 13:39
          -1

          селективное горизонтальное масштабирование, когда с одной стороны компоненты нагружены сильно неравномерно


          Это и имеется ввиду. Просто никто не говорит «селективное горизонтальное...».

          о таком анализе для конкурса «Мисс Россия» в статье ничего нет — только готовое решение


          Была надежда, что вы разберетесь с тремя простыми ответственностями на схеме, их границами и способами масштабирования. Пояснять подробнее не планировал.

          И насколько это дешевле по сравнению с (хорошо спроектированной) монолитной системой?

          Покажите мне хорошо спроектированную монолитную систему и я смогу сравнить.

          вы ее порвали не только и столько для ботоводов, сколько для обычных пользователей

          Видимо вам лучше знать что и зачем мы сделали. Не буду портить монолог.


          1. Bonart
            28.04.2017 16:29
            +1

            Была надежда, что вы разберетесь с тремя простыми ответственностями на схеме, их границами и способами масштабирования. Пояснять подробнее не планировал.

            Так ваша схема вполне понятна. Непонятно другое — каков мотив реализации именно на микросервисах.
            Старая система была неудачно спроектирована для имеющихся нагрузок.
            Это вы показали наглядно.
            Вы лучше спроектировали новую.
            Это вы тоже показали наглядно.
            А вот причины выбора именно микросервисной организации вы наглядно показывать не стали.
            Хотя это самый важный момент. Микросервисы недешевы и разрабочикам очень полезно знать, что их окупает.


            Покажите мне хорошо спроектированную монолитную систему и я смогу сравнить

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


            Видимо вам лучше знать что и зачем мы сделали.

            Я вполне доверяю вам по обоим пунктам:


            1. Вы делали это против ботоводоства
            2. Вы достигли по этому параметру хорошего результата

            Но с другой стороны страно так остро реагировать на неизбежное следствие вашего решения — пользователи тоже потеряли обратную связь со всеми вытекающими.


            1. AlexanderByndyu
              28.04.2017 17:54
              +2

              Непонятно другое — каков мотив реализации именно на микросервисах.


              Коротко описал в статье, вот выдержка:

              Для новой архитектуры мы взяли за основу идеи, которые бы привели к достижению бизнес-целей:

              1. Разделить приложение на (микро)ответственности.
              2. Каждая часть будет идеально выполнять свою роль.
              3. Каждая часть будет сама заботиться о масштабировании.
              4. Тотальная автоматизация.


              Более длинно в другой статье в блоге по более глобальному проекту http://blog.byndyu.ru/2016/11/it.html. Понятно, что конкурс не имеет много бизнес-логики, но три части четко выделялись из монолита, что мы и использовали.

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


              Это точно! Одна из причин почему мы выбрали микросервисы — у нас есть достаточный опыт, чтобы силами двух человек за 4 недели переделать весь проект на новую архитектуру. Если мы только читали о микросервисах, то переход на них был бы более рискованный, чем дробление легаси-монолита.

              довод в пользу хорошего проектирования, а не микросервисов


              Да, именно так. Перед нами стоял выбор: дробить старую систему или написать всё заново. У менять не иллюзий на тему «давайте перепишем всё с нуля!!!111111», подробно на эту тему писал здесь http://blog.byndyu.ru/2014/01/blog-post_8.html. Скажу больше, обычно мы не переписываем всё с нуля, т.к. это рисковано и экономически неоправдано. Но конкретно в этом случае мы посчитали, что надо переписывать всё с нуля. Причин было много: плохая архитектура, очень слабо написан front-end, CMS и, самое главное, не много бизнес-логики.

              пользователи тоже потеряли обратную связь со всеми вытекающими


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


  1. mihmig
    28.04.2017 11:56

    >>Когда человек голосует, ему всегда отвечают: «Спасибо, Ваш голос учтен!». В этот момент формируется сообщение о голосе, сообщение отправляется в очередь…
    Сообщение неправильное, т.к. в этот момент голос не учтён, а только принят…


    1. AlexanderByndyu
      28.04.2017 12:58

      Что предлагаете? Рассказать пользователям, что их голос отправлен в очередь? :)

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


      1. Bonart
        28.04.2017 13:35
        -4

        Выкинуть очередь и обновлять счетчик онлайн не комильфо?


        Сравним:


        «Ваш голос учтён и появится на сайте в ближайшее время, спасибо за участие в голосовании!»

        Их голос будет учтен в среднем в течение 15 секунд, а счетчик сайта обновится через час

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


        1. Lailore
          28.04.2017 13:54
          +6

          реальные онлайн последовательные счетчики под нагрузкой это ппц какое узкое горлышко


          1. AlexanderByndyu
            28.04.2017 13:55

            Аминь :)


          1. Bonart
            28.04.2017 16:34

            Это реальное оправдание для видимого учета голоса пользователя только через час?


            1. AlexanderByndyu
              28.04.2017 17:55

              Реально описал выше в комментарии. Если коротко: программный комитет конкурса дал на это разрешение и сказал, что на пользователей это никак не повлияет. Мы тоже не увидели проблем с этим решением и сделали так как сделали.


            1. aftertherainbow
              28.04.2017 22:33
              +1

              Скажите, а то что ютуб просмотры подсчитывает не в реальном времени, вас также возмущает?


              1. Bonart
                29.04.2017 18:05
                +1

                С чего вы взяли что меня что-то возмущает?
                Александр дал в своих комментариях исчерпывающий ответ: заказчика (оргкомитет) в данном вопросе удобство пользователей не заботило, а по другим критериям принятое решение вполне удачное.
                У ютуба подсчет количества просмотров — не основная задача, в отличие от конкурса с голосованием. Если бы ютуб видео по ссылке начинал показывать примерно через час после перехода на страницу — это было бы сравнимо.


                1. aftertherainbow
                  29.04.2017 22:34

                  Вы говорите правильные вещи, но делаете неправильные выводы.

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

                  И удобство для пользователей тут — это уверенность, что кандидат, за которого ты голосовал — победил или проиграл честно.


                  1. Bonart
                    30.04.2017 12:54

                    Не отобразить их сразу, а обеспечить целостность и достоверность.

                    Это интерес не пользователя, а оргкомитета. А для живого человека самые неприятные интерфейсы — медленные без обратной связи. Именно такой и был сделан.
                    Иногда число голосов не показывают специально — люди склонны отдавать свой голос одному из лидеров гонки и без знания текущего положения голосование будет точнее. Но к текущему решению это не относится.


                    Есть еще один вид заинтересованных лиц — сам оргкомитет. И абсолютно непрозрачная для пользователя схема подсчета с неверной информацией об учете голоса по построению — широчайший простор для манипуляций. И даже если считать оргкомитет женой Цезаря (закрыв глаза на комментарии inkvizitor68sl) всегда остаются ложноположительные срабатывания бот-детектора, которые благодаря разрыву обратной связи теперь определить гораздо сложнее.


          1. zoonman
            29.04.2017 07:27
            +1

            А можно по-подробнее? В чем это заключается?


            1. AlexanderByndyu
              29.04.2017 08:13

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

              Если счет не надо обновлять в реальном времени, то можно использовать CQRS, чтобы отдельно обновлять счетчик, отдельно его показывать. Показывать с допустимой задержкой (eventually consistent), зато дешево масштабировать на любую нагрузку.


              1. zoonman
                29.04.2017 09:06

                Я тут на коленке посчитал, у вас было 970000 посетителей в сутки. Даже если все они пришли в течение 8 часов и все проголосовали, это 34 запроса в секунду. У меня на текущей рабочей базе данных с объемом в 1ТБ идет примерно 300 запросов в секунду с пиками до 2000 и отдачей данных в режиме реального времени. Но это MongoDB, что более чем вписывается в вашу бизнес-модель.
                Правильная реализация позволила бы получить этот же рейтинг с обновлением в режиме реального времени.


                1. aftertherainbow
                  29.04.2017 11:23
                  +1

                  Вы только забыли включить в ваши расчёты затраты на обработку запроса и понимание накрутка это или нет. То что у вас там 300 select'ов в секунду совсем без разницы, если условно 5 секунд уходит на осознание того, что голосовал реальный пользователь, который не голосовал до этого.


                1. AlexanderByndyu
                  29.04.2017 11:33

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

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

                  Решение получается железобетонное и дешевое в разработке и поддержке. По сути разрабатывать и настраивать нечего, кроме самого алгоритма отсева.

                  Еще раз повторю, что подходов может быть много, но в данном случае самые простой и надежный представлен на нашей архитектуре.


    1. AlexanderByndyu
      28.04.2017 13:05

      Вот точный текст ответа: «Ваш голос учтён и появится на сайте в ближайшее время, спасибо за участие в голосовании!»


      1. Bonart
        28.04.2017 13:23
        -5

        И как же переводится на язык пользователя "в ближайшее время"?


        1. Schvepsss
          28.04.2017 13:31
          +3

          Вы конечно простите, но на вкус и цвет все фломастеры разные. И подобные придирки выглядят очень странно.

          А что значит фраза «в ближайшее время»? Кстати, а как это переводится на язык майя? Ну вдруг кто-то из племени будет тоже голосовать.


          1. Bonart
            28.04.2017 13:40
            -5

            Почемы вы обычные требования пользователя к системе онлайн-голосования называете придирками?
            Учтите, после былинных отказов вроде "Имя Россия" или "Премии рунета" априорного доверия к организаторам любых голосований давно уже нет.
            Специфика данного конкретного конкурса только добавляет голосующим скепсиса. А в нюансах микросервисности, очередей и ботоводства обычный пользователь разираться не обязан.


            1. Neftedollar
              29.04.2017 04:09
              +1

              Но ведь требования к системе выставляет заказчик. А пользователь системы либо системй пользуется либо нет. Ваш вопрос, очевидно, к заказчику.


              1. Bonart
                29.04.2017 18:22
                +1

                На момент написания комментария Александр еще не дал полного ответа.
                Из текста самой статьи никак не следовало, что удобство пользователей на самом деле заказчика не волновало совсем, а исполнителя — только в рамках договора с заказчиком.
                В любом случае сообщение, выдаваемое системой пользователю, явно расходится с действительностью.


  1. ChiefPilot
    28.04.2017 12:04
    +1

    Это вы зря с девушками… Невозможно прочитать статью, когда сначала быстро пролистываешь её вниз, ища обещанные фотографии, а потом не находишь их и уходишь расстроенный. :) (девушек, если что, во Вконтакте вроде как обещали — я оттуда сюда пришёл :))


    1. Schvepsss
      28.04.2017 12:38
      +2

      Я тут нашла их сайт, там точно больше фотографий, чем вместит в себя эта статья. :) Рекомендую.


      1. AlexanderByndyu
        28.04.2017 12:42
        +1

        Еще есть видео с конкурса, они там в купальниках ходят https://youtu.be/JvjXXVRtqEM?t=56m50s


  1. starshov
    28.04.2017 12:21
    +1

    Александр а что Вы использовали для нагрузочного тестирования?


    1. AlexanderByndyu
      28.04.2017 12:46
      +3

      Яндекс.Танк https://tech.yandex.ru/tank/


    1. inkvizitor68sl
      28.04.2017 14:48
      -2

      https://overload.yandex.net/ + yandex.tank

      И «предыстория» в статье — враньё.


  1. neol
    28.04.2017 14:32
    +1

    CMS «Плеск»

    А можно поподробнее про этого зверя? Plesk всю жизнь был админ панелью для хостинга и про одноимённую CMS не нашлось никакой информации ни в google, ни на сайте по ссылке.


    1. AlexanderByndyu
      28.04.2017 17:59

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


  1. inkvizitor68sl
    28.04.2017 15:01
    +6

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

    > Сайт хостился на выделенном сервере. Добавление железа в сервер перестало приносить пользу. Когда заказчик провел нагрузочное тестирование, сайт упал на 150 запросах в секунду.

    Ребят, вы вконец охренели со своим пиаром. Миссрашка жила последние 3-4 года на обычной железке с 32G RAM и никто никогда не жаловался на «500 и не работает голосование». И железа туда никто никогда добавлять не пытался — один черт, никогда близкой к 150 RPS цифры там реальной нагрузки не было. И да, если «старую архитектуру» залили бы нормальной железкой — то держала бы она и 300, и 500 RPS (после некоторой настройки), эти цифры покрывают необходимый запас ещё на много лет вперед.

    Вот что переписали это дерьмо мамонта — это вы молодцы, правильно сделали, без нового кода там делать нечего было. Но вот утверждать, что ваши соседи по индустрии лаптями едят — это вы зря. Мир тесен.


    1. Bonart
      28.04.2017 16:40
      +1

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


    1. AlexanderByndyu
      28.04.2017 18:03
      +1

      если «старую архитектуру» залили бы нормальной железкой


      Добавить железку… :) Именно такого решения и ждали заказчики? Текущая стоимость в 3 раза дешевле, чем тот сервер, который якобы держал нагрузку и проблем не вызывал.

      Ребята, ну серьезно, заказчик забрал у вас контракт не потому что всё было круто, быстро и все были довольны. Разве не так?

      Но вот утверждать, что ваши соседи по индустрии лаптями едят


      Где такое было? Жду цитату из статьи и готов взять свои слова обратно, если там есть оскорбление.


      1. inkvizitor68sl
        28.04.2017 19:39
        -2

        > Именно такого решения и ждали заказчики?
        Нет, они ждали новомодных словечек в своём проекте и получили то, что хотели — Ажур при том же количестве ресурсов на бумаге медленнее железа.

        > Добавить железку… :)
        Не добавить, а заменить. Вы же пишете — «Добавление железа в сервер перестало приносить пользу. ». Никто его туда никогда не добавлял, не планировал, а самое главное — не задумывался об этом, ибо не нужно. Ну а я, в свою очередь, утверждаю, что замена железа на более производительное принесла бы огромную пользу к нафиг никому не нужным цифрам в лице теоретического максимума rps.

        > Жду цитату из статьи и готов взять свои слова
        Например вот — «Во время конкурса пользователи постоянно жаловались, что страницы медленно открываются, отдают 500-ошибку и не работает голосование».
        Или вот — «якобы держал нагрузку».

        > Текущая стоимость в 3 раза дешевле,
        Хватит врать, серьёзно. В полтора раза дороже ваша S1 в месяц, чем то, что использовалось.

        Давайте немного в цифрах. Самый-самый пик запросов в php в 2016м в течении секунды — что-то в районе 80 rps. А вообще нагрузка в день конкурса держалась в промежутке 10-20 rps. Обе цифры выглядят меньше 150, не? Или у меня проблемы с математикой на уровне второго класса?
        Пятисоток там тоже в 2016м не было.

        > заказчик забрал у вас контракт не потому что всё было круто
        Мы можем поговорить про корпоративные за*бы, наверное, но не стоит. А то мы сейчас будем выяснять, у кого из корпов кончились деньги. Переписывать проект нужно было, опять делать это на php было глупым вариантом в 2017м. Так что молодцы, что переписали на современных технологиях и наконец-то задумались об оптимизации фронта.

        Но вот утверждать, что оно «плохо работало раньше и падало во время конкурса» — это наглое враньё. Оно работало как работало, во время конкурса и в обычные дни — да, не очень шустро из-за кода и верстки родом из 2008го, но ничуть не медленее, чем обычно. И несмотря на необходимость переписать всё к чертям, старое решение прожило достаточно долго для такого уровня проекта и имело хороший запас по мощности и возможности расти по цифрам дальше.


        1. AlexanderByndyu
          28.04.2017 21:10

          Я понимаю, что не приятно читать о своей работе в таком ключе. К сожалению, с этим в данный момент уже ничего нельзя сделать.

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


          1. Bonart
            29.04.2017 18:26

            Всё, что написано о «прошлом» проекта я знаю со слов организаторов. Видимо так они видели предыдущее сотрудничество

            В сочетании с их реальным отношением к голосам пользователей картинка складывается не особо приятная.


    1. aftertherainbow
      28.04.2017 22:26
      +1

      на обычной железке с 32G RAM

      это шутка?


      1. inkvizitor68sl
        29.04.2017 21:47
        -2

        Что именно?
        32 гигабайта памяти стоят сейчас 10-12 тысяч. А арендовать сервер с 32G можно на 35 EUR. В ходу сейчас сервера с 256-512G памяти.


        1. aftertherainbow
          29.04.2017 21:58
          +2

          Да тут вопрос не в цене. Я про то, что у того же Azure S1 всего 1.75GB.
          Вы используете такого монстра, который явный оверкил для данной задачи и говорите, что нужно ещё добавить железа. 512 GB которые с трудом будут тянуть 150 запросов? Это инженерное решение?


          1. inkvizitor68sl
            01.05.2017 21:57
            +1

            Вы как-то очень интересно по диагонали читаете. Давайте я вам по порядку объясню.

            1) Сервер с 32G RAM (и каким-то там процессором из разряда «обычных») стоит дешевле виртуалки в azure с 1.75G RAM. Как в аренду, так и если его купить и поставить в стойку (из расчета, что он будет использоваться 3-4+ года).
            2) Железка с 32G ram справлялась с пиковой нагрузкой (в аж целых 80 RPS, да), а виртуалка в azure за бОльшие (или примерно те же) деньги, судя по статье — нет.
            3) Сравнивать абсолютные значения RPS старенькой CMS на php и свежего оптимизированного под конкретный проект кода — мягко говоря, некорректно.
            4) сервера c 32G сейчас являются игрушкой для стажеров, а не «монстром» в IT-компаниях. Возможно, в мире махрового ынтерпрайза это не так. Повторюсь, RAM сама по себе не стоит ничего. Каких-то денег стоят серьёзные процессоры, но его там нет и не было (e5540, что ли или похожий).
            5) в действительно высоконагруженных проектах на данный момент закупаются/арендуются сервера с 256G+ RAM (при условии наличия соответствующих процессоров в ноде). Сервера со 128G отправляются в девелопмент или вроде того, а сервера с 32G уже года 3 как распродаются такими проектами за бесценок (потому что утилизация стоит приличных денег).
            6) что добавлять железо нужно было в MR — я как раз не говорил. Про это почему-то в статье говорят (почему — думаю, юристы разбираться будут, кто и что кому сообщил. Сами владельцы проекта не в курсе, что у них, оказывается, что-то раньше падало).
            7) Даже если и добавлять железо — то менять процессор, а не память.

            Впрочем, посыл «Это инженерное решение?» вы зря так саркастично употребили. Многие проблемы забрасываются железом ровно потому, что так дешевле. За зарплату хорошего разработчика можно амортизировать/арендовать 20-30 хороших железок. А за удивившие вас 32G памяти в сервере можно разве что один раз в паб вдвоём-втроём хороший сходить.


            1. aftertherainbow
              02.05.2017 12:22
              +2

              Спасибо за развёрнутый ответ. Прошу прощения, если задел вас.


            1. AlexanderByndyu
              03.05.2017 05:59

              Очевидно, что в облаке вы платите не за железки, а за SLA и готовые инструменты для администрирования, логирования, масштабирования и т.д.

              За зарплату хорошего разработчика можно амортизировать/арендовать 20-30 хороших железок.


              Чтобы железки превратить в нечто полезное, нужны те самые дорогие инженеры. Вместо этого можно взять PaaS (любой, не обязательно Azure) и заниматься только бизнес-задачами, что мы и сделали.


  1. kxl
    28.04.2017 19:12
    +2

    750К за две недели… хм… А в пике за минуту сколько было?


    1. inkvizitor68sl
      28.04.2017 19:40
      -1

      " что-то в районе 80 rps. А вообще нагрузка в день конкурса держалась в промежутке 10-20 rps. "
      с 2016 цифры. Вряд ли в этом году больше.


    1. AlexanderByndyu
      01.05.2017 16:30

      Пиковая нагрузка на веб около 2К rps, на голосование 500 rps. Нагрузка распределена ооочень неравномерно в течение 2х недель, пока идет конкурс.

      Бывает так, что люди, которые поддерживают девушек устраивают флешмобы. Или популярные девушки (по 40К подписчиков) просят за них голосовать. Или любители покупки голосов размещают объявления о накрутках (мы отсеяли 500К бото-голосов из 750К общих). Тогда начинает нагружаться голосование. А нам надо в конце дня предоставлять отчет по накруткам и показывать сколько откручивали. Алгоритмы и хитрости отсева не rocket-science, но требуют ресурсов.

      При этом проходят пресс-релизы, девушки ездят на мероприятия и т.п. В этот момент много народу (2К rps) приходят смотреть фоточки, новости и т.п. на сайте.

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


  1. aftertherainbow
    28.04.2017 22:11
    +1

    Здравствуйте, ребята, отличная статья, спасибо.

    Несколько моментов, которые я не очень понял.
    «Выбирали очередь между Service Bus и Storage Queues» по требованиям вроде бы и 2е подходит, или я чего-то не знаю?

    У вас и для api и для сайта я так понимаю был .net core. Kestrel использовали в обоих случаях с iis в качестве прокси или чистый?


    1. AlexanderByndyu
      02.05.2017 08:58

      Извините за долгий ответ, все были в отпусках, а я сам не вспомнил точную причину :)

      «Выбирали очередь между Service Bus и Storage Queues» по требованиям вроде бы и 2е подходит, или я чего-то не знаю?


      Модель работы Service Bus Queues выглядит надежнее, чем у Storage queues, а именно больше гарантий при доставки сообщений (At-Least-Once и At-Most-Once), более надежная блокировка (Peek & Lock или Receive & Delete). Также нет ограничений на время хранения сообщений. Ограничение на сообщение в Storage queues — 64 KB, а в Service Bus Queues — 256 KB or 1 MB.

      Сам по себе Service Bus больше похож на очереди, а Storage Queues это скорее некое расширение обычного хранилища. Более подробно https://docs.microsoft.com/en-us/azure/service-bus-messaging/service-bus-azure-and-service-bus-queues-compared-contrasted.

      У вас и для api и для сайта я так понимаю был .net core. Kestrel использовали в обоих случаях с iis в качестве прокси или чистый?


      В WebApp использовали Kestrel, IIS руками не трогали. Видимо он где-то есть глубоко в Azure, чтобы балансировать, если кол-во инстансов увеличивается.


  1. DarWiM
    28.04.2017 22:11
    +1

    Благодарю за статью.
    Было бы интересно почитать о том, как вы боролись с накруткой.


    1. AlexanderByndyu
      29.04.2017 05:11

      Спасибо.

      Могу рассказать только о том, что видно на сайте, но не о внутренних алгоритмах отсева, иначе этим воспользуются люди, которые продают накрутки. Попробуйте поискать «накрутка голосов мисс россия», например, есть вот такие ребята http://jet-s.ru/blog/konkurs-miss-rossija-pomozhem-vyigrat. Кроме них мы видели с десяток видео, как формировать POST-запросы к предыдущим формам голосования.

      О видимых способах отсева:

      • Убрали обратную связь при голосовании. Это лишает тех, кто тыкает в сайт понимания работает их способ или нет. Они посылают запросы и мы всегда отвечаем, причем мгновенно, что их голос будет учтен. Если бы счетчик обновлялся сразу, то подобрать способ обхода защиты было бы проще.
      • Проверка по IP. Это, конечно, очень простое ограничение, но не бесполезное.
      • Recaptcha. Да, мы все знаем о сервисах ручного «взлома» любой капчи :)
      • Аутентификация через аккаунт в соц. сети. Да, мы в курсе, что аккаут в соц. сети стоит 3-5 рублей за штуку.
      • «Магия» анализа на клиенте и на сервере, здесь подробностей не будет


  1. Benedict
    29.04.2017 00:10
    +1

    А не пытались вместо очереди для голосов рассматривать какое-то im-memory хранилище? Навскидку кажется что для такой нагрузки должно быть более чем достаточно


    1. AlexanderByndyu
      29.04.2017 05:14

      Вполне можно было взять и in-memory хранилище. В нашем случае мы взяли очереди, потому что они логически подходят под задачу, поднимаются кликами мышкой и стоят $10 в месяц :)


  1. Benedict
    29.04.2017 00:39
    +1

    Единственная неприятная проблема возникла с Kestrel, который под нагрузкой начинал отвечать кодом 502.3. При этом приложение падало и не оживало до перезапуска.

    Проблема была в версии Kestrel версии 1.1.0. Описание в Issue323 и Issue311. Нам повезло, что за две недели до начала конкурса вышел пакет Microsoft.AspNetCore.Server.Kestrel версии 1.1.1 и проблема ушла..


    По мне так очередной показатель того что AspNet Core сырой. А если бы не вышел апдэйт, чем бы ваше решение было бы лучше предыдущего в том плане что страницы
    отдают 500-ошибку


    1. AlexanderByndyu
      01.05.2017 16:29

      Речь о Kestrel, а не ASP.NET Core. Если бы апдейт не вышел, то мы переключились бы на IIS за 10 минут.


  1. julie
    29.04.2017 14:01
    +1

    Контент грузится раза в три быстрее чем в остально интернете по ощущениям. Круто!


    1. AlexanderByndyu
      29.04.2017 14:38

      Спасибо! Это при том, что мы снизили производительность на 2/3, т.к. конкурс уже закончился и пора начать экономить деньги заказчика :)


  1. sergey-b
    29.04.2017 17:18
    +1

    Скажите, сколько по трудозатратам ушло на адаптивную переверстку сайта?


    1. AlexanderByndyu
      29.04.2017 18:38

      Сложно выделить переверстку от всего процесса разработки. Но если грубо разделить весь проект на бэк и фронт, то можно сказать, что на переверстку ушло 4 недели, из которых 1,5 недели ушли на бэкофис (закрытая часть сайта).


  1. groaner
    30.04.2017 22:12
    +2

    Немного критики в подкасте Радио-Т (с 52 минуты) — https://radio-t.com/p/2017/04/29/podcast-543/


    1. AlexanderByndyu
      01.05.2017 07:31

      Спасибо за ссылку! Поржал от души. Меня обвинили во всем, что только можно :) Написал им комментарий https://radio-t.com/p/2017/04/29/podcast-543/#comment-3282714877


      1. zesetup
        01.05.2017 20:26

        Вы надолго останетесь в истории, как человек не сумевший обосновать свой профессионализм Умпутуну ;-).
        Вам остались часы для адекватных ответов.


        1. AlexanderByndyu
          01.05.2017 20:50

          Если честно я не в теме кто этот Умпутуну и почему остались часы. К сожалению, автор подкаста живет в кокане, на пробивание которого у меня нет времени.


        1. AlexanderByndyu
          05.05.2017 18:07
          +1

          Извинился, выдохнул и написал развернутый комментарий по архитектуре https://radio-t.com/p/2017/04/29/podcast-543/#comment-3287936617 и по тезисами из подкаста https://radio-t.com/p/2017/04/29/podcast-543/#comment-3288429755.