
Всем привет, меня зовут Евгений Тихонов я работаю в Банке Уралсиб, в дирекции по сопровождению комплаенс‑систем, факторинга и электронных продаж. Я хочу рассказать вам о простом кейсе, который облегчил жизнь отдела разработки рекламных crm‑кампаний.
В чем суть
Я поддерживаю техническую сторону ПО Unica. Вендор из РФ ушел, соответственно, сам продукт работает, но поддержка не осуществляется. Коллеги из маркетинга самостоятельно запускают и останавливают свои флоучарты и, казалось бы, все тут хорошо, но я не зря пишу эту статью ?
Все рекламные кампании проходят через сервер. В моменты повышенной нагрузки на сервер маркетинговый флоучарт может зависнуть. И коллеги обращаются в поддержку, то есть ко мне. Это может случиться рано утром, в выходной или праздничный день. Я подключался к контуру Банка и останавливал вручную такие зависшие рекламные кампании. Мне неудобно, коллегам нервозно и главное — много ручника.
Поиск решения
В Уралсибе мы регулярно обсуждаем и делимся практиками инженерной культуры. Автоматизация рутинных процессов или создание self‑сервиса там, где это возможно — одно из очевидных решений. Перед новым деловым сезоном нужна доработка, которая заменит рутину и ускорит процесс остановки. Необходимо придумать такой способ, чтобы коллеги из бизнеса смогли самостоятельно останавливать зависшие флоучарты и делать это в любое время без прямой поддержки специалиста.
Т.е. для пользователей нужен простой интерфейс, вход с доменной авторизацией, и главное — функция «остановить флоучарт», он же рекламная кампания. Для технической поддержки мы тоже заложили важные функции этой доработки, какие именно и для чего расскажу дальше.
Что применили
Python — язык программирования, самый простой и с большим набором библиотек и фреймворков.
Flask — фреймворк для создания веб‑приложении на языке программирования Python
Библиотека Sqlite — база данных
Библиотека psutil — получает информацию о запущенных процессах на сервере
Библиотека python‑ldap — позволяет работать с LDAP
Основной функционал данного приложения — это остановка процессов. Flask‑приложение видит их на сервере и может управлять ими.
Схема такая:
Браузер
|
Flask
|
Psutil
|
Linux‑процессы
Движение процесса psutil:
поиск процессов
получение PID и имя
определение флоучарта с форматом.ses
отправка процессу сигнала остановки.
Основной механизм получения процессов:
for proc in psutil.process_iter([ "pid", "name", "username", "cpu_percent", "memory_percent" ]):
psutil.process проходит по всем процессам Linux и из него получает proc.pid, proc.name(), proc.username().
Так как все флоучарты Unica запускаются под пользователем hcl, мы для безопасности смотрим только процессы hcl
PROCESS_OWNER = "hcl" owner = (info["username"] or "").lower() if owner != PROCESS_OWNER: continue
Таким образом, имеем защиту от остановки процессов root, zabbix и тому подобное
Остановка происходит следующим образом: Flask получает POST /kill/12345 и вызывает stop_process(12345) внутри создается объект процесса с PID 12345, далее мы проверяем владельца.
owner = proc.username().lower() if owner != PROCESS_OWNER: raise Exception(...)
Самая важная команда проекта это os.kill(proc.pid, signal.SIGTERM), по сути линукс получает kill ‑TERM 12345, выбор пал именно на term, а не kill -9 так как term менее жесткий вариант остановки.
В нашем случае psutil не отвечает за Unica напрямую. Он отвечает за взаимодействие flask‑приложения с процессами linux. Исходя из этого, данное приложение можно адаптировать под любой линукс‑сервер куда мы не хотим пускать пользователей по ssh, а необходимость остановки процессов у них возникает.
Для себя на сервере сделал логирование по остановкам флоучартов, чтобы понимать кто и как часто пользуется доработкой. Выдачу доступов настроили по заявке через ServiceDesk, написал пошаговую инструкцию для пользователей. На все движения по доработке ушло две недели, включая шлифовку. Сегодня коллеги уже пользуются сервисом.
Ценность для бизнеса
О профите для бизнеса сложно говорить, когда ты инженер, и за обратной связью я обратился к Даниилу Борисову, который возглавляет отдел разработки кампейна, он и его команда занимаются crm‑кампаниями.
«У нас в работе очень много флоучартов, и примерно раз в месяц мы отлавливаем зависшие рекламные кампании. Бывало, что просили поддержку отключить их в выходной или поздно вечером, это избыточная коммуникация — мы знаем, что делать, но раньше у нас не было инструмента. С момента внедрения доработки удалось воспользоваться ее функционалом один раз, но экономия времени и удобство здесь очевидны. Надвигается осень, мы показываем больше офферов, в том числе акционных, ограниченных по времени и здесь простои очень чувствительны для бизнеса».
Инженерные итоги:
разработан и внедрен self‑сервис для дирекции, которая управляет маркетинговым бизнес‑процессом;
рутина автоматизирована, стало меньше промежуточных коммуникаций;
я получил новый опыт и подумаю о его применении в других системах банка, которые я сопровождаю.
Писали доработки с применением flask‑Phyton? Поделитесь своим опытом!
crymans
Идея с self-service отличная, но есть пара инфраструктурных нюансов по реализации:
Под каким пользователем запущен сам фласк? Если сервис работает от
root, чтобы иметь права наos.kill— это очень опасный паттерн для веб-приложения. Гораздо безопаснее запускать сам Flask (через systemd/gunicorn) строго под юзеромhcl. Тогда проверкаif owner != PROCESS_OWNERстановится просто страховкой от ошибок логики — ядро ОС на уровне прав само не даст фласку убить чужие процессы, даже если кто-то подделает запрос.Вы пишете, что выбрали SIGTERM как "менее жесткий вариант". Но если флоучарт реально намертво «завис» (например, случился дедлок или процесс повис на I/O-операциях), он с большой вероятностью просто проигнорирует мягкий SIGTERM, и процесс останется висеть. В таких хелперах обычно реализуют паттерн graceful shutdown: отправляют SIGTERM (у
psutilдля этого есть удобный методproc.terminate()), ждут пару секунд черезproc.wait(timeout=3), и если процесс всё ещё жив — добивают уже жесткимproc.kill(). Иначе вашим инженерам всё равно придется периодически заходить и делатьkill -9руками.evgeny586 Автор
Спасибо большое за подсказку, flask запускается действительно из под root. Много моментов упустил из за неопытности. Попробую по вашей рекомендации сделать и протестировать. Еще раз спасибо