10
votes

Travail cron pour script php nécessitant un temps d'exécution très long

J'ai un script PHP exécuté en tant que travail cron qui exécute un ensemble de tâches simples qui bouclent pour chaque utilisateur dans la base de données et prend environ 30 minutes à compléter. Ce processus commence chaque heure et doit être aussi rapide et efficace que possible. Le problème que je possède, c'est comme avec n'importe quel script de serveur, le temps d'exécution varie et j'ai besoin de comprendre les meilleurs paramètres de temps de cron.

Si je manquais de cron toutes les minutes, j'ai besoin d'arrêter la dernière boucle du script 20 secondes avant la fin de la minute pour vous assurer que la boucle actuelle se termine à temps. Au cours de l'heure, cela ajoute à beaucoup de temps perdu.

Je me demandais si c'est une mauvaise idée de simplifier la limite de temps d'exécution PHP et exécutez le script une fois par heure et laissez-la courir à l'achèvement ... est-ce une mauvaise idée?


3 commentaires

Votre travail cron appelait-il un site Web exécutant PHP ou en utilisant PHP à partir de la ligne de commande? Je ne comprends pas complètement le deuxième paragraphe - pourquoi arrêtez-vous le traitement et le redémarrage de chaque minute?


Je pense que vous pouvez obtenir des réponses plus productives ici si vous expliquez ce que le travail doit faire. Il peut y avoir un moyen plus efficace de le faire.


Si vous appelez un travail de cron à exécution longue à l'aide de WGET, envisagez de définir le nombre d'essais à 1 à l'aide de -T 1 afin que cela ne soit appelé qu'une seule fois.


8 Réponses :


0
votes

J'ai utilisé l'interface de ligne de commande PHP pour des tâches de fonctionnement similaires dans le passé. Vous ne souhaitez probablement pas supprimer la limite de temps d'exécution pour une demande.


0 commentaires

0
votes

Cela ressemble à une bonne idée s'il y a peu de chance qu'il faudra plus d'une heure. Notez cependant que le mauvais bogue peut être un très bon moyen de le faire prendre plus de temps que prévu.

Pour éviter toutes sortes de problèmes méchants, vous devez avoir un fichier de garde avec l'ID de processus du script. Lors du démarrage, vous devez vérifier que le fichier n'existe pas, ou s'il le fait que l'ID de processus dans le fichier n'existe pas (à travers un appel à tuer (PID, 0)). Si ces conditions sont remplies, créez un nouveau fichier avec le PID du script et supprimez le fichier lorsque vous avez terminé.

C'est le même truc que de nombreux démons utilisent pour s'assurer que cela ne fonctionne pas déjà. Si le démon a été tué soudainement, le fichier existera toujours, mais il est peu probable que le PID du processus est peu susceptible de fonctionner.


0 commentaires

1
votes

Réglage de la limite de temps à 0 et le laisser faire sa chose est assez typique des cronjobs basés sur PHP (dans mon expérience), mais c'est aussi le point que vous devriez vous poser quelques questions importantes, telles que "Devrais-je réécrire ce travail dans une langue compilée? " et "suis-je en train d'utiliser tous mes outils (base de données, etc.) à leur efficacité maximale?"

Cela dit, peut-être mieux que de supprimer complètement le délai imparti pour la définir dans la limite supérieure que vous souhaitez réellement. Si cela signifie 48 minutes, alors set_time_limit (48 * 60);


0 commentaires

0
votes

En fonction de votre script, cela peut entraîner des problèmes si vous supprimez la limite de temps. Si par exemple, vous interrogez un serveur externe qui ne répond pas tandis que le travail est en cours d'exécution et que votre cron prend 2 heures au lieu de 30 minutes à compléter, vous pouvez obtenir une pile de processus PHP étant tiré même si les précédents Haven. 't complété encore. Cela peut provoquer une instabilité et des accidents du système.

Vous avez probablement deux options:

  • Assurez-vous qu'aucune autre instance de votre script ne fonctionne à l'avance, sinon quittez () le début.
  • envisager de changer votre cronjob en démon.

0 commentaires

1
votes

Je pense vraiment que vous ne devriez pas définir le temps sur 0, c'est juste à la recherche de problèmes. Au plus, définissez-la à 59 * 60 secondes, mais la définition à 0 pourrait provoquer des problèmes de sécurité, si une script est suspendue, elle restera presque pour toujours jusqu'à ce que l'hôte du serveur arrête l'exécution. Il est considéré comme une mauvaise pratique de le faire.


0 commentaires

0
votes

a-t-il à courir horaire comme des horlogères?

Si non divisé le travail (vous avez mentionné que c'était plus d'une tâche simple) faire chaque tâche toutes les heures?

ou diviser par utilisateur, faites A-M heure, puis N-Z le suivant?


0 commentaires

8
votes

En supposant que vous souhaitez que le travail soit dès que possible, n'utilisez pas de cron. Cron est bon pour les choses qui doivent se passer à des moments précis. Il est souvent abusé de simuler un processus d'arrière-plan qui traiterait idéalement le travail dès que le travail apparaît. Vous devriez probablement écrire un démon qui fonctionne continuellement. (Remarque: vous pouvez également consulter un système de type MESSAGE / WHOW-WHOW-WHOW-WHOWEE, il y a de belles bibliothèques pour le faire aussi)

Vous pouvez écrire un démon à partir de zéro à l'aide du Fonctions PCNTL (puisque vous ne vous souciez pas de plusieurs processus de travail, c'est super-easy pour obtenir un processus en marche en arrière-plan.) ou tricher et simplement faire un script qui fonctionne pour toujours et exécutez-le via Écran ou exploiter un code de bibliothèque solide, tels que la poire système : Daemon ou Nanoserv

Une fois que le truc de démonisation est pris en charge, tout ce que vous vous souciez vraiment de a une boucle qui fonctionne pour toujours. Vous voudrez veiller à ce que votre script ne fuit pas de mémoire ni de consommer trop de ressources.

Généralement, vous pouvez faire quelque chose comme: xxx

et il fonctionnera assez bien.


2 commentaires

Et si le fichier php.ini a max_execution_time = 30?, le script va se terminer après 30 secondes.


@Kiranmaniya - Nope! Vous le penseriez, mais PHP-CLI ignore la valeur. Écrivez un script de test trivial et voyez par vous-même.



8
votes

au lieu de régler le max_execution_time Vous pouvez également utiliser set_time_limit () à Réinitialiser le compteur sur chaque boucle. Cela s'assurera que votre script ne manque jamais de temps à moins que quelque chose de grave est suspendu dans la boucle actuelle (et de prendre plus de plus que le max_execution_time).

Fondamentalement, cela devrait faire fonctionner votre script tant qu'il en a besoin en lui donnant un délai de 30 secondes entre deux set_time_limit () appels.


1 commentaires

C'est un bon conseil. Je ne suis pas sûr de savoir pourquoi vous n'avez pas assez de votes.