One Ring to rule them all
J. R. R. Tolkien «The Lord of the Rings»
Введение
Все чаще наши клиенты обращаются в ИНТЕРВОЛГУ с запросом на комплексную масштабную работу над проектом. Мы не удивляемся этому: время небольших доработок, «перекрашивания» кнопок и починки страничек прошло.
В последние несколько лет средний и крупный бизнес стремится превратить сайт в многофункциональный инструмент для взаимодействия с партнерами и клиентами. И желательно — единственный инструмент. Все чаще нас просят добавить «пару отчетиков для партнеров», программу лояльности и биллинг прямо на сайте. Позже выясняется, что отчеты — это не SUM и GROUP BY по табличке заказов, а ТЗ на десять страниц с дифурами и прочим матаном, программа лояльности должна учитывать лайки в соцсетях, а биллинг должен быстро работать в реальном времени. Под капотом у таких функций — масштабные вычисления, к которым традиционный веб-сайт просто не готов.
Значительные подсчеты требуются и для интернет-магазинов федерального масштаба. Их отличия от обычного ИМ:
Работа по всей России: GeoIP, многоскладовость и прочие вытекающие (а не один-два города)
Десятки миллионы товаров и SKU, а не десятки тысяч
Лихо закрученное, как лента Мебиуса, ценообразование (а не две цены: «Опт», «Розница»)
Магазин-маркетплейса (продажа чужих товаров с партнерской комиссией)
Десятки интеграций с разными учетными системами (и ни одной 1С!)
И, разумеется, чтобы работало быстро.
Как же сделать тяжелые вычисления вебе и не уронить сервер? За последние 5 лет мы ни раз сталкивались с подобными проектами.
Как увеличить производительность веб вычислений
В обоих случаях (личные кабинеты и федеральные интернет-магазины) требуется быстро оперировать большими объемами данных. Наращивание мощностей веб-сервера помогает до поры до времени. Веб как технология никогда не был сверхскоростной средой для громоздких вычислений. На то есть несколько причин:
Язык разработки. PHP, Ruby, Python многократно проигрывают компилируемым языкам в производительности.
Протокол HTTP. А конкретно — понятие таймаута. Считать на лету слишком долго не получится, рано или поздно серверу нужно будет оборвать соединение и браузер покажет ошибку ожидания ответа. Спасает пошаговое выполнение процедуры, но не всегда.
Особенности ПО. Повсеместные apache и nginx успешно справляются с умеренно большим потоком пользователей, если запросы простые и отрабатывают быстро. Отдать 10 000 раз главную страницу — не проблема. А вот вычислить 10 000 балансов на лету уже не так весело.
Очевидный вариант — переложить тяжелую работу с сайта на учетную систему. УС действительно эффективнее при решении сложных задач, но они не рассчитаны на ту нагрузку, которую создает посещаемый веб-сайт. Получается конфликт: сайт считает медленно, но для тысяч пользователей, а УС — быстро, но для пяти-десяти. У нас был опыт с проектами обоих типов.
Наш вывод — ни одна из этих систем не должна заниматься постоянными тяжелыми вычислениями. Откладываем в сторону бритву Оккама и начинаем проектировать промежуточное ПО (связующее ПО или middleware). Middleware примет на себя основную нагрузку.
Пожелания к middleware:
Работа на отдельном (от сайта и УС) сервере;
Современный, распространенный язык программирования и фреймворк.
Надежный подрядчик.
В простом случае промежуточное ПО можно разработать на базе более упрощенных систем (отдельная копия, разумеется). Но если критична скорость ответа и выживаемость под высокой нагрузкой, лучше написать отдельный софт, например на Java (быстрый и современный язык), которая по скорости не уступает C/C++.
Рассмотрим более сложную задачу. Сколько middleware потребуется для такой инфраструктуры проекта?
Как ни странно, понадобится только один новый узел.
Развитие идеи middleware для большего количества IT-систем называется ESB (enterprise service bus — сервисная шина предприятия). Иногда этот подход называют интеграционной шиной или шиной данных. Как и промежуточное ПО в случае с двумя системами, это не какой-то конкретный продукт или фреймворк, а подход, призывающий совершать все транзакции между IT-системами в единой точке.
Существует паттерн проектирования, реализующий эту же логику с той же целью. Это Медиатор (Mediator). Он выступает посредником между различными классами, предотвращает прямое взаимодействие и способствует ослаблению связей в коде. Элементы системы не знают о существовании друг друга, только о существовании Медиатора. Согласитесь, очень похоже на определение middleware и интеграционной шины?
Но чем же, в таком случае, должны заниматься учетная система и сайт, если всю тяжелую работу выполняет middleware? Сайт становится простой «болванкой»? Не совсем. Мы снимаем с сайта только самые тяжелые операции, для которых он не пригоден по определению. Для всего остального он по прежнему — лучшее решение
Сайт как «фронт»:
выводит чистые данные клиенту,
красивый и удобный,
собирает пользовательские данные из форм,
отправляет письма и СМС (не маркетинговые рассылки, а разовые уведомления),
готовит запросы к middleware,
выводит вычисленные результаты.
Middleware:
чистит данные от мусора, ( intervolga@gmail.ru -> intervolga@gmail.com )
удаляет то, что невозможно очистить (intervolga@.ru),
стандартизирует данные (а в вашей CRM номера клиентов через «+7», «7» или «8»?)
сопоставляет товары, статусы, адреса («г. Москва» и «гор. Москва»),
ведет учет остатков,
взаимодействует с десятком учетных систем,
производит инкрементальные расчеты для ускорения типовых запросов.
Учетная система как «бэк»:
биллинг,
учет транзакций,
расчет баланса,
складской учет,
вычисление персональных цен.
Кейсы с конкретными задачами
Кейс 1. Отчеты в реальном времени
Задача
Строить отчеты партнеров на сайте
Правильное решение
Каждый день middleware подводит промежуточный итог за прошедший день для каждого партнера по всем отчетам.
Сайт не строит отчеты, только собирает заявки и ставит их в очередь.
Из очереди заявки на отчет попадают в middleware, которое и ведет расчеты по своей копии данных из УС. Middleware считает только статистику за сегодняшний день, за предыдущие уже все посчитано.
Middleware передает сгенерированные данные в виде готового PDF/DOC/XLS на сайт.
P.S. Приведенный сценарий хорош если в вашей учетной системе запрещено редактировать первичку задним числом. В противном случае алгоритм усложняется.
Кейс 2. Персональные цены
Задача
На каждый товар B2B интернет-магазина практически у каждого пользователя своя скидка/наценка. Как результат — своя цена. Учетная система писалась чуть ли не во времена СССР, скидки зависят от двадцати параметров и никто не может объяснить, как оно работает.
Правильное решение
Учетная система выгружает на сайт товары с базовой ценой (максимальная цена без скидок).
При открытии страницы сайт отображает базовые цены товаров. По ним же происходит сортировка и фильтрация. Этот результат можно закешировать.
Параллельно сайт запрашивает из middleware цены для нужных товаров для текущего пользователя. Сайт отображает цены.
Кейс 3. Участие в акции компании с филиалами
Задача
В B2B портале производители размещают акции для компаний-дистрибьюторов (купи X товаров по цене Y в количестве Z в каждый магазин и получи бонусы). Пользователи портала — холдинги и дистрибьюторы могут прямо на сайте принять участие в акции. Если холдинг решает принять участие в акции — то в акцию автоматически должны вступить все дочерние компании со всеми магазинами. Но не у всех компаний заключен договор с производителем. Даже если и заключен, в договоре могут быть ограничение на минимальное/максимальное количество товаров, которые компания может купить у производителя.
Задача: при подписке холдинга на акцию подписать все допустимые компании, рассчитать сумму сделки и ожидаемые бонусы за участие в акции.
Правильное решение
Вся нужная информация для вступления в акцию доступна в middleware. Хороший вариант — master-slave репликация БД (потребуется только чтение и всегда актуальные данные).
При вступлении холдинга в акцию сайт добавляет задание в очередь для middleware.
Из очереди задания попадают в middleware. Middleware проверяет наличие договоров и их условия, запоминает рассчитанные данные и возвращает результат на сайт (сумма сделки, плановые бонусы).
Сайт отображает результат вступления.
При изменении состава холдинга или других первичных данных middleware должен пересчитать и обновить ранее запомненные данные. Тогда следующий запрос от сайта выполнится значительное быстрее.
Кейс 4. Десятки учетных систем
Задача
Для проекта типа «маркетплейс» требуется собирать номенклатуру у десятков (в перспективе — сотен) партнеров и отображать на сайте. Оформленные на сайте заказы отправлять обратно в УС каждого партнера отдельно. Заранее неизвестно, какое ПО будет у партнера и в каком формате будут предоставлены данные о товарах и заказах. Товары у партнеров примерно одинаковые.
Правильное решение
ESB собирает товары в единую базу и выполняет сопоставление товаров с единым справочником (по артикулам, характеристикам, штрих кодам и т.д.).
ESB анализирует цены от разных поставщиков. Если 9 разных партнеров предлагают товар за 10000 рублей, а 10-ый за 100 — возможно, сопоставление произошло некорректно и показывать такой товар на сайте нельзя.
ESB готова обмениваться с учетными системами партнеров по самым простым протоколами в ручном режиме. CSV и YML для товаров, CSV и CommerceML 2 для заказов.
Заключение
Сделать интеграцию нескольких IT-систем можно по-разному. Если вы хотите, чтобы результат был масштабируемым, чтобы увеличение объема данных в два раза не увеличивало тормоза сайта в два раза, обращайтесь к нам. Каждую задачу нужно решать правильными инструментами. 1С для учета и сотрудников. Сайт для UX. Промежуточное ПО для «грязной» работы.