Maison  >  Article  >  interface Web  >  Explication détaillée de plusieurs méthodes de mise en œuvre de la communication de processus dans le nœud

Explication détaillée de plusieurs méthodes de mise en œuvre de la communication de processus dans le nœud

青灯夜游
青灯夜游avant
2021-12-14 19:04:514868parcourir

nodeComment communiquer entre processus ? L'article suivant vous aidera à comprendre les méthodes de communication des processus de nœud et comment implémenter ces méthodes de communication dans node. J'espère qu'il vous sera utile !

Explication détaillée de plusieurs méthodes de mise en œuvre de la communication de processus dans le nœud

La communication couvre en fait tous les niveaux de développement. Les plus courants incluent la communication client et serveur via divers protocoles de communication, la communication RPC, la communication mutuelle entre les différents modules pendant le processus de développement et entre le processus électronique principal et le processus de rendu. entre les nœuds, etc.

Cet article tente principalement de résumer les méthodes de communication nodejs (monothread, multi-thread, multi-processus), les scénarios d'utilisation, la mise en œuvre, etc.

Comment mettre en œuvre la communication

La communication du processus général est mise en œuvre comme suit :

1. Mémoire partagée (partage de mémoire)

2. canal nommé FIFO);

4. Signal (signal);

5. File d'attente des messages (file d'attente des messages)

Voyons comment implémenter ces méthodes de communication dans le nœud

1. Mémoire partagée (partage de mémoire); )

Sous une seule machine (un seul thread dans le client, plusieurs threads dans un seul processus, plusieurs processus dans un seul serveur), la communication via le partage de mémoire est la méthode la plus courante.

Mémoire partagée (partage de mémoire) - thread unique

Du niveau du système d'exploitation, toute la mémoire des threads dans le processus est partagée, mais la condition préalable est que l'adresse d'accès à la mémoire doit être connue.

Mais au niveau du langage (niveau d'implémentation nœud ou v8), nous ne touchons pas directement à la gestion de la mémoire, mais effectuons indirectement des opérations mémoire à partir de la syntaxe/api fournie par la v8. La v8 nous offre trois façons de partager la mémoire (on l'appelle peut-être plus correctement variables partagées) :

variables globales

, variables locales, paramètres partagés (appel par partage) ;v8 transférera d'abord le code avant de l'exécuter. Après avoir été converti en arbre de syntaxe abstraite via la spécification Estree, il est ensuite interprété, compilé et exécuté. Il y a une portée dans l'arbre de syntaxe abstraite (voir mon autre article sur l'arbre de syntaxe abstraite), et la lecture de la mémoire se fait via des identifiants. (nom de la variable) Recherche niveau par niveau. Ainsi, si vous avez besoin de partager de la mémoire entre deux méthodes, vous pouvez la créer dans leur portée commune.

Mémoire partagée (partage de mémoire) - multi-threading

Dans l'environnement client ou dans l'environnement nœud, nous pouvons implémenter le multi-threading, et les deux méthodes sont similaires (le nœud est implémenté via worker_threads, et le le navigateur est implémenté via Worker). Le partage de mémoire ici est principalement réalisé à l'aide de l'API d'opération de mémoire (SharedArrayBuffer). Regardons d'abord un exemple d'implémentation de navigateur :

// 主线程
const buffer = new SharedArrayBuffer(1024)
const typedArr = new Int16Array(buffer)
const newWorker = new Worker('./worker.js')

typedArr[0] = 20

newWorker.postMessage(buffer)
newWorker.onmessage= (data) => {
    console.group('[the main thread]');
    console.log('Data received from the main thread: %i', typedArr[0]);
    console.groupEnd();
}
// 子线程
addEventListener('message', ({ data }) => {
  const arr = new Int16Array(data)

  console.group('[the worker thread]')
  console.log('Data received from the main thread: %i', arr[0])
  console.groupEnd()
  arr[0] = 18
  
  postMessage('Updated')
})
// 结果
[the worker thread]
  Data received from the main thread: 20
[the main thread]
  Data received from the main thread: 18

Mémoire partagée (partage de mémoire) - multi-processus

