Comment analyser le code source de Gunicorn Arbiter
Comme mentionné précédemment, Arbiter est au cœur du processus gunicorn master. Arbiter est principalement responsable de la gestion des processus de travail, y compris le démarrage, la surveillance et la suppression des processus de travail. Dans le même temps, Arbiter peut également mettre à jour (recharger) à chaud les applications d'application ou mettre à niveau Gunicorn en ligne lorsque certains signaux se produisent. Le code de base d'Arbiter est dans un seul fichier et la quantité de code n'est pas importante. Le code source est ici : https://github.com/benoitc/gunicorn.
Arbiter dispose principalement des méthodes suivantes :
setup :
Traitement des éléments de configuration, le plus important est le nombre de travailleurs et le modèle de travail du travailleur
init_signal :
Enregistrer la fonction de traitement du signal
handle_xxx :
Les fonctions de traitement spécifiques de chaque signal
kill_worker, kill_workers:
Envoyer un signal au processus de travail
spawn_worker, spawn_workers:
Démarrez un nouveau processus de travail
murder_workers:
Tuer dans un certain laps de temps Processus de travail qui ne répond pas
manage_workers :
En fonction du nombre de travailleurs dans le fichier de configuration et du nombre de travailleurs actuellement actifs, décidez s'il faut bifurquer ou tuer le processus de travail
reexec :
Signal reçu appel SIGUSR2, mise à niveau en ligne gunicorn
reload:
Après avoir reçu le signal appel SIGHUP, le processus de travail sera démarré en fonction de la nouvelle configuration et le processus de travail précédent sera tué
sleep :
Lorsqu'il n'y a pas de traitement du signal, utilisez la sélection du délai d'attente pour dormir et peut être réveillé
wakeup :
En écrivant des messages dans le tuyau, réveillez le processus
run :
Boucle principale
La seule fonction Arbiter qui est réellement appelée par d'autres codes (Application) est __init_ _ et exécute les méthodes, en une phrase de code :
Arbiter(self).run()
Le self dans le code ci-dessus est l'instance d'application. , dans lequel __init__ appelle setup pour définir les éléments de configuration. Voici le pseudo code de la méthode run
def run() self.init_signal() self.LISTENERS = create_sockets(self.cfg, self.log) self.manage_workers() while True: if no signal in SIG_QUEUE self.sleep() else: handle_signal()
À propos du sous-processus fork
Le code du sous-processus fork est dans spawn_worker, le code source est le suivant :
Arbiter.spawn_worker
Processus principal :
(1) Charger work_class et instancier (la valeur par défaut est le modèle synchrone SyncWorker)
(2) Le processus parent (processus maître) revient après le fork et toute la logique ultérieure est exécutée dans l'enfant process
(3) Appelez worker.init_process pour entrer dans la boucle, nouveau canal Tout le travail de la formation IELTS est dans cette boucle
(4) Une fois la boucle terminée, appelez sys.exit(0)
(5) Enfin , enfin, enregistrez la sortie du processus de travail
Ce qui suit est moi-même. J'ai écrit un petit code pour simplifier le processus principal du fork
1 # prefork.py 2 import sys 3 import socket 4 import select 5 import os 6 import time 7 8 def do_sub_process(): 9 pid = os.fork()10 if pid < 0:11 print 'fork error'12 sys.exit(-1)13 elif pid > 0:14 print 'fork sub process %d' % pid15 return16 17 # must be child process18 time.sleep(1)19 print 'sub process will exit', os.getpid(), os.getppid()20 sys.exit(0)21 22 def main():23 sub_num = 224 for i in range(sub_num):25 do_sub_process()26 time.sleep(10)27 print 'main process will exit', os.getpid()28 29 if __name__ == '__main__':30 main()
Sortie dans l'environnement de test :
fork sub. processus 9601
fork sous-processus 9602
le sous-processus quittera 9601 9 600
le sous-processus quittera 9602 9600
Le processus principal quittera 9600
Il convient de noter que la ligne 20 appelle sys.exit assurer la fin du sous-processus, sinon la boucle for dans la fonction principale et la logique ultérieure continueront. Commentez la ligne 19 et réexécutez, et vous comprendrez en regardant le résultat.
À propos de la suppression des processus enfants
Il est très simple pour le processus maître de tuer le processus de travail, il suffit d'envoyer un signal directement, le code source est le suivant :
1 def kill_worker(self, pid, sig): 2 """\ 3 Kill a worker 4 5 :attr pid: int, worker pid 6 :attr sig: `signal.SIG*` value 7 """ 8 try: 9 os.kill(pid, sig)10 except OSError as e:11 if e.errno == errno.ESRCH:12 try:13 worker = self.WORKERS.pop(pid)14 worker.tmp.close()15 self.cfg.worker_exit(self, worker)16 return17 except (KeyError, OSError):18 return19 raise
À propos du sommeil et wakeup
Jetons un coup d'œil au sommeil et au réveil d'Arbiter. L'arbitre "se mettra en veille" lorsqu'il n'y aura pas de signal à traiter. Bien sûr, il n'appellera pas réellement time.sleep, sinon le signal ne sera pas traité immédiatement lorsqu'il arrivera. L'implémentation ici est plus intelligente, utilisant des tuyaux et un délai d'attente sélectionné. Il suffit de regarder le code et vous saurez
def sleep(self): """\ Sleep until PIPE is readable or we timeout. A readable PIPE means a signal occurred. """ ready = select.select([self.PIPE[0]], [], [], 1.0) # self.PIPE = os.pipe() if not ready[0]: return while os.read(self.PIPE[0], 1): pass
Les commentaires dans le code sont très clairs, soit PIPE est lisible et revient immédiatement, soit les délais d'attente expirent. Le tuyau est lisible car un signal se produit. Voici un aperçu de la fonction pipe
os.
pipe
()os.
pipe
()Create a pipe. Return a pair of file descriptors
(r,w)
(r, w)
utilisable respectivement en lecture et en écriture.
Ensuite, regardons quand le tube est lisible : il doit s'agir de quelque chose d'écrit dans le tube. C'est la fonction de la fonction de réveil
def wakeup(self): """ Wake up the arbiter by writing to the PIPE """ os.write(self.PIPE[1], b'.')
Enfin, l'Arbiter est attaché Traitement du signal
: Sortie, INT : Arrêt rapide 🎜🎜TERM : Arrêt progressif. Attend que le travailleur termine sa demande en cours jusqu'à ce que son délai expire. 🎜HUP : rechargez la configuration, démarrez de nouveaux processus de travail avec une nouvelle configuration et arrêtez progressivement les anciens processus de travail. Gunicorn chargera également la nouvelle version si l'application n'est pas préchargée (en utilisant l'option --preload).
TTIN : Augmenter le nombre de processus d'un
TTOU : Diminuer le nombre de processus d'un
USR1 : Rouvrir le fichier journal
USR2 : Mettre à niveau Gunicorn à la volée. Un signal de terme distinct doit être utilisé pour terminer l'ancien processus. Ce signal peut également être utilisé pour utiliser de nouvelles versions préchargées d'applications.
Winch : arrêtez gracieusement les processus de travail lorsque Gunicorn est démonisé.
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!

Outils d'IA chauds

Undresser.AI Undress
Application basée sur l'IA pour créer des photos de nu réalistes

AI Clothes Remover
Outil d'IA en ligne pour supprimer les vêtements des photos.

Undress AI Tool
Images de déshabillage gratuites

Clothoff.io
Dissolvant de vêtements AI

AI Hentai Generator
Générez AI Hentai gratuitement.

Article chaud

Outils chauds

Bloc-notes++7.3.1
Éditeur de code facile à utiliser et gratuit

SublimeText3 version chinoise
Version chinoise, très simple à utiliser

Envoyer Studio 13.0.1
Puissant environnement de développement intégré PHP

Dreamweaver CS6
Outils de développement Web visuel

SublimeText3 version Mac
Logiciel d'édition de code au niveau de Dieu (SublimeText3)

Qu'est-ce que Python GIL, comment fonctionne-t-il et comment affecte-t-il Gunicorn. Quel type d’ouvrier Gunicorn dois-je choisir pour la production ? Python a un verrou global (GIL) qui permet à un seul thread de s'exécuter (c'est-à-dire d'interpréter le bytecode). À mon avis, comprendre comment Python gère la concurrence est essentiel si vous souhaitez optimiser vos services Python. Python et gunicorn vous offrent différentes manières de gérer la concurrence, et comme il n'existe pas de solution miracle couvrant tous les cas d'utilisation, c'est une bonne idée de comprendre les options, les compromis et les avantages de chaque option. Type de travailleur GunicornGunico

Déploiement d'applications Flask : comparaison de Gunicorn et suWSGI Introduction : Flask, en tant que framework Web Python léger, est apprécié par de nombreux développeurs. Lors du déploiement d'une application Flask dans un environnement de production, le choix de l'interface de passerelle serveur (SGI) appropriée est une décision cruciale. Gunicorn et uWSGI sont deux serveurs SGI courants. Cet article les décrira en détail.

Concepts et fonctions de base de Gunicorn Gunicorn est un outil permettant d'exécuter des serveurs WSGI dans des applications Web Python. WSGI (Web Server Gateway Interface) est une spécification définie par le langage Python et permet de définir l'interface de communication entre les serveurs web et les applications web. Gunicorn permet de déployer et d'exécuter des applications Web Python dans des environnements de production en implémentant la spécification WSGI. La fonction de Gunicorn est de

Comment déployer l'application Flask à l'aide de Gunicorn ? Flask est un framework Web Python léger largement utilisé pour développer divers types d'applications Web. Gunicorn (GreenUnicorn) est un serveur HTTP basé sur Python utilisé pour exécuter des applications WSGI (WebServerGatewayInterface). Cet article expliquera comment utiliser Gunicorn pour déployer des applications Flask, avec

Gunicorn est une spécification d'interface de passerelle de serveur Web WSGI (serveur HTTP) écrite en Python. Il s'agit d'un serveur léger et efficace spécialement conçu pour exécuter des applications Web Python. Ses principales caractéristiques et fonctions incluent : 1. Hautes performances, qui peuvent facilement gérer des requêtes simultanées élevées ; 2. Stable et fiable, qui peut fournir un fonctionnement durable à long terme, réduisant considérablement le risque de panne du serveur ; faire Pour maintenir la stabilité du service ; 4. Méthodes de déploiement multiples, etc.

Gunicorn et Flask : La combinaison de déploiement parfaite, nécessitant des exemples de code spécifiques Présentation : Il est très important pour les développeurs de choisir la méthode de déploiement appropriée, notamment pour les applications Web Python. Parmi les frameworks Web Python, Flask est un choix très populaire et Gunicorn est un serveur permettant de déployer des applications Python. Cet article présentera la combinaison de Gunicorn et Flask et fournira quelques exemples de code spécifiques pour aider les lecteurs.

LINUX est un système d'exploitation puissant largement utilisé dans les serveurs et les environnements de développement. CentOS est un système d'exploitation open source basé sur Red Hat Enterprise Linux (RHEL) et largement utilisé dans les environnements de serveur. L'installation de Gunicorn et le partitionnement sur CentOS peuvent améliorer les performances. du serveur. Performances et sécurité, cet article détaillera comment installer Gunicorn sur CentOS et comment le partitionner. Installer Gunicorn sur CentOS Gunicorn est un serveur Python WSGIHTTP permettant d'exécuter des applications Web Python. Voici comment installer Gunicorn sur CentOS.

Comment Gunicorn améliore-t-il les performances des applications Flask ? Avec le développement rapide d'Internet, les performances des applications Web sont devenues de plus en plus importantes pour l'expérience utilisateur et la compétitivité des entreprises. Lors du traitement de requêtes simultanées élevées, le serveur de développement par défaut du framework Flask ne peut souvent pas répondre à la demande. Par conséquent, nous devons utiliser Gunicorn (GreenUnicorn) pour améliorer les performances des applications Flask. Gunicorn est un serveur HTTP basé sur Python qui utilise des
