Maison  >  Article  >  développement back-end  >  Comment résoudre les conflits de concurrence lors de l'exécution d'un script crond ?

Comment résoudre les conflits de concurrence lors de l'exécution d'un script crond ?

零下一度
零下一度original
2017-06-23 14:31:501361parcourir

Dans les tâches planifiées, vous verrez occasionnellement des exécutions répétées :

Par exemple, les tâches planifiées de notre entreprise :

*/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

Cela dure deux minutes Exécuter une tâche once ne garantit pas que chaque processus démarré puisse être complètement terminé et fermé dans les deux minutes. Si les processus continuent de s'accumuler, les ressources du système peuvent être épuisées, entraînant un temps d'arrêt du système.

Exemple :

Créez un nouveau fichier test.php avec le code suivant :

<?php
sleep(70);?>

Ajoutez une tâche planifiée :

*/1 * * * * root cd /home/ganjincheng;php test.php

En attente d'exécution, une accumulation se produit

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

Tout d'abord, contrôlez la concurrence dans le code

Cette méthode consiste à transformer le code. Ajoutez le jugement quant à l'exécution du processus. Par exemple, le code suivant :

<?php  
$lockfile = &#39;/tmp/mytest.lock&#39;;  
   
if(file_exists($lockfile)){  
    exit();  
}
file_put_contents($lockfile, date("Y-m-d H:i:s"));
   
sleep(70);
 
unlink($lockfile);  
?>

Il y a un problème avec cette façon de déterminer si un fichier n'existe pas. Autrement dit, il est possible que le programme n'ait pas été exécuté jusqu'à la fin, c'est-à-dire que le fichier mytest.lock précédemment créé n'ait pas été supprimé. Cela empêchera le programme de s’exécuter correctement à l’avenir.

Deuxièmement, la concurrence contrôlée par la base de données

La première solution peut être transférée vers Redis et Memache pour un jugement de valeur clé.

Si la tâche planifiée consiste à accéder à la base de données, vous pouvez effectuer des opérations de verrouillage de table. Parfois, nous pouvons également utiliser le caractère unique de l'index unique et de l'index conjoint pour éviter des insertions répétées

La troisième méthode consiste à déterminer si le processus existe

Exemple :

$fp = popen("ps aux | grep 'test.php' | wc -l", "r");
$proc_num = fgets($fp);if ($proc_num > 3) { //这里要注意为什么进程数要大于3,实际操作一遍你就明白了exit;
}
sleep(70);

Un inconvénient de cette méthode est que la commande ps doit être écrite avec précision. Évitez de compter les processus qui n'exécutent pas le script test.php. Par exemple :
Nous ouvrons le fichier test.php via vim. Cela entraînera un décompte incorrect de la commande ci-dessus. Ainsi, lorsque nous ouvrons accidentellement le fichier test.php dans vim, il ne peut pas être exécuté.

La quatrième méthode consiste à utiliser la commande flock de Linux

Laissez Linux nous aider à juger. La commande flock fournit la fonction de verrouillage de fichier. Les paramètres de la commande sont les suivants :

[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

Exemple de configuration :

*/1 * * * * root flock -xn /tmp/mytest.lock -c 'php ./test.php'

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn