Node.js correspond parfaitement à notre projet Web, mais il existe peu de tâches de calcul pour lesquelles nous préférerions Python. Nous avons également déjà un code Python pour eux. Nous sommes très préoccupés par la vitesse, quelle est la manière la plus élégante d'appeler un "worker" Python à partir de node.js de manière asynchrone et non bloquante?
127
Réponses:
Pour la communication entre node.js et le serveur Python, j'utiliserais des sockets Unix si les deux processus s'exécutaient sur le même serveur et les sockets TCP / IP sinon. Pour le protocole de marshaling, je prendrais JSON ou un tampon de protocole . Si Python threadé s'avère être un goulot d'étranglement, envisagez d'utiliser Twisted Python , qui fournit la même concurrence d'accès pilotée par les événements que node.js.
Si vous vous sentez aventureux, apprenez clojure ( clojurescript , clojure-py ) et vous obtiendrez le même langage qui s'exécute et interagit avec le code existant sur Java, JavaScript (node.js inclus), CLR et Python. Et vous obtenez un superbe protocole de marshalling en utilisant simplement des structures de données clojure.
la source
Cela ressemble à un scénario où zeroMQ serait un bon ajustement. C'est un framework de messagerie similaire à l'utilisation de sockets TCP ou Unix, mais il est beaucoup plus robuste ( http://zguide.zeromq.org/py:all )
Il existe une bibliothèque qui utilise zeroMQ pour fournir un framework RPC qui fonctionne plutôt bien. Il s'appelle zeroRPC ( http://www.zerorpc.io/ ). Voici le bonjour le monde.
Serveur Python "Hello x":
Et le client node.js:
Ou vice-versa, serveur node.js:
Et le client python
la source
Si vous décidez d'avoir votre worker Python dans un processus séparé (soit un processus de type serveur de longue durée, soit un enfant généré à la demande), votre communication avec lui sera asynchrone du côté node.js. Les sockets UNIX / TCP et la communication stdin / out / err sont intrinsèquement asynchrones dans le nœud.
la source
Je considérerais également Apache Thrift http://thrift.apache.org/
Il peut faire le pont entre plusieurs langages de programmation, est très efficace et prend en charge les appels asynchrones ou synchronisés. Voir toutes les fonctionnalités ici http://thrift.apache.org/docs/features/
Le multi langage peut être utile pour les projets futurs, par exemple si vous souhaitez plus tard faire une partie de la tâche de calcul en C ++, il est très facile de l'ajouter au mix en utilisant Thrift.
la source
J'ai eu beaucoup de succès en utilisant thoonk.js avec thoonk.py . Thoonk exploite Redis (magasin de valeurs-clés en mémoire) pour vous fournir des modèles de flux (pensez publier / souscrire), de files d'attente et de tâches pour la communication.
Pourquoi est-ce mieux que les sockets Unix ou les sockets TCP directs? Les performances globales peuvent être légèrement diminuées, cependant Thoonk fournit une API très simple qui simplifie le traitement manuel d'une socket. Thoonk contribue également à rendre très simple la mise en œuvre d'un modèle de calcul distribué qui vous permet de mettre à l'échelle vos nœuds de calcul python pour augmenter les performances, car il vous suffit de lancer de nouvelles instances de vos nœuds de calcul python et de les connecter au même serveur redis.
la source
Je recommanderais d'utiliser une file d'attente de travail en utilisant, par exemple, l'excellent Gearman , qui vous fournira un excellent moyen de répartir les tâches en arrière-plan et d'obtenir leur résultat de manière asynchrone une fois qu'elles sont traitées.
L'avantage de cela, largement utilisé chez Digg (parmi beaucoup d'autres), est qu'il fournit un moyen solide, évolutif et robuste de permettre aux travailleurs de n'importe quelle langue de parler avec les clients dans n'importe quelle langue.
la source
Mise à jour 2019
Il existe plusieurs façons d'y parvenir et voici la liste par ordre croissant de complexité
Approche 1 Python Shell Approche la plus simple
fichier source.js
fichier destination.py
Notes : Créez un dossier appelé abonné qui est au même niveau que le fichier source.js et mettez destination.py à l'intérieur. N'oubliez pas de changer votre environnement virtualenv
la source