Maison > Article > développement back-end > Comment résoudre les conflits de concurrence lors de l'exécution d'un script crond ?
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
Cette méthode consiste à transformer le code. Ajoutez le jugement quant à l'exécution du processus. Par exemple, le code suivant :
<?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); ?>
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.
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
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é.
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!