• Главная
  • Контакты
Подписаться:
  • Twitter
  • Facebook
  • RSS
  • VK
  • PushAll
logo

logo

  • Все
    • Положительные
    • Отрицательные
  • За сегодня
    • Положительные
    • Отрицательные
  • За вчера
    • Положительные
    • Отрицательные
  • За 3 дня
    • Положительные
    • Отрицательные
  • За неделю
    • Положительные
    • Отрицательные
  • За месяц
    • Положительные
    • Отрицательные
  • За год
    • Положительные
    • Отрицательные
  • Сортировка
    • По дате (возр)
    • По дате (убыв)
    • По рейтингу (возр)
    • По рейтингу (убыв)
    • По комментам (возр)
    • По комментам (убыв)
    • По просмотрам (возр)
    • По просмотрам (убыв)
Главная
  • Все
    • Положительные
    • Отрицательные
  • За сегодня
    • Положительные
    • Отрицательные
  • За вчера
    • Положительные
    • Отрицательные
  • За 3 дня
    • Положительные
    • Отрицательные
  • За неделю
    • Положительные
    • Отрицательные
  • За месяц
    • Положительные
    • Отрицательные
  • Главная
  • The uWSGI Spooler

The uWSGI Spooler +26

24.04.2017 08:30
VyacheslavAkhmetov 4 3300 Источник
Python*, Блог компании Селектел


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


Самой популярной системой очередей в Python является Celery, она обладает широким набором возможностей по управлению задачами. К сожалению, системы на базе Celery сложно поддерживать в работоспособном состоянии, и когда что-то идёт не так, то найти проблему бывает весьма не просто. Можете спросить любого девопса об опыте работы с Celery, но будьте готовы услышать не очень приятные слова.


К счастью, есть альтернативное решение — uWSGI Spooler, и в этой статье я расскажу о нём подробнее.



Основным отличием от Celery является то, что не нужно использовать дополнительные компоненты (сам Celery и хранилище, например Redis), таким образом количество точек отказа уменьшается на две. В качестве хранилища задач может использоваться директория, внешняя директория или сетевой пул.


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


Кроме обслуживания Python-кода в виде обеспечения непрерывного доступа к web-приложению, в uWSGI входит компонент Spooler, который реализует систему очередей. Spooler имеет некоторые особенности, а документация по нему достаточно скудна.


Использовать uWSGI Spooler просто, как раз-два-три! Но есть несколько нюансов.
Модуль uwsgi нельзя импортировать из кода, а соответственно тестировать из консоли код не получится, необходимо каждый раз запускать uwsgi воркера, для чего необходимо создать конфиг:


[uwsgi]
socket = /var/run/mysite.sock 
master = True
processes = 4
project_dir = /home/myuser/mysite
chdir = %(project_dir)
spooler = /var/uwsgi_spools/mysite_spool
spooler-import = path.to.spool.package # (package to import spool file)
spooler-frequency = 10 # Frequency for scanning spool
max-requests = 5000
module = wsgi:application
touch-reload = wsgi.py

Файл воркера:


from uwsgidecorators import spool, uwsgi

@spool
def my_func(args):
    print(args)
    # do some job

Постановка задачи из вашего кода:


import uwsgi_spools.mysite_spool as mysite_spool

mysite_spool.my_func.spool(test=True)

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


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


Таск может вернуть три статуса:


  • -2 (SPOOL_OK) – таск выполнен, будет удалён из очереди;
  • -1 (SPOOL_RETRY) – что-то пошло не так, таск будет повторно вызван;
  • 0 (SPOOL_IGNORE) – игнорировать таск.

Все прочие значения будут интерпретированы как -1 (SPOOL_RETRY).


Особенность: декоратор @spool выполняется единожды (возвращает SPOOL_OK), если функция не упала с исключением.
Для того чтобы управлять жизненным циклом нужно использовать @spoolraw.


Особые ключи (вспомогательные) при создании таска:


  • spooler — абсолютный путь к спулеру, который будет выполнять задачу;
  • at — unix time, когда задача должна быть выполнена (правильнее сказать, она не будет выполнена ранее этого значения);
  • priority — указывает на подпапку в папке задач (на такую подпапку можно выделить большее количество воркеров), через --spooler-ordered можно настроить приоритеты;
  • body — этот ключ используется для значений более 64 КБ, в задачу будет доступен в сериализованном виде.

Кроме декоратора @spool доступен декоратор @timer, который принимает количество секунд в качестве аргумента и позволяет выполнять декорируемую функцию с указанным интервалом.


@timer(30)
def my_func(args):
    print(args)
    # do some job every 30 sec

Аналогично @timer есть декоратор @spoolforever, который будет повторно запускать выполнение функции (завершение задачи со статусом SPOOL_RETRY).


@spoolforever
def my_func(args):
    print(args)
    # do some job and repeat

Для настройки воркеров для работы по сети, нужно добавить адрес, по которому он будет доступен в ini-файл:


socket = 127.0.0.1:10001

При создании задачи указывать адрес получателя задачи:


uwsgi.send_message(“127.0.0.1:10001”, 17, 0, test=True, 5)
# или
uwsgi.spool(test=True, spooler=“127.0.0.1:10001”)

Таким образом, uWSGI Spooler можно использовать как замену очередям, но если всё же не хватает возможностей или хочется немного сахара, то можно использовать uwsgi-tasks, который реализует недостающее.

Поделиться с друзьями
-->

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


  1. crazylh
    24.04.2017 20:20
    #10189156
    +1

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

    А вы уверены, что говорите именно про проблемы продукта, а не очереди, поверх которой бежит Celery (rabbitmq/redis/mongo)


    1. rusnasonov
      27.04.2017 11:15
      #10193584

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


  1. Satevg
    24.04.2017 21:33
    #10189264

    но если всё же не хватает возможностей


    Из статьи создается ощущение того, что все с Spooler «ровно-гладко, замените Celery, захочете еще»,
    И все же какие есть различия с Celery кроме описанных выше, нюансы в продакшене?


  1. foldr
    27.04.2017 11:15
    #10193590

    А можно по-подробнее, о каких проблемах с Celery идет речь? Сам участвую в проекте с Celery не так давно, но пока не возникало желания его выкинуть и заменить на что-то другое

МЕТКИ

  • Хабы
  • Теги

Python

Блог компании Селектел

spooler

uWSGI

система очередей

СЕРВИСЫ
  • logo

    CloudLogs.ru - Облачное логирование

    • Храните логи вашего сервиса или приложения в облаке. Удобно просматривайте и анализируйте их.
Все публикации автора
  • The uWSGI Spooler +26

    • 24.04.2017 08:30

    Vscale: облачные серверы +25

    • 17.08.2015 10:48

Подписка


ЛУЧШЕЕ

  • Сегодня
  • Вчера
  • Позавчера
08:00

Отказ от IPv4 и готовность человечества к IPv6‑инфраструктуре +20

00:18

Принцип Ландауэра — сколько весит один бит информации и почему стирание памяти греет Вселенную +16

07:05

Можно ли «посмотреть за угол»? Физика отвечает: да, конечно, никаких проблем +15

07:03

«Это уже тысячу раз делали»: как мы добавили медиаленту в Яндекс Еду для iOS. А потом переделали +14

06:04

Советский вундеркинд, клепавший в школе роботов, часть 2 +12

06:01

OCC-RAG: компактные модели, которые отвечают только по источникам +11

06:00

От перфокарт до мейнфреймов: как в Германии обнаружили забытый «музей» вычислительной техники +11

08:00

СПОТ с 1 июня 2026 года: новые правила ввоза товаров из ЕАЭС и что нужно сделать уже сейчас +6

00:17

Как я строил трактор(RAG) для клумбы, а клумбы не оказалось +6

08:01

CancelledError — не просто очередная ошибка. Разбираемся, как устроена отмена задач в asyncio +5

08:05

Анализ медицинского анализатора: Bayer Clinitek Status+ +4

08:00

Как и чем ломали российские компании. Исследование Jet CSIRT +4

06:55

Живой космос на Metal: как я переписывал фон мобильной игры и поднимал FPS с 20 до 120 +4

06:32

Принцип ограничения некомпетентности, или почему «варяг» лучше? +4

09:01

Пасхалки для своих: Emacs в массовой культуре +3

08:57

Потратил полгода на обучение своей ии с нуля, вот что вышло +3

08:08

Как собственные головные боли привели меня к созданию приложения для анализа метеозависимости +3

07:32

Почему Солнце светит, а чайник — нет. Разбираемся в недостающем звене между термоядерным синтезом и видимым светом +3

07:20

Трассируем чтение 8 КБ из PostgreSQL +3

08:00

Как я устал вести ИТ‑активы в Excel и написал свой ITAM/CMDB +2

08:48

Я обнаружил крупномасштабное распространение вирусов в GitHub +123

10:25

Vibecode по дешевке — домашний сервер с Qwen Code за 25к, который не отключит Anthropic +95

13:40

Как я нашел новую панграмму (разнобуквицу) +71

08:00

Сказ о том, как нейросеть занялась reward hacking прямо у меня на кухне +55

13:02

Про то, как из 0°C получить мороз в десятки градусов и не только +40

07:00

Когда нашим дорогим инженерам сильно надоело 5 раз проверять документацию за подрядчиками +30

09:01

Безымянный китайский телекастер +28

07:05

Позвонить бесплатно: история взлома аналоговой телефонии. Часть 1 +28

11:14

Внешняя память для LLM: как RAG дает моделям доступ к новым знаниям +24

15:13

ROP Level 1 в GD32F4: «А метлой дверь подпёр?» Или как нежно слить защищенную прошивку через программатор +22

07:57

КД по ГОСТ за один клик +21

09:03

«РБПО для бедных»: собираем CI/CD-конвейер безопасной разработки +20

12:45

SI/PI в разработке электронных устройств: анализ, который сэкономит вам время, деньги и нервы +19

08:05

Продали дом за 7 000 000₽ и потеряли в майнинге. Видеокарты остались — из них вырос сервис генерации +19

10:50

Делаем науку на ровном месте +18

08:05

Как мы построили централизованную CMDB для управления Zabbix с RFC, аудитом и откатом изменений +18

09:46

Как с нас пытались взыскать 5 000 000 рублей за детские трусы +17

09:11

Книга: «Компьютерные сети. Принципы, технологии, протоколы. 7-е издание.» +17

08:05

Transfer 2.0, или Как я перестал бояться и полюбил миграции облачных серверов +17

16:32

Открыл бету AI-Мастера для D&D. Главная проблема оказалась не в кубиках, а в памяти +16

11:00

Новые правила Хабра. Версия от 2026 +207

14:05

Почему мы до сих пор неправильно пишем физические движки и 3D-графику +89

07:01

Звуки музыки советских ПЭВМ +69

12:01

Интервью автора легендарной Elite Йена Белла (Эксклюзив для Хабра) +57

07:52

YaFF в опенсорсе: как и зачем мы сделали zero‑copy представление для Protobuf +55

13:01

Docker Fundamentals: теория и базовая эксплуатация +47

14:17

Как «Союз» считал орбиту шестерёнками: внутри навигационного компьютера «Глобус» +43

08:00

История виртуализации от chroot и jails до современных гипервизоров +36

22:46

Адаптация в команде есть? А если найду? +35

07:12

Почему советы «как улучшить резюме» в IT в 2026 — это издевательство (и что делать вместо этого) +35

14:38

Условная агрегация в SQL: ускоряем отчеты, избавляясь от лишних JOIN-ов и подзапросов +25

09:01

Как выбрать самый безопасный мессенджер +22

18:07

PaintCAD Mobile 3.0.24 — графический редактор для Android 2.3+ и J2ME +20

08:00

Код в эпоху AI: как перестать бороться за качество и начать контролировать деградацию +18

21:28

Clean Architecture и AI: как я перестроил проект на 200К строк, чтобы агенты не ломали код +17

12:39

Как в 1915 году взялись собирать базу данных на всю страну без единого компьютера +17

12:37

Лонсдейлитовая кромка. Перспективы искусственного расширения шкалы Мооса. Guest Post +17

11:29

Серьёзная ретро-консоль за адекватные деньги: разбираем по винтикам DVTech And-001 +17

13:17

Как незаметная indirect-зависимость в Go дописала ручку в ваш HTTP-сервер +16

07:05

Zynq 7000. Переносим I²C Master Controller.  Linux + buildroot + kernel driver +16

ОБСУЖДАЕМОЕ

  • Новые правила Хабра. Версия от 2026 +207

    • 330   22000

    Vibecode по дешевке — домашний сервер с Qwen Code за 25к, который не отключит Anthropic +95

    • 163   37000

    Цена одного канала видеонаблюдения на нейронных сетях +3

    • 104   6300

    Почему советы «как улучшить резюме» в IT в 2026 — это издевательство (и что делать вместо этого) +35

    • 69   12000

    Продали дом за 7 000 000₽ и потеряли в майнинге. Видеокарты остались — из них вырос сервис генерации +19

    • 64   14000

    Парадокс Open-Source: Единственный способ победить корпорации — раздать свой код бесплатно +9

    • 41   8500

    Я год не писал код руками. Но я не вайбкодер — и это две разные профессии +12

    • 37   11000

    ЦОДам в Москве отказывают в сети, они вынуждены строить электростанции +4

    • 37   8400

    Звуки музыки советских ПЭВМ +69

    • 37   12000

    Интервью автора легендарной Elite Йена Белла (Эксклюзив для Хабра) +57

    • 36   12000

    Как я нашел новую панграмму (разнобуквицу) +71

    • 31   14000

    Как я перестал исправлять ИИ код и начал проектировать под него архитектуру +10

    • 31   11000

    Я обнаружил крупномасштабное распространение вирусов в GitHub +123

    • 30   21000

    Лучшие связки CPU и GPU для игрового ПК в 2026 году: от 1080p до 4K +11

    • 29   12000

    Как спроектировать web-приложение на годы вперед +6

    • 27   13000
  • Главная
  • Контакты
© 2026. Все публикации принадлежат авторам.