Налаштування cron-завдань для веб-додатку
Cron-завдання запускають код за розкладом: очистка застарілих даних, відправка дайджестів, генерація звітів, оновлення кешу. Головне завдання при налаштуванні — запобігти паралельному запуску однієї задачі та забезпечити моніторинг виконання.
Laravel Task Scheduling
// app/Console/Kernel.php
protected function schedule(Schedule $schedule): void
{
// Щоденний дайджест о 9:00 за московським часом
$schedule->job(SendDailyDigestJob::class)
->dailyAt('09:00')
->timezone('Europe/Moscow')
->withoutOverlapping() // не запускати якщо попередній ще виконується
->onOneServer() // тільки на одному сервері при горизонтальному масштабуванні
->runInBackground();
// Очистка застарілих сесій — кожну годину
$schedule->command('sessions:cleanup')
->hourly()
->withoutOverlapping(5) // максимум 5 хвилин на перекриття
->appendOutputTo(storage_path('logs/sessions-cleanup.log'));
// Перевірка черги сповіщень кожну хвилину
$schedule->command('notifications:send-pending')
->everyMinute()
->runInBackground()
->skip(fn() => !config('features.notifications'));
// Тижневий звіт у понеділки о 8:00
$schedule->job(WeeklyReportJob::class)
->weekly()
->mondays()
->at('08:00');
}
# Crontab: запускати планувальник кожну хвилину
* * * * * cd /var/www/myapp && php artisan schedule:run >> /dev/null 2>&1
Node.js: node-cron
import cron from 'node-cron';
import { db } from './database';
import { emailService } from './services/email';
// Щоденна очистка о 3:00
cron.schedule('0 3 * * *', async () => {
const lock = await acquireLock('cleanup-expired-tokens');
if (!lock) return; // інший інстанс уже виконує
try {
const deleted = await db.query(
'DELETE FROM password_reset_tokens WHERE expires_at < NOW()'
);
console.log(`Cleaned ${deleted.rowCount} expired tokens`);
} finally {
await releaseLock('cleanup-expired-tokens');
}
}, { timezone: 'Europe/Moscow' });
// Кожні 5 хвилин: оновлення курсів валют
cron.schedule('*/5 * * * *', async () => {
try {
const rates = await fetchExchangeRates();
await cache.set('exchange_rates', rates, 300);
} catch (err) {
console.error('Exchange rates update failed:', err);
}
});
Розподілена блокування через Redis (запобігти дублюванню)
// Для Laravel: стандартний Cache::lock()
$schedule->call(function () {
$lock = Cache::lock('daily-digest', 3600);
if (!$lock->get()) {
return; // інший сервер вже виконує
}
try {
app(DigestService::class)->sendAll();
} finally {
$lock->release();
}
})->dailyAt('09:00')->onOneServer();
Моніторинг: Healthchecks.io / Laravel Health
# Crontab з ping-сповіщенням
* * * * * cd /var/www/myapp && php artisan schedule:run \
&& curl -fsS https://hc-ping.com/YOUR-UUID > /dev/null 2>&1
// Сповіщення про помилку планувальника
$schedule->job(SendDailyDigestJob::class)
->dailyAt('09:00')
->pingOnSuccess('https://hc-ping.com/success-uuid')
->pingOnFailure('https://hc-ping.com/fail-uuid')
->emailOutputOnFailure('[email protected]');
Терміни реалізації
Налаштування cron-розкладу для Laravel або Node.js додатку: 1 день. З розподіленою блокуванням, моніторингом виконання та сигналами тривоги: 2 дні.







