Всем привет! Меня зовут Юра Буйлов, и я отвечаю за разработку в CarPrice. Компания развивается динамично, поэтому скорость проведения экспериментов для нас играет важную роль. Сегодня хочу рассказать о простом инструменте, который избавляет разработчиков от бесконечного потока простых однотипных задач по интеграции с внешними сервисами.
Мотивация. Почему Huginn
Рынок изобилует сервисами, позволяющим менеджерам строить простые цепочки действий, например:
- поступила жалоба от клиента
- зафиксировать факт в журнале
- отправить сообщение в Telegram
Мы уже активно использовали Zapier для подобных задач, но нам важны self-hosting, масштабируемость и отсутствие ограничений по количеству обрабатываемых задач. Так мы стали искать инструмент для простых и быстрых интеграций, который был бы полезен и менеджерам, и разработчикам. Сам подход не нов и напоминает упрощенную реализацию EIPs (Enterprise Integration Patterns). Естественно, мы попробовали несколько решений из мира “кровавого энтерпрайза” (Mulesoft, Jboss Fuse, WSO2, Servicemix, Corezoid). Вели переговоры с вендорами проприетарного ПО. Все не то: долго, дорого, сложно или неудобно.
Так мы пришли к Huginn.
- OpenSource – более 16k звёзд на github.
- Написан на RoR – можно дорабатывать и писать свои компоненты.
- Легко разворачивается и масштабируется.
- Имеет низкий порог вхождения.
Где использовать Huginn
Для капитальной интеграции мы используем RabbitMQ с адаптерами для каждого сервиса, критичного для работоспособности системы.
Настроен мониторинг размера очередей, доступности сервисов и работоспособности компонент. Однако вносить изменения и поддерживать документацию в актуальном состоянии в такой схеме накладно.
Huginn же используем для экспериментов и простых быстрых интеграций без высоких требований к надежности:
- публикация аукционов во внутренний Telegram-канал,
- триггерные уведомления: жалобы, нарушения, пики и просадки в метриках,
- пуш данных во внешние системы, такие как exponea, expertsender или piwik.
Что такое Huginn
Изначально Huginn – это платформа, которая задумывалась для запуска агентов, которые выполняют ваши задания в интернете. Парсят странички, отслеживают события и выполняют действия от вашего имени. Агенты создают и принимают события, передавая их друг другу по цепочке.
Huginn предоставляет множество встроенных агентов, которые мы можем использовать как настраиваемые элементы своего Pipeline. Агенты могут запускаться по расписанию или принимать события от других агентов, обрабатывать и передавать результат дальше по цепочке.
- Webhook Agent – принимает POST запросы от внешних источников.
- Post Agent, Website Agent – отправляет запросы на указанный урл, парсит JSON, HTML или XML.
- DeDuplication Agent – не пропускает дубли событий по уникальному ключу.
- Event Formatting Agent – позволяет перемапить поля в сообщении.
- JavaScript Agent – выполняет произвольный JS код (V8, therubyracer).
Для полноценной интеграции нам не хватало только агента, который умеет отслеживать изменения в базе и мы написали его сами, благо в Huginn очень удобно писать своих агентов.
huginn_mysql2_agent
Как оказалось, большинство кейсов мы покрываем тремя агентами:
- Mysql2Agent – поллим базу на наличие изменений. Для каждой строки выборки будет сгенерировано событие и передано дальше по цепочке.
- EventFormatting – форматируем входящее сообщение с использованием liquid шаблонов.
- JsonAPIAgent – вызвать внешнее или внутреннее API для получения/отправки данных.
Примеры использования
Публикация новых аукционов в Telegram-канал
Ниже представлена одна из первых реализованных цепочек. Агент ежеминутно проверяет новые аукционы в БД по created_at, далее по внутреннему API получает всю информацию по авто и отправляет сообщение в Telegram.
Самое примечательное – это то, что интерфейсы интуитивно понятны, а актуальная конфигурация визуализирована в виде графа. Поэтому подобная интеграция не требует ресурсов разработки и делается силами менеджеров и интернет-маркетологов.
Персональные рекомендации по sms
Ниже пример реализации эксперимента по доставке персональных рекомендаций дилерам по sms. Для каждого нового аукциона получаем по API внутренней рекомендательной системы (LSTM RNN) список дилеров, из БД получаем номер телефона, сокращаем ссылку на аукцион с помощью urlshortener и отправляем sms через внешний сервис рассылки.
Интеграция с маркетинговыми инструментами
Далее представлена часть схемы интеграции с маркетинговыми инструментами – сервисом exponea. В ходе ее реализации ни один разработчик не пострадал – реализация и поддержка силами одного менеджера.
Развернуть и попробовать
Самый простой способ попробовать Huginn – развернуть его в docker.
docker run -it --name huginn -p 3000:3000 -e ADDITIONAL_GEMS="huginn_mysql2_agent(git: https://github.com/yubuylov/huginn_mysql2_agent.git),huginn_jsonapi_agent(git: https://github.com/yubuylov/huginn_jsonapi_agent.git)" huginn/huginn
http://localhost:3000/
Логин: admin, Пароль: password
Можно использовать внешнюю базу MySQL и отдельно запускать разные инстансы для web интерфейсов и обработчиков событий, что позволяет с легкостью масштабироваться.
Спасибо за внимание. Надеюсь, данная заметка будет полезна, а Huginn кому-то поможет освободить немного времени для крутых проектов!
Полезные ссылки
> Оф.репозиторий
> Установка в docker
> Production environment
> Список агентов
Комментарии (9)
Aracon
07.06.2017 17:58Спасибо! Полезный опыт, так как сейчас очень актуальны задачи связки разных сервисов, а Zapier и аналоги действительно очень не всегда подходят.
Для меня статья очень вовремя и очень в тему.Aracon
16.06.2017 20:31Поднял экземпляр на Heroku по документации, впечатления весьма приятные. Самые необходимые агенты в наличии. Кроме упомянутых в статье, добавлю в число самых интересных ещё агент, проверяющий IMAP. Есть ряд сервисов, которые шлют уведомления на email, и на эти уведомления нужно реагировать. Так как уведомления от них очень редко, писать что-то на каждый сервис лень (проще отреагировать вручную), а здесь всё можно настроить унифицированно.
Порадовало, что, похоже, если сценариев и событий не очень много, то всё прекрасно работает на бесплатном тарифе Heroku.
CynicalBear
07.06.2017 19:27Спасибо большое, интересный инструментарий! А вы не прикидывали хотя бы приблизительно, сколько человек в разных департаментах вам заменил Huginn? Я так понял, в первую очередь это экономия на кол-центре?
yubuylov
08.06.2017 11:54Спасибо! Мы не ставили перед собой цель заменить инструментом людей – Huginn просто позволяет нам масштабироваться.
Например, аккаунт-менеджеры 100% времени тратили на вывод дилеров на аукцион.
После появления персональных уведомлений (Huginn + рекомендательная система) они могут уделять больше внимания обучению новых дилеров или например, работать с пассивами.WhiteUnicorn
08.06.2017 12:40Вы написали, что используете Huginn для интеграций «без высоких требований к надежности». Это обусловлено какими-то ограничениями/трудностями в использовании этой платформы?
yubuylov
08.06.2017 14:22У любой системы есть свои плюсы и минусы, в том числе и у Huginn.
Плюсы:
- скорость внесения изменений
- стоимость интеграции
- прозрачность логики
- наглядность DataFlow
Минусы:
- легко сломать
- SPoF
- контроль изменений
Huginn действительно легко сломать – тяжелый запрос к базе или неаккуратно настроенный агент может заблокировать все свободные обработчики. Соответственно, задачи остальных агентов будут находиться в очереди. Врядли бизнесс устроит задержка по обратному звонку клиенту из-за того, что мы вдруг решили просеять через Huginn все хиты на сайте, а CircuitBreaker не реализовали.
Контролировать изменения сложно. Нет версионности и истории конфигураций агентов.
Но проект активно развивается и возможно в будущем все это появится.
Bushikot
08.06.2017 15:28Со стороны выглядит так, будто все ваши «эксперименты» так и остаются в Huginn на постоянной основе. Если так, то значит функционал копится и копится, а в один прекрасный день всё это разом ломается. Менеджером. Или же в какой-то момент вы принимаете решение привлечь разработчика и таки вынести некоторую часть в отдельный сервис? Есть ли у вас примеры функционала, которые прошли эту стадию?
yubuylov
08.06.2017 16:39функционал копится… а в один прекрасный день всё это разом ломается
В Huginn нет ничего, что может привести к деградации системы – мы понимаем, что он может развалиться и прийдется восстанавливаться из бекапов.
Кроме того, мы в любой момент можем понять, что эксперимент «не летит» и одной кнопкой его остановить.
… так и остаются в Huginn на постоянной основе
У нас есть сервисы полностью интегрированные через Huginn на постоянной основе, например exponea.
Мы сознательно не переносим их в проект, что-бы избежать ловушек Point-to-Point интеграции:
- экспоненциальный рост сложности и связанности компонент
- потеря гибкости при внесении изменений
- сложность вывода сервиса из эксплуатации
Но действительно, у нас есть примеры, когда мы выносили некоторые части из Huginn, например персональные рекомендации дилерам.
Изначально с помощью Huginn был реализован эксперимент, в котором для каждого аукциона сложным sql-запросом подбирались дилеры, принимавшие участие в аукционах на похожие авто. Запрос много раз переписывался и тюнился. Далее мы привлекли разработчика и sql-запрос заменился сервисом с LSTM RNN «под капотом».
koluchiy01
А вот и руби в зоопарк из пых, голангов и прочих ларавелей )