• Главная
  • Контакты
Подписаться:
  • 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

Подписка


ЛУЧШЕЕ

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

Создаем собственную базовую станцию при помощи SDR +10

07:19

Реально большая стейт-машина: как мы строили облачную запись и ИИ-конспектирование в Телемосте +5

05:42

Двусторонний монтаж печатных плат +5

06:43

LEGO Education 2026: Новые наборы? Новая электроника? Новая образовательная парадигма +4

02:59

Оземпик: что изменилось в 2026 и почему таблетки не отменяют систему +3

07:47

OSINT для ленивых. Часть 9: Найти все  и не потеряться +1

06:12

Пиратство в эпоху VHS: как Universal судилась с Sony и почему последствия этого спора мы ощущаем и в наши дни +1

10:46

Давайте уже сделаем отдельный хаб: «Я собрал приложение за вечер — зачем теперь разработчики?» +154

15:00

Радар для слежения за БПЛА. Часть 1 +70

08:00

Муравьи против трансформеров: старый алгоритм 1992 года, который вернулся +64

13:31

Голосуй, или проиграешь! разбор фишинга, который пытается угнать Telegram +51

13:29

OneOCR — скрытая OCR внутри Windows 11 +36

13:01

Ваш ИИ ошибался, ошибается и будет ошибаться +34

08:50

Чебурнет близко +33

12:00

Люди скупают Mac Mini M4, а SpaceX покупает Cursor за $60 млрд: ML-дайджест +30

05:29

Баги, которые не ловит Rust +27

07:05

Что делает match после того, как вы нажали Compile +26

09:00

Как Monium приручил GC: разбираемся со сборщиками мусора в observability‑платформе +25

07:01

Как запускать LLM-агентов без облачных API: VPS, локальные модели и требования к железу +25

09:01

Flappy Bird: код веб-клона под микроскопом +24

07:00

Как подготовиться к алгоритмическим соревнованиям: опыт финалиста ICPC +22

15:30

Радар для слежения за БПЛА. Часть 2 +19

13:22

«Алгоритмы на языке Go». Книга, которую ждали +17

12:03

«У нас было 230 тысяч строк легаси-кода». Как мы изменяли приложение «Настройки» +17

08:00

Создание чат-бота в портале Битрикс24 с помощью AI-агентов +17

22:14

Как ИИ потерял доверие общества в США +16

13:20

Как Runtime Radar помогает обнаруживать атаки на цепочку поставок: кейс LiteLLM +16

08:00

Вентиляция в съемной квартире +133

17:12

Я ЛОХ, меня развели в максе +84

10:03

Senior‑разработчики как исчезающий вид +68

10:13

Манипуляции: как распознать и не поддаться +65

09:01

Зря вы забыли эти HTML- и CSS-фичи +51

14:38

Linux диванного гитариста +43

08:03

Может ли ИИ напечатать годную модель на 3D-принтере? +43

07:00

Двигается как утка, выглядит как утка, но не утка +40

09:00

За два месяца вместо года: как мы переписали 97 тысяч строк кода с Objective-C на Swift +39

15:24

НЕкраткая история телеграфа +36

07:05

Немного об «имитаторах» вечного движения… +36

13:01

10 лучших инструментов для бэкапа VDS +31

07:01

Smart Timber: измеряем лес смартфоном. Часть 1: Роль продуктового подхода в успехе проекта +22

05:30

Как я подключил ну очень много датчиков пульса к часам Garmin +22

10:01

Закон о суверенном ИИ и его борьба с матчастью +21

07:30

Reactive Resume — создаём стильное CV за 10 минут +21

07:27

Гайд душного айтишника из СНГ по Вьетнаму +20

10:58

Как одна OC может запускать приложения из разных миров +18

14:15

Минпромторг исключил бренды компьютерной электроники из перечня параллельного импорта, разбираем аналоги и влияние +16

11:55

OCR в кармане: как HunyuanOCR на 1B параметров потеснил гигантов в задачах парсинга документов +16

ОБСУЖДАЕМОЕ

  • Я ЛОХ, меня развели в максе +84

    • 270   39000

    Зачем нам цифровой рубль? +5

    • 175   19000

    Вентиляция в съемной квартире +133

    • 123   29000

    Senior‑разработчики как исчезающий вид +68

    • 109   29000

    Чебурнет близко +33

    • 85   13000

    Давайте уже сделаем отдельный хаб: «Я собрал приложение за вечер — зачем теперь разработчики?» +154

    • 71   16000

    Как я подключил ну очень много датчиков пульса к часам Garmin +22

    • 51   12000

    Linux диванного гитариста +43

    • 50   14000

    Мифы про REST API. Часть 3 +15

    • 42   7400

    Голосуй, или проиграешь! разбор фишинга, который пытается угнать Telegram +51

    • 36   13000

    Минпромторг исключил бренды компьютерной электроники из перечня параллельного импорта, разбираем аналоги и влияние +16

    • 29   18000

    Я 3 недели спал под тяжёлым одеялом: засыпать стало проще, но главный эффект оказался неожиданным +4

    • 29   6800

    Коэффициент токсичности задачи: как одна метрика снизила текучку в команде до 10% +14

    • 27   8000

    Тестовый релиз 1С: Предприятие 8.5.4: лицензии, данные и администрирование +5

    • 26   9700

    Радар для слежения за БПЛА. Часть 1 +70

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