Parce que la mémoire ne peut pas être lue les unes des autres après le démarrage des processus (restrictions au niveau du système), le partage de mémoire entre les processus est en fait obtenu en ouvrant une nouvelle section de mémoire partagée. Cependant, le nœud ne prend actuellement pas en charge la mémoire partagée et ne peut être implémenté que via des langages de bas niveau, tels que le plug-in complémentaire de perturbateur de mémoire partagée implémenté en C++ (décrit dans un autre article).

2. Socket (Socket)

Socket est divisé en deux implémentations :

1. TCP Socket 

2. UNIX Domain Socket ; Concept : TCP Socket est la couche d'abstraction intermédiaire pour la communication entre la couche application et la famille de protocoles TCP/IP. Il s'agit d'un mécanisme de communication inter-processus fourni par le système d'exploitation

La communication TCP Socket devrait être la communication la plus courante dans notre système d'exploitation. développement quotidien (architecture C/S) L'une des méthodes les plus courantes dans notre développement quotidien est l'utilisation de divers protocoles de couche d'application (http, websocket, rpc, ftp, etc.). Le module http dans node est également implémenté sur la base. sur le module réseau.

Remarque : En fait, UDP appartient également à la couche TCP (ne faisant pas strictement référence à la communication TCP, mais la couche TCP/IP dans la couche de communication réseau fournit le module « dgram » pour l'implémenter, mais il n'y en a pas). contact dans les applications réelles Réussi, donc pas de compréhension supplémentaire.

net

Dans le nœud, TCP Socket est implémenté par le module net. Le module net fournit principalement les fonctions suivantes :

1. Prise en charge IPC de couche supérieure (en fait, la mise en œuvre de la communication pipeline, plus de détails sur la communication pipeline. plus tard) Description);

2, classe net.Server;

TCP Socket适用于单机,C/S架构等.但UNIX Domain Socket只适用于单机。  
UNIX Domain Socket不需要经过一系列的网络中转(协议,分包,校验等等),性能更高,稳定性更好。
3, classe net.Socket;
// 服务端通过net.createServer创建服务,会返回net.Server对象,可以通过返回值进行各种事件监听,端口监听
const net = require('net')

net.createServer((server => {
  server.end(`hello world!\n`)
})).listen(3302, () => {
  console.log(`running ...`)
})

UNIX Domain Socket

UNIX Domain Socket crée un descripteur de fichier et la communication entre les différents processus passe en lecture et écrivez ce descripteur de fichier pour la communication (peut être divisé en processus de création et autres processus, et la communication mutuelle entre d'autres processus peut se faire via le processus de création comme transit). par exemple

const net = require('net')
const socket = net.createConnection({port: 3302})

socket.on('data', data => {
  console.log(data.toString())
})

3. Pipeline

La communication par pipeline est divisée en deux types, les canaux non nommés et les canaux nommés.

Les canaux sans nom sont implémentés de la même manière que les sockets de domaine UNIX, communiquant en créant des descripteurs de fichiers. Les canaux nommés communiquent via des descripteurs de fichiers fixes :
"\\\\.\\pipe\\" + PIPE_NAME;

源码可参考stackoverflow(https://stackoverflow.com/questions/11750041/how-to-create-a-named-pipe-in-node-js)
目前理解的管道通信和UNIX Domain Socket实现基本一致,只是管道通信规范了读写权限,半双工通信,UNIX Domain Socket更加自由一些。

四、Signal(信号)

Signal是操作系统在终止进程前给进程发送的信号。在node中可以通过process.kill(pid, signal)/child_process.kill(pid, signal)接口实现,e.g.

// 要被终止的http守护进程
const Koa = require('koa')
const app = new Koa()

app.listen(3004, () => {
  console.log(`process pid is : ${process.pid}`) // process pid is : 75208
})
// 操作进程
process.kill(75208, 'SIGHUP') // 'SIGHUP'是一般结束进程的信号,还有更多其他的信号参考 [标识](https://blog.csdn.net/houjixin/article/details/71430489)

但这里的前提是你需要获取到被终止的进程pid,更多pid的内容可阅读我之前关于进程的文章。

五、Message queue(消息队列)

一开始我以为是redis,各种MQ之类的基于TCP的消息队列。但其实是操作系统内的消息队列,node暂时没有提供相关的上层接口,需要更底层实现,e.g. svmq

更多node相关知识,请访问:nodejs 教程!!

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!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer