Running a php application on windows - daemon or cron?

I need recommendations for implementation. I have a MYSQL database that will be written remotely so that tasks are processed locally, and I need my application written in PHP to perform these tasks imediatly as they become available.

But, of course, my PHP application should be told when to run. I was thinking about using cron jobs, but my application is on a windows machine. Secondly, I need to constantly check every few seconds, and cron can only do every minute.

I was thinking of writing a PHP daemon, but I get a job invitation, and even if it's a good idea!

I would appreciate any advice on how to do this.

+6
source share
8 answers

pyCron is a good CRON alternative for Windows:

pyCron

Since this task is quite simple, I would just setup pyCron to run the following script every minute:

set_time_limit(60); // one minute, same as CRON ;) ignore_user_abort(false); // you might wanna set this to true while (true) { $jobs = getPendingJobs(); if ((is_array($jobs) === true) && (count($jobs) > 0)) { foreach ($jobs as $job) { if (executeJob($job) === true) { markCompleted($job); } } } sleep(1); // avoid eating unnecessary CPU cycles } 

Thus, if the computer goes down, you will have the worst delay of 60 seconds.

You may also need to study semaphores or some kind of blocking strategy, for example, use the APC variable or check for a block file to avoid race conditions using APC, for example:

 set_time_limit(60); // one minute, same as CRON ;) ignore_user_abort(false); // you might wanna set this to true if (apc_exists('lock') === false) // not locked { apc_add('lock', true, 60); // lock with a ttl of 60 secs, same as set_time_limit while (true) { $jobs = getPendingJobs(); if ((is_array($jobs) === true) && (count($jobs) > 0)) { foreach ($jobs as $job) { if (executeJob($job) === true) { markCompleted($job); } } } sleep(1); // avoid eating unnecessary CPU cycles } } 

If you stick with the PHP daemon, do yourself a favor and skip this idea, use Gearman instead.

EDIT . I asked a related question that may interest you: Anatomy of a distributed system in PHP .

+8
source

I suggest something unusual: you said that you need to run the task at the moment when the data is written to MySQL. This means that MySQL “knows” something must be done. This sounds like the perfect script for MySQL UDF sys_exec .

Basically, it would be nice if MySQL could call an external program as soon as something happened to it. If you use the mentioned UDF, you can execute the PHP script from within - let them say an INSERT or UPDATE trigger. On the other hand, you can make it more resource-friendly and create a MySQL event (assuming you are using the appropriate version) that will use sys_exec to invoke a PHP script that performs certain updates at predetermined intervals, which reduces the need for Cron or any similar program that can execute anything at predetermined intervals.

+3
source

I definitely do not recommend using a cronjob for this.

cronjobs is good and very useful and easy for many purposes, but as you describe your needs, I think that they can create more complications than they do well. Here are a few things to consider:

  • What happens if jobs overlap? execution takes longer than one minute? Are there shared resources / locks / temporary files? - The most common method is to use a lock file and terminate if it is busy at the very beginning of the program. but the program should also look for additional tasks immediately before its completion. - this, however, can also get complicated on Windows machines because they AFAIK do not support write locks out of the box.

  • cronjobs is a pain in the ass to maintain. if you want to control them, you need to implement additional logic, for example, checking when the last program was launched. this can be difficult if your program should run only on demand. the best way would be some kind of "filling the job" in the database or deleting the rows that were processed.

  • on most unix based systems, cronjobs are pretty stable, but there are many situations where you can crash your cronjob system. most of them are based on human error. for example, sysadmin, which does not exit the crontab editor in the correct mode, can delete all cronjob. many companies also do not have an adequate monitoring system for the above reasons and notify as soon as their services experience problems. at the moment, often no one has recorded / entered into version control, which cronjobs should run, and wild guessing and recovery begins.

  • Cronjob support can be even more complicated when external tools are used and the environment is not its own unix system. sysadmins need to gain knowledge of more programs, and they may have potential errors.

I honestly think this is a small script that you run from the console, and let open fine.

 <?php while(true) { $job = fetch_from_db(); if(!$job) { sleep(10) } else { $job->process(); } } 

you can also touch the file (change the modification timestamp) in each loop, and you can write a nagios script that checks that this timestamp is out of date, so you know that your work is still working ...

if you want it to start with the system, I recommend deamon.

ps: the company I work for has a lot of background activity for our site (crawl, update processes, calculations, etc.), and cronjobs were a real mess when I started there. they were distributed across different servers responsible for different tasks. Databases were accessed wildly over the Internet. a ton of nfs filesytems, samba, etc. were available for sharing resources. the place was full of single points of failure, bottlenecks and something constantly broke. there was so much technology that it was very difficult to maintain, and when something didn’t work, it took him hours to track the problem and another hour of what that part was supposed to do.

Now we have one unified update program that is responsible for literally everything, it works on several servers, and they have a configuration file that determines the tasks that are performed. eveyrthing is dispatched from one parent process, executing an infinite loop. It is easy to control, configure, synchronize and everything works smoothly. it is redundant, it is synchronized and the granularity is beautiful. therefore, it runs in parallel, and we can scale to as many servers as we like.

I really suggest sitting down long enough to think about everything in general and get a picture of the complete system. then take the time and effort to implement a solution that will function well in the future and will not distribute many different programs on your system.

imp:

I read a lot about the minimum interval of 1/5 minutes for cronjobs / tasks. you can easily get around this with an arbitrary script that takes this interval:

 // run every 5 minutes = 300 secs // desired interval: 30 secs $runs = 300/30; // be aware that the parent interval needs to be a multiple of the desired interval for($i=0;$i<$runs;$i++) { $start = time(); system('myscript.php'); sleep(300/10-time()+$start); // compensate the time that the script needed to run. be aware that you have to implement some logic to deal with cases where the script takes longer to run than your interavl - technique and problem described above } 
+2
source

It looks like work for a job server;) See Gearman . An additional advantage of this approach is that it is initiated by the remote side when and only if there is something to do, instead of polling. Especially in periods of less than (say) a 5-minute survey is not very effective, depending on the tasks performed by the work.

+1
source

A quick and dirty way is to create a loop that constantly checks to see if there is a new job.

pseudo-users code

 set_ini("max_execution_time", "3600000000"); $keeplooping = true; while($keeplooping){ if(check_for_work()){ process_work(); } else{ sleep(5); } // some way to change $keeplooping to false // you don't want to just kill the process, because it might still be doing something } 
0
source

Have you tried the window scheduler (the default is Windows)? In this you will need to specify the php path and your php file path. He works well

0
source

Can't you just write a java / C ++ program that will ask you at a given time interval? You can include this in the list of boot programs so that it always works. After a task is found, it can process it on a separate thread and process more requests and mark others.

0
source

The easiest way is to use the built-in Windows schedule.

Run the script using php-cli.exe with filled php.ini with the extensions needed for the script.

But I must say that in practice you do not need such a short period of time to complete the scheduled tasks. Just do a few tests to get the best time interval value for yours. It is not recommended to set the time interval to less than 1 minute.

And some more tips: make some lock file at the beginning of your script (php flock function), check for an entry in this lock file to prevent two or more copies from working at the same time and at the end your script will disconnect it after unlocking.

If you need to write the output result to the database, try using MySQL TRIGGERS instead of PHP. Or use events in MySQL.

0
source

Source: https://habr.com/ru/post/886494/


All Articles