Как да пускате фонови задачи в уеб приложение: опашки, планировчици и cron
За да пускате фонови задачи в уеб приложение, първо разделете работата на два вида. Задачите по събитие (изпрати приветствен имейл, обработи качен файл) могат да се запазят в опашка за задачи, често таблица в базата данни, и да се обработват от работник с опити за повторение. Планираните задачи (нощен отчет, напомняния на всеки 15 минути) се нуждаят от нещо, което се задейства по график: cron функция на хоста или външен планировчик, който извиква защитена крайна точка във вашето приложение. Винаги правете задачите безопасни за изпълнение два пъти, записвайте грешките и никога не разчитайте на таймер в сървър, който може да заспи или да се рестартира.
Това ръководство обяснява опциите, кога всяка подхожда и как да ги настроите с AI строител на приложения, включително на хостинги, които се мащабират до нула.
Какво се брои като фонова задача
Всичко, което е бавно, ненадеждно или не е нужно за незабавния отговор към потребителя:
- Изпращане на имейли, известия и разписки
- Преоразмеряване на изображения, транскодиране на видео, генериране на PDF файлове
- Извикване на бавни услуги на трети страни, включително AI модели за дълги задачи
- Импортиране или синхронизиране на данни от друга система
- Нощно почистване, отчети и напомняния
Правенето на това в самата заявка прави страниците бавни и крехки: ако доставчикът на имейли е недостъпен, регистрацията на потребителя се проваля. Преместването във фонов режим означава, че потребителят получава мигновен отговор, а задачата може да се повтори.
Опциите
| Опция | Как работи | Предимства | Недостатъци |
|---|---|---|---|
| Fire-and-forget в същия процес | Отговаряте, после продължавате работата в сървъра | Без настройка | Губи се, ако сървърът спре; без опити за повторение |
Таймер в процеса (setInterval, setTimeout) | Таймер в работещия сървър | Тривиално | Не работи докато спи; дублира се с няколко копия |
| Опашка в база данни | Задачите се записват като редове; работник ги взима и изпълнява | Използва базата, която имате; трайна; лесна за проверка | Сами изграждате повторенията и заключването; нужно е нещо, което да пуска работника |
| Специализирана опашка (на Redis или управлявана) | Услуга за опашка плюс работници | Зрели функции за повторения и планиране | Още една услуга за поддържане и плащане |
| Хостната услуга за задачи или работни процеси | Трета страна извиква вашите крайни точки с повторения и графици | Планирането и повторенията се поемат вместо вас | Зависимост от доставчик; още един акаунт и ключ |
| Външен планировчик, който извиква крайна точка | Таймер някъде другаде праща HTTP заявка по график | Работи на всеки хост, включително при мащабиране до нула | Минимални интервали и забавяния; защитете крайната точка |
| Вграденият cron на хоста | Платформата изпълнява команда по график | Просто, където го има | Не всеки хост го предлага |
Няма единствен правилен отговор. Малкото приложение често се нуждае само от опашка в база данни плюс външен планировчик.
Защо хостингите, които се мащабират до нула, променят картината
Много съвременни хостинги приспиват приложението ви, когато никой не го използва, и го събуждат при следващата заявка. Това спестява пари, но заспал сървър не изпълнява код: таймерите не се задействат и работниците не проверяват опашката. На тези хостинги планираната работа трябва да започне с входяща заявка, а най-лесният източник на тази заявка е външен планировчик. Всяко извикване събужда приложението (и често базата му данни), така че извикване на всяка минута струва повече от извикване на всеки 15 минути. Изберете най-бавния график, който отговаря на нуждата.
Модел 1: опашка от задачи в база данни
За задачите по събитие:
- Създайте таблица
jobs: тип, полезен товар (JSON), статус (pending,running,done,failed), опити, 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 повтаря неуспешните плащания по абонаменти и изпраща уебхукове; вие реагирате, вместо да проверявате. Вижте какво е уебхук.
- Имейл. Доставчиците слагат в опашка и повтарят доставката, след като им предадете съобщението.
- Масова AI работа. OpenAI и Anthropic предлагат batch API за незабързани заявки, които изпращате и събирате по-късно.
Промптове за вашия AI строител
За опашка:
Добави опашка за фонови задачи, използвайки таблица jobs в нашата база данни (тип, полезен товар JSON, статус, опити, run_after, last_error). Когато потребител се регистрира, вмъкни задача send_welcome_email в същата транзакция вместо да изпращаш inline. Добави функция 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 сутринта“ означава различни неща за вашия планировчик (често UTC) и за вашите потребители. Съхранявайте времената в UTC и ги превръщайте за всеки потребител.
- Тайни във файла на работния процес. Пазете токените в тайното хранилище на планировчика. Вижте как да пазите API ключовете в безопасност.
Контролен списък
- Бавната работа е преместена извън заявките на потребителите
- Задачите са съхранени трайно, не само в паметта
- Повторения с нарастващи забавяния и максимум
- Всяка задача е безопасна за изпълнение два пъти
- Планираната крайна точка е защитена с таен токен
- Всяко изпълнение обработва ограничена партида
- Неуспешните задачи са видими, с известия
- Интервалът на графика е избран с оглед на разходите за хостинг
- Времената се съхраняват в UTC
Фонови задачи в Mythex
Документацията на Mythex не описва планирани или cron задачи, а публикуваните приложения и техните бази данни заспиват при бездействие и се събуждат при следващата заявка (вижте Ограничения на хостинга). Затова не разчитайте на таймери в приложението си. Подходът, който работи, е този по-горе: помолете агента за таблица за задачи и крайна точка, защитена с токен, после насочете външен планировчик към публикувания ви URL. Съхранете токена като тайна на проекта и помнете, че всяко събуждане харчи кредити за времето, през което приложението и базата данни са будни, затова изберете разумен интервал. Ако приложението ви се нуждае от API бекенд за това, рецептата за REST API бекенд е добра отправна точка, а как да изградите REST API обхваща проектирането на крайните точки. Ако основната част от продукта ви са постоянно работещи работници или ботове, хостинг, създаден за постоянни процеси, може да ви подхожда по-добре.
Въпроси
Какво е фонова задача?
Фонова задача е работа, която приложението прави извън заявката, на която потребителят чака, например изпращане на имейли, преоразмеряване на изображения, генериране на отчети или синхронизиране на данни. Потребителят получава бърз отговор, а задачата се изпълнява отделно и може да се опита отново, ако се провали.
Как да пусна планирана задача, ако хостингът ми няма cron?
Добавете защитена крайна точка, която върши работата, и накарайте външен планировчик да я извиква по график. Възможностите включват насрочен работен процес в GitHub Actions, хостван cron услуга или планировчика на облачния ви доставчик. Защитете крайната точка с таен токен.
Мога ли да използвам setInterval или setTimeout за планирани задачи?
Само за малки, неважни задачи на сървър, който винаги работи. Ако сървърът се рестартира, се мащабира до нула или работи в няколко копия, таймерите се губят или се изпълняват повече от веднъж. Съхранявайте планираната работа в база данни или използвайте планировчик.
Поддържа ли Mythex cron задачи?
Документацията на Mythex не описва планирани или cron задачи, а публикуваните приложения заспиват при бездействие. Надеждният подход е външен планировчик да извиква защитена крайна точка във вашето приложение, която събужда приложението и изпълнява работата.