How do I configure a cron task to run every 10 seconds in CentOS 9 Stream? On CentOS 7, I used a method with multiple entries in crontab using the SLEEP command, but in CentOS 9 Stream this approach doesn’t work - cron doesn’t execute and doesn’t write logs. Examples of current crontab entries:
* * * * * sleep 0 ; /usr/bin/php -f /home/bitrix/ext_www/site.com/bitrix/php_interface/cron_events.php >> /home/bitrix/.bx_temp/site.com/log/cron_events.log 2>&1
* * * * * sleep 10 ; /usr/bin/php -f /home/bitrix/ext_www/site.com/bitrix/php_interface/cron_events.php >> /home/bitrix/.bx_temp/site.com/log/cron_events.log 2>&1
* * * * * sleep 20 ; /usr/bin/php -f /home/bitrix/ext_www/site.com/bitrix/php_interface/cron_events.php >> /home/bitrix/.bx_temp/site.com/log/cron_events.log 2>&1
* * * * * sleep 30 ; /usr/bin/php -f /home/bitrix/ext_www/site.com/bitrix/php_interface/cron_events.php >> /home/bitrix/.bx_temp/site.com/log/cron_events.log 2>&1
* * * * * sleep 40 ; /usr/bin/php -f /home/bitrix/ext_www/site.com/bitrix/php_interface/cron_events.php >> /home/bitrix/.bx_temp/site.com/log/cron_events.log 2>&1
* * * * * sleep 50 ; /usr/bin/php -f /home/bitrix/ext_www/site.com/bitrix/php_interface/cron_events.php >> /home/bitrix/.bx_temp/site.com/log/cron_events.log 2>&1
What alternative methods exist for running tasks every 10 seconds in CentOS 9 Stream, and why did the standard approach with SLEEP stop working?
The SLEEP Approach in CentOS 9 Stream: Why It No Longer Works and Systemd Timer Solutions
In CentOS 9 Stream, the standard approach using multiple entries in crontab with the SLEEP command has stopped working due to changes in the service management system and cron behavior. The primary alternative is systemd timers, which provide a more modern and reliable mechanism for executing tasks with second-level precision.
Table of Contents
- Problem with SLEEP in CentOS 9 Stream
- Why the Old Method Doesn’t Work
- Solution with Systemd Timers
- Alternative Methods for Executing Tasks Every 10 Seconds
- Configuring and Managing Systemd Timers
- Comparison of Cron and Systemd Timers
- Conclusion
Problem with SLEEP in CentOS 9 Stream
The standard approach that worked in CentOS 7 with multiple crontab entries and the SLEEP command no longer functions correctly in CentOS 9 Stream. As research indicates, cron was originally designed to run tasks every minute, and attempts to bypass this limitation with SLEEP can lead to unpredictable behavior[source].
In your example with six entries, each using a sleep command with delays of 0, 10, 20, 30, 40, and 50 seconds, the system in CentOS 9 Stream either doesn’t execute the tasks at all or doesn’t write logs, indicating changes in the cron daemon’s operation or related system components.
Why the Old Method Doesn’t Work
There are several reasons why the SLEEP approach no longer works in CentOS 9 Stream:
-
Systemd Changes: CentOS 9 Stream uses a newer version of systemd that manages services and timers differently compared to CentOS 7[source].
-
Cron Limitations: As noted in research, cron is not designed to run tasks more frequently than once per minute, and all attempts to bypass this limitation are considered “hacks”[source].
-
Synchronization Issues: Research shows that sleep commands in cron can have synchronization problems, especially when creating crontab files at specific times[source].
-
Changes in Cron Behavior: CentOS 9 Stream may include changes in how cron handles parallel tasks or delayed tasks.
Solution with Systemd Timers
The most reliable and modern solution for running tasks every 10 seconds in CentOS 9 Stream is to use systemd timers. Systemd timers offer several advantages over cron:
- Second-level Precision: Unlike cron, which is limited to minute-level precision, systemd timers allow specifying execution with second-level accuracy[source]
- Reliability: Systemd timers guarantee task execution even if the system was powered off at the scheduled time[source]
- Dependency Management: Ability to specify dependencies between services and timers
- Better Parallel Task Management: If a task takes longer than the interval between executions, systemd will delay the next run, unlike cron which might launch multiple instances of the task simultaneously[source]
Creating a Systemd Service and Timer
To run your PHP script every 10 seconds, we’ll create two files: a service and a timer.
1. Create the service file /etc/systemd/system/cron-events.service:
[Unit]
Description=Run cron_events script every 10 seconds
After=network.target
[Service]
Type=simple
ExecStart=/usr/bin/php -f /home/bitrix/ext_www/site.com/bitrix/php_interface/cron_events.php
User=bitrix
Group=bitrix
StandardOutput=file:/home/bitrix/.bx_temp/site.com/log/cron_events.log
StandardError=file:/home/bitrix/.bx_temp/site.com/log/cron_events.log
2. Create the timer file /etc/systemd/system/cron-events.timer:
[Unit]
Description=Run cron_events script every 10 seconds
Requires=cron-events.service
[Timer]
Unit=cron-events.service
OnUnitInactiveSec=10s
AccuracySec=1s
[Install]
WantedBy=timers.target
3. Enable and start the timer:
systemctl daemon-reload
systemctl enable cron-events.timer
systemctl start cron-events.timer
4. Check the timer status:
systemctl list-timers --all
Alternative Methods for Executing Tasks Every 10 Seconds
Besides systemd timers, there are other alternative methods:
1. Using a while loop in a separate script
Create a script that runs as a systemd service and contains an infinite loop with a delay:
#!/bin/bash
while true; do
/usr/bin/php -f /home/bitrix/ext_www/site.com/bitrix/php_interface/cron_events.php
sleep 10
done
2. Using anacron with modified configuration
Although anacron is typically designed for periodic tasks with day intervals, it can be configured for more frequent runs, but this is not optimal for 10-second intervals.
3. Using external tools
Consider using specialized tools for monitoring and task execution, such as:
- Supervisor: For process management
- Runit: For service management
- Monit: For monitoring and automatic process startup
Configuring and Managing Systemd Timers
For more detailed systemd timer configuration, you can use the following parameters:
[Timer]
# Run the task every 10 seconds
OnUnitInactiveSec=10s
# Execution accuracy (1 second)
AccuracySec=1s
# Random delay to distribute load
RandomizedDelaySec=1s
# Maximum wait time before execution
Persistent=true
# Run on system boot
OnBootSec=10s
For viewing systemd timer logs, use:
journalctl -u cron-events.service -f
For managing timers:
systemctl stop cron-events.timer # Stop the timer
systemctl start cron-events.timer # Start the timer
systemctl restart cron-events.timer # Restart the timer
systemctl status cron-events.timer # Check status
Comparison of Cron and Systemd Timers
| Criterion | Cron | Systemd Timers |
|---|---|---|
| Precision | Minute-level | Second-level |
| Reliability | Misses tasks when system is off | Executes missed tasks |
| Dependency Management | Limited | Full |
| Parallel Tasks | May launch multiple instances | Delays next execution |
| Configuration | Simple but limited | More complex but powerful |
| Logging | Standard cron logs | Integration with journalctl |
Conclusion
-
Main Problem: The approach using multiple crontab entries with the SLEEP command no longer works in CentOS 9 Stream due to systemd changes and cron behavior modifications.
-
Optimal Solution: Using systemd timers provides a modern, reliable, and precise mechanism for executing tasks at 10-second intervals.
-
Systemd Advantages: Second-level precision, reliable execution of missed tasks, better parallel task management, and integration with the modern service management system.
-
Recommendation: For CentOS 9 Stream, it’s recommended to fully transition to systemd timers for high-frequency tasks, as this is a more reliable and modern solution that will be better supported in future system versions.
-
Next Steps: When transitioning to systemd timers, it’s also advisable to reconsider the task architecture, possibly combining multiple high-frequency tasks into a single, more efficient service.