Kronob - how to do it right?

A very common need for an application is to run a script every X minutes / hours. Essentially nothing complicated, just PHP code and a crontab entry.

Despite the fact that in recent years I wrote a lot of such crowns, I still have not seen any best practices, at least not so many. As with every “background processing”, many things can go wrong, especially in a production environment.

Among them:

  • an error occurred while executing cron and script died processing half the data
  • cronjob was accidentally run twice by another process / by user error / whatever
  • cronjob took much longer than expected, and the script is called again, although its not processed data
  • and etc.

What are the best grades for writing reliable, reliable cronjob scripts? Writing a lock file stating that only one instance is running, extended log and monitoring in another to prevent ten thousand duplicate emails from being sent? What are your ideas?

+7
source share
2 answers

Personally, the way to handle errors is to simply send STDERR to the log file, and then periodically check this file. An easy way to do this is to add 2> / pathtolog to the crontab entry.

As for duplicates of the same program, I prefer that the script try to block something (file or local network port). If he could not get this lock, the script does not run. Thus, if an existing script is currently running, the new one cannot get an identical lock.

+2
source

There are many things you can do.

Install your cron scripts / binaries (scripts which I think since you mentioned that they are written in PHP) are executed by the owner or group depending on your needs.

If you want to make sure that they are run only by cron, then create the cron user, which is the only user who can execute the script. Then set this user to run in your crontab entry.

Your cron script displays the important things that it does. Prepare your result with a time / date stamp (depending on how often it works). This makes grep easier for a specific time in your log file.

Add the stdout script file to the log file by adding >> /path/cron.log to your crontab entry.

You can also print the start and end times of your cronjob so that you can analyze the log every once in a while to make sure it is not too slow.

Your log file might look something like this:

 [ Tue Feb 20, 2012 ]: [ Tue Feb 20, 2012 ]: Executing mycron.php [ Tue Feb 20, 2012 ]: [ Tue Feb 20, 2012 ]: Running Query: ""SELECT SUM(`clicks`) FROM `matable`"" [ Tue Feb 20, 2012 ]: Running Query: ""INSERT INTO `History` (`date`, `total_clicks`) VALUES(CURDATE(), 12324123) [ Tue Feb 20, 2012 ]: [ Tue Feb 20, 2012 ]: Finished executing mycron.php. Time taken: 3.462 seconds [ Tue Feb 21, 2012 ]: [ Tue Feb 21, 2012 ]: Executing mycron.php [ Tue Feb 21, 2012 ]: [ Tue Feb 21, 2012 ]: Running Query: ""SELECT SUM(`clicks`) FROM `matable`"" [ Tue Feb 21, 2012 ]: Running Query: ""INSERT INTO `History` (`date`, `total_clicks`) VALUES(CURDATE(), 10376123) [ Tue Feb 21, 2012 ]: [ Tue Feb 21, 2012 ]: Finished executing mycron.php. Time taken: 2.998 seconds 

Except for what he does instead of these two random queries, of course.

0
source

All Articles