Як запускати фонові завдання у вебзастосунку: черги, планувальники і cron
Щоб запускати фонові завдання у вебзастосунку, спершу розділіть роботу на два види. Завдання за подією (надіслати вітальний лист, обробити завантаження) можна зберегти в черзі завдань, часто це таблиця у вашій базі даних, і обробляти воркером з повторними спробами. Заплановані завдання (нічний звіт, нагадування кожні 15 хвилин) потребують чогось, що спрацьовує за розкладом: функції cron хостингу або зовнішнього планувальника, який викликає захищену кінцеву точку вашого застосунку. Завжди роблячи завдання безпечними для повторного запуску, фіксуйте збої і ніколи не покладайтеся на таймер всередині сервера, який може заснути або перезапуститися.
Цей посібник пояснює варіанти, коли кожен підходить і як налаштувати їх за допомогою AI-конструктора застосунків, зокрема на хостингах, які масштабуються до нуля.
Що вважається фоновим завданням
Будь-що повільне, ненадійне або не потрібне для негайної відповіді користувачеві:
- Надсилання листів, сповіщень і квитанцій
- Зміна розміру зображень, транскодування відео, створення PDF
- Виклики повільних сторонніх API, зокрема моделей ШІ для довгих завдань
- Імпорт або синхронізація даних із іншої системи
- Нічне очищення, звіти і нагадування
Якщо робити це всередині запиту, сторінки стають повільними і крихкими: якщо провайдер електронної пошти не працює, реєстрація користувача завершується помилкою. Перенесення в фон означає, що користувач отримує миттєву відповідь, а завдання можна повторити.
Варіанти
| Варіант | Як працює | Плюси | Мінуси |
|---|---|---|---|
| Запустити і забути в тому самому процесі | Відповісти, потім продовжити роботу на сервері | Без налаштування | Губиться, якщо сервер зупиняється; без повторних спроб |
Таймер у процесі (setInterval, setTimeout) | Таймер у запущеному сервері | Просто | Не працює, поки сервер спить; дублікати за кількох копій |
| Черга в базі даних | Завдання зберігаються як рядки; воркер бере їх і виконує | Використовує вашу наявну базу даних; надійна; легко перевірити | Повторні спроби і блокування створюєте ви; потрібно щось, що запускатиме воркер |
| Окрема черга (на основі Redis або керована) | Сервіс черги і воркери | Зрілі функції повторів і планування | Ще один сервіс для запуску і оплати |
| Хостингові сервіси завдань або робочих процесів | Сторонній сервіс викликає ваші кінцеві точки з повторами і розкладами | Планування і повтори обробляються за вас | Залежність від постачальника; ще один обліковий запис і ключ |
| Зовнішній планувальник, що викликає кінцеву точку | Таймер деінде надсилає HTTP-запит за розкладом | Працює на будь-якому хостингу, зокрема з масштабуванням до нуля | Мінімальні інтервали і затримки; захистіть кінцеву точку |
| Вбудований cron хостингу | Платформа запускає команду за розкладом | Просто там, де є | Не кожен хостинг це пропонує |
Єдиної правильної відповіді немає. Малому застосунку часто потрібні лише черга в базі даних і зовнішній планувальник.
Чому хостинги, що масштабуються до нуля, змінюють картину
Багато сучасних хостингів усипляють ваш застосунок, коли ним ніхто не користується, і будять його при наступному запиті. Це заощаджує гроші, але сервер, що спить, не виконує код: таймери не спрацьовують і воркери не опитують. На таких хостингах заплановану роботу треба почати з вхідного запиту, а найпростіше джерело такого запиту — зовнішній планувальник. Кожен виклик будить застосунок (і часто його базу даних), тож виклик щохвилини коштує більше, ніж раз на 15 хвилин. Обирайте найповільніший розклад, який задовольняє потребу.
Патерн 1: черга завдань у базі даних
Для завдань за подією:
- Створіть таблицю
jobs: тип, payload (JSON), статус (pending,running,done,failed), attempts, run_after, last_error, позначки часу. - Коли щось відбувається, вставте рядок завдання в тій самій транзакції, що і зміна, яка його викликала, щоб вони або успішно виконалися разом, або разом провалилися.
- Воркер бере завдання, яким настав час, позначає їх
running, виконує роботу і позначаєdone. - У разі збою збільште
attempts, встановіть пізнішийrun_after(наприклад, 1, 5, потім 30 хвилин) і збережіть помилку. Після максимуму позначте йогоfailedі сповістіть когось.
Якщо може працювати кілька воркерів одночасно, завдання треба брати безпечно. У Postgres SELECT ... FOR UPDATE SKIP LOCKED дозволяє кожному воркеру брати різні рядки без конфліктів.
Що запускає воркер? На сервері, який завжди працює, — цикл в окремому процесі. На хостингу, що масштабується до нуля, запланована кінцева точка з Патерну 2 може обробляти пакет завдань, яким настав час, при кожному виклику.
Патерн 2: зовнішній планувальник, що викликає ваш застосунок
Для запланованих завдань:
- Додайте кінцеву точку, наприклад
POST /api/cron/send-reminders. - Захистіть її: вимагайте секретний токен у заголовку, збережений як секрет з обох боків, і відхиляйте все інше.
- Зробіть її ідемпотентною: повторний запуск протягом тієї самої хвилини не повинен надсилати два нагадування. Фіксуйте, що вже надіслано.
- Тримайте кожен виклик коротким: обробляйте пакет (скажімо, 100 елементів), а наступний виклик нехай бере решту.
- Спрямуйте на неї планувальник.
Вибір планувальника:
- Заплановані робочі процеси GitHub Actions. Безкоштовно в межах лімітів використання GitHub. Станом на вересень 2026 року документація GitHub каже, що найкоротший інтервал — раз на 5 хвилин, запуски можуть затримуватися в зайняті періоди (особливо на початку кожної години), розклади за замовчуванням використовують UTC, а заплановані робочі процеси в публічному репозиторії вимикаються після 60 днів без активності в репозиторії.
- Хмарні сервіси cron. Існує багато сервісів, єдине призначення яких — викликати URL за розкладом. Перевірте надійність, мінімальний інтервал і сповіщення, перш ніж на них покластися.
- Планувальник вашого хмарного провайдера. Якщо ви вже користуєтеся великим хмарним провайдером, у нього є керований планувальник, який може викликати HTTPS-кінцеву точку.
- Хостинговий сервіс завдань або робочих процесів. Вони поєднують планування, черги і повтори та викликають ваші кінцеві точки для кожного кроку. Порівняйте ціни і ліміти на сайті кожного постачальника.
Патерн 3: нехай це зробить провайдер
Іноді найкраще фонове завдання — взагалі відсутнє:
- Платежі. Stripe повторює невдалі платежі за підписками і надсилає вебхуки; ви реагуєте, а не опитуєте. Див. що таке вебхук.
- Електронна пошта. Провайдери ставлять доставку в чергу і повторюють її, щойно ви передали повідомлення.
- Масова робота з ШІ. OpenAI і Anthropic пропонують пакетні API для несрочних запитів, які ви надсилаєте і забираєте пізніше.
Промпти для вашого AI-конструктора
Для черги:
Додай чергу фонових завдань з використанням таблиці jobs у нашій базі даних (type, payload JSON, status, attempts, run_after, last_error). Коли користувач реєструється, вставляй завдання send_welcome_email в тій самій транзакції замість надсилання всередині запиту. Додай функцію processJobs(limit), яка бере завдання, яким настав час, через SELECT ... FOR UPDATE SKIP LOCKED, виконує їх і повторює невдалі після 1, 5 і 30 хвилин, позначаючи їх failed після 4 спроб.
Для запланованого запуску:
Додай POST /api/cron/tick, захищений bearer-токеном із секрету CRON_SECRET; відхиляй будь-який запит без нього. Кожен виклик виконує processJobs(100) і надсилає нагадування про бронювання, які мають бути надіслані протягом наступних 24 годин і ще не були надіслані, фіксуючи надіслані нагадування, щоб нічого не надсилалося двічі. Поверни JSON-підсумок того, що виконалося. Потім напиши робочий процес GitHub Actions, який викликає цю кінцеву точку кожні 15 хвилин, зчитуючи URL і токен із секретів репозиторію.
Поширені помилки
- Покладатися на
setInterval. Він непомітно зупиняється, коли сервер засинає або перезапускається, і дублюється, коли працюють дві копії. - Незахищена cron-кінцева точка. Будь-хто, хто її знайде, може запустити ваші завдання або збільшити ваш рахунок за електронну пошту.
- Неідемпотентні завдання. Повтори і дублікати викликів планувальника трапляються. Проєктуйте з урахуванням цього.
- Немає видимості збоїв. Завдання, яке непомітно провалюється тиждень, гірше за те, що голосно падає. Записуйте помилки в журнал і сповіщайте про повторні збої.
- Довгі виконання в одному запиті. Запити завершуються за часом. Обробляйте пакетами.
- Занадто часте планування. Кожен виклик на хостингу, що масштабується до нуля, будить застосунок і йому виставляють рахунок. Узгоджуйте інтервал з реальною потребою.
- Часові пояси. «9:00» означає різне для вашого планувальника (зазвичай UTC) і для користувачів. Зберігайте час у UTC і конвертуйте для кожного користувача.
- Секрети у файлі робочого процесу. Тримайте токени в сховищі секретів планувальника. Див. як зберігати ключі API в безпеці.
Контрольний список
- Повільну роботу винесено з запитів користувачів
- Завдання зберігаються надійно, а не лише в пам'яті
- Повтори із збільшуваними затримками і максимумом
- Кожне завдання безпечне для повторного запуску
- Заплановану кінцеву точку захищено секретним токеном
- Кожен запуск обробляє обмежений пакет
- Невдалі завдання видимі, є сповіщення
- Інтервал розкладу обрано з урахуванням вартості хостингу
- Час зберігається в UTC
Фонові завдання в Mythex
Документація Mythex не описує заплановані або cron-завдання, а опубліковані застосунки та їхні бази даних засинають, коли неактивні, і прокидаються при наступному запиті (див. Ліміти хостингу). Тож не покладайтеся на таймери всередині застосунку. Працює підхід, описаний вище: попросіть агента створити таблицю завдань і кінцеву точку, захищену токеном, а потім спрямуйте зовнішній планувальник на вашу опубліковану адресу. Зберігайте токен як секрет проєкту і пам'ятайте, що кожне пробудження витрачає кредити за час, коли застосунок і база даних активні, тож обирайте розумний інтервал. Якщо вашому застосунку для цього потрібен бекенд API, бекенд REST API — хороша відправна точка, а як побудувати REST API пояснює проєктування кінцевих точок. Якщо основа вашого продукту — воркери або боти, що постійно працюють, хостинг, призначений для тривалих процесів, може підійти краще.
Запитання
Що таке фонове завдання?
Фонове завдання — це робота застосунку поза запитом, на який чекає користувач, наприклад надсилання листів, зміна розміру зображень, створення звітів або синхронізація даних. Користувач отримує швидку відповідь, а завдання виконується окремо і може бути повторено, якщо не вдалося.
Як запустити заплановане завдання, якщо мій хостинг не має cron?
Додайте захищену кінцеву точку, яка виконує роботу, а потім нехай зовнішній планувальник викликає її за розкладом. Варіанти: заплановане робоче процес GitHub Actions, хмарний сервіс cron або планувальник вашого хмарного провайдера. Захистіть кінцеву точку секретним токеном.
Чи можна використовувати setInterval або setTimeout для запланованих завдань?
Лише для невеликих, неважливих завдань на сервері, який завжди працює. Якщо сервер перезапускається, масштабується до нуля або працює в кількох копіях, таймери губляться або виконуються більше одного разу. Зберігайте заплановану роботу в базі даних або використовуйте планувальник.
Чи підтримує Mythex cron-завдання?
Документація Mythex не описує заплановані або cron-завдання, а опубліковані застосунки засинають, коли неактивні. Надійний підхід — зовнішній планувальник, що викликає захищену кінцеву точку вашого застосунку; вона пробуджує застосунок і виконує роботу.