In planning tasks, you will occasionally see repetitive execution:
Examples of our company's planned tasks are as follows:
*/2 * * * * root cd /opt/xxxx/test_S1/html/xxxx/admin; php index.php task testOne >/dev/null 2>&1 */2 * * * * root cd /opt/xxxx/test_S1/html/xxxx/admin; php index.php task testTwo >/dev/null 2>&1
This is a two-minute task. It does not guarantee that every process can be completely closed in two minutes. If the process keeps piling up, the system resources may be exhausted, resulting in system downtime.
Give an example:
New test.php file, code as follows:
<?php sleep(70); ?>
Add scheduled tasks:
*/1 * * * * root cd /home/ganjincheng;php test.php
Waiting for execution, piling up
root 26722 0.0 0.0 9232 1064 ? Ss 12:05 0:00 /bin/sh -c cd /home/ganjincheng;php test.php root 26744 0.0 0.0 112304 8840 ? S 12:05 0:00 php test.php root 29102 0.0 0.0 9232 1060 ? Ss 12:06 0:00 /bin/sh -c cd /home/ganjincheng;php test.php root 29116 0.1 0.0 112304 8840 ? S 12:06 0:00 php test.php root 29906 0.0 0.0 103320 904 pts/3 S+ 12:06 0:00 grep test.php
Solution
The first is to control concurrency in code
This method is to transform the code. Increase the judgment of whether there is process execution or not. The following code:
<?php $lockfile = '/tmp/mytest.lock'; if(file_exists($lockfile)){ exit(); } file_put_contents($lockfile, date("Y-m-d H:i:s")); sleep(70); unlink($lockfile); ?>
This way of judging whether a document does not exist is problematic. That is, it is possible that the program has not been executed to the end, that is, the mytest.lock file created before has not been deleted. This will cause the program to fail to execute properly afterwards.
Second, database controls concurrency
The first scheme can be transferred to redis, memache for key value judgment.
If the planned task is to access the database, the lock table operation can be performed. Occasionally, we can also use the uniqueness of the unique index and the joint index to avoid repeated insertions.
Third, determine whether the process exists
Give an example:
$fp = popen("ps aux | grep 'test.php' | wc -l", "r"); $proc_num = fgets($fp); if ($proc_num > 3) { //Here we should pay attention to why the number of processes is greater than 3. Once you have done it, you will understand. exit; } sleep(70);
The disadvantage of this method is that the ps command should be written accurately. Avoid counting processes that are not executing test.php scripts. Such as:
We open the test.php file through vim. This will cause the above commands to be mistakenly counted. So when we accidentally open the test.php file by vim, we can't execute it.
Fourth, use the flock command of linux
Let linux help us to judge ah, the flock command provides the function of file lock. The command parameters are as follows:
[root@qkzj_Multi-Purpose_1A_113.107.248.124 ganjincheng]# flock -h flock (util-linux-ng 2.17.2) Usage: flock [-sxun][-w #] fd# flock [-sxon][-w #] file [-c] command... flock [-sxon][-w #] directory [-c] command... -s --shared Get a shared lock -x --exclusive Get an exclusive lock -u --unlock Remove a lock -n --nonblock Fail rather than wait -w --timeout Wait for a limited amount of time -o --close Close file descriptor before running command -c --command Run a single command string through the shell -h --help Display this text -V --version Display version
Examples of configuration:
*/1 * * * * root flock -xn /tmp/mytest.lock -c 'php ./test.php'