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

零下一度
Libérer: 2023-03-10 18:24:02
original
1379 Les gens l'ont consulté

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
Copier après la connexion

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);?>
Copier après la connexion

Ajoutez une tâche planifiée :

*/1 * * * * root cd /home/ganjincheng;php test.php
Copier après la connexion

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
Copier après la connexion

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);  
?>
Copier après la connexion

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);
Copier après la connexion

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
Copier après la connexion

Exemple de configuration :

*/1 * * * * root flock -xn /tmp/mytest.lock -c 'php ./test.php'
Copier après la connexion

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!

Étiquettes associées:
source:php.cn
Déclaration de ce site Web
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
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal