Mysql
 sql >> Base de données >  >> RDS >> Mysql

Comment gérer les processus côté serveur à l'aide de MySQL

Il semble que vous essayez de lancer des processus de longue durée à partir d'un serveur Web, puis de suivre ces processus dans une base de données. Ce n'est pas impossible, mais ce n'est pas une pratique recommandée.

Le principal problème est qu'une requête HTTP doit être actuellement traitée sur votre serveur Web car vous le faites réellement faites n'importe quoi (y compris les processus de suivi en cours d'exécution sur le système) - vous avez besoin de quelque chose qui peut fonctionner tout le temps...

Au lieu de cela, une meilleure idée serait d'avoir un autre processus de "gestionnaire" démonisé (comme vous le mentionnez perl, ce serait un bon langage pour l'écrire) générer et suivre les tâches de longue durée (par PID et signaux), et pour cela processus pour mettre à jour votre base de données SQL.

Vous pouvez ensuite demander à votre processus "gestionnaire" d'écouter les demandes de démarrage d'un nouveau processus à partir de votre serveur Web. Il existe différents mécanismes IPC que vous pouvez utiliser. (par exemple :signaux, shm SysV, sockets de domaine unix, files d'attente en cours de processus comme ZeroMQ, etc.).

Cela a de multiples avantages :

  • Si vos scripts générés doivent s'exécuter avec une isolation basée sur l'utilisateur/le groupe (soit du système, soit les uns des autres), votre serveur Web n'a pas besoin de s'exécuter en tant que root, ni d'être setgid.
  • Si un processus généré "plante", un signal sera envoyé au processus "gestionnaire", afin qu'il puisse suivre les erreurs d'exécution sans problème.
  • Si vous utilisez des files d'attente en cours de processus (par exemple :ZeroMQ) pour envoyer des requêtes au processus "gestionnaire", il peut "limiter" les requêtes du serveur Web (afin que les utilisateurs ne puissent pas intentionnellement ou accidentellement provoquer un D.O.S).
  • Que le processus généré se termine bien ou non, vous n'avez pas besoin d'une requête HTTP "active" adressée au serveur Web pour mettre à jour votre base de données de suivi.

Quant à savoir si quelque chose qui devrait être en cours d'exécution est en cours d'exécution, c'est vraiment à votre sémantique. (c'est-à-dire :est-il basé sur un temps d'exécution connu ? Basé sur les données consommées ? etc.).

La vérification pour savoir si c'est l'est courir peut être double :

  1. Le processus "gestionnaire" met à jour la base de données selon les besoins, y compris le PID généré.
  2. Le code hébergé sur votre serveur Web peut en fait répertorier les processus pour déterminer si le PID dans la base de données est réellement en cours d'exécution, et même combien de temps il a fait quelque chose d'utile !

La vérification pour savoir si ce n'est pas l'exécution devrait être basée sur une convention :

  1. Nommez les processus générés de manière prévisible.
  2. Obtenez une liste de processus pour déterminer ce qui est encore en cours d'exécution (obsolète ?) et qui ne devrait pas l'être.

Dans les deux cas, vous pouvez soit informer les utilisateurs qui ont demandé que les processus soient générés et/ou faire quelque chose à ce sujet.

Une approche pourrait être d'avoir un travail CRON qui lit à partir de la base de données SQL et fait ps pour déterminer quels processus générés doivent être redémarrés, puis redemande que le processus "gestionnaire" le fasse en utilisant le même mécanisme IPC que celui utilisé par le serveur Web. C'est à vous de décider comment différencier les démarrages des redémarrages dans votre suivi/surveillance/journalisation.

Si le serveur lui-même perd de l'alimentation ou tombe en panne, vous pouvez demander au processus "gestionnaire" d'effectuer un nettoyage lors de sa première exécution, par exemple :

  1. Recherchez dans la base de données les entrées des processus générés qui étaient censés s'exécuter avant l'arrêt du serveur.
  2. Vérifier ces processus par PID et durée d'exécution (c'est important).
  3. Soit régénérer les processus générés qui ne se sont pas terminés, soit stocker quelque chose dans la base de données pour indiquer au serveur Web que c'était le cas.

Mise à jour #1

D'après votre commentaire, voici quelques conseils pour commencer :

Vous avez mentionné perl, donc en supposant que vous en ayez une certaine maîtrise -- voici quelques modules perl pour vous aider à écrire le script de processus "manager":

Si vous ne le connaissez pas déjà CPAN est le référentiel pour les modules perl qui font pratiquement n'importe quoi.

Daemon::Daemonize - Pour démoniser le processus afin qu'il continue à s'exécuter après votre déconnexion. Fournit également des méthodes pour écrire des scripts pour démarrer/arrêter/redémarrer le démon.

Proc::Spawn - Aide à "engendrer" des scripts enfants. En gros, fait fork() puis exec() , mais gère également STDIN/STDOUT/STDERR (ou même tty) du processus enfant. Vous pouvez l'utiliser pour lancer vos scripts perl de longue durée.

Si le code frontal de votre serveur Web n'est pas déjà écrit en perl, vous aurez besoin de quelque chose d'assez portable pour la transmission de messages et la mise en file d'attente entre les processus. Je ferais probablement de votre serveur Web une interface facile à déployer (comme PHP).

Voici deux possibilités (il y en a beaucoup plus):

Proc::ProcessTable - Vous pouvez utiliser cette vérification sur les processus en cours d'exécution (et obtenir toutes sortes de statistiques, comme indiqué ci-dessus).

Heure ::HiRes - Utilisez les fonctions temporelles à haute granularité de ce package pour implémenter votre cadre de "limitation". En gros, limitez simplement le nombre de requêtes que vous retirez de la file d'attente par unité de temps.

DBI (avec mysql ) - Mettez à jour votre base de données MySQL depuis le processus "manager".