Le partage de contexte de ressource asynchrone signifie le partage de données de contexte au sein d'un cycle de vie de demande réseau ou d'une chaîne d'appel de ressource asynchrone.
Avant de répondre à cette question, il faut d’abord comprendre ce que sont les ressources asynchrones.
Les ressources asynchrones peuvent être comprises comme des objets avec des rappels, tels que, sans toutefois s'y limiter, les promesses, les délais d'attente, TCPWrap, UDP, etc. Consultez la liste des types de ressources asynchrones pour plus de détails.
La définition officielle est la suivante :
Une ressource asynchrone représente un objet avec un rappel associé. Ce rappel peut être appelé plusieurs fois, comme l'événement 'connection' dans net.createServer(), ou juste une seule fois comme dans fs.open. (). Une ressource peut également être fermée avant l'appel du rappel.
Nous présentons ici AsyncLocalStorage, la solution de partage de contexte asynchrone officiellement fournie par Node.js. Cette fonctionnalité était encore expérimentale avant la 16.4.0 et est stable depuis la 16.4. .0.
AsyncLocalStorage peut partager des données dans une chaîne d'opérations asynchrones.
L'instance d'AsyncLocalStorage asyncLocalStorage a les méthodes principales suivantes :
exemple :
const store = { id: 1 } ; // Remplace le magasin précédent par l'objet de magasin donné asyncLocalStorage.enterWith(magasin); asyncLocalStorage.getStore(); // Renvoie l'objet magasin someAsyncOperation(() => { asyncLocalStorage.getStore(); // Renvoie le même objet });
Le premier paramètre de la fonction asyncLocalStorage.run() est de stocker les données partagées auxquelles nous devons accéder dans l'appel asynchrone, et le deuxième paramètre est une fonction asynchrone.
Voici un exemple illustrant comment utiliser AsyncLocalStorage pour implémenter le partage de contexte de ressources asynchrone :
Sortie :
runA 8f19ebef-58d7-4b1a-8b9b-46d158beb5d2 2022/5/24 20:26:17 ceci est un message de journal runB 8f19ebef-58d7-4b1a-8b9b-46d158beb5d2 2022/5/24 20:26:17 ceci est un message de journal
Dans la même fonction asynchrone exécutée via asyncLocalStorage.run, les fonctions runA et la fonction runB seront exécutées, et runA et runB peuvent être accessible aux mêmes données de contexte.
AsyncLocalStorage nous offre un excellent parcours pour implémenter facilement le partage de contexte de ressources asynchrones dans Node.js, mais chaque opération de ressource asynchrone déclenchera des Async Hooks, ce qui aura inévitablement un certain impact sur les performances de notre application Node. Alors, quelle est l’ampleur de l’impact ?
Selon une mesure réelle réalisée par Kuzzle, l'utilisation d'AsyncLocalStorage entraînera une perte de performances supplémentaire d'environ 8 %. Bien entendu, différents scénarios commerciaux peuvent avoir des performances différentes. Si cet aspect des performances vous préoccupe, vous pouvez également ajouter des tests comparatifs à votre entreprise pour tester l’impact spécifique sur les performances.
---- | Journal avec AsyncLocalStorage | Log classique | différence |
---|---|---|---|
req/s | 2613 | 2842 | ~8% |
Dans d'autres langages multithread, chaque HTTP crée un nouveau thread et chaque thread possède sa propre mémoire. Vous pouvez stocker l'état global dans la mémoire des threads et récupérer l'état global depuis n'importe où dans votre code.
Dans Node.js, étant donné que Node.js est monothread et partage la mémoire entre toutes les requêtes HTTP, chaque requête HTTP ne peut pas contenir un état global isolé les uns des autres.
AsyncLocalStorage peut isoler efficacement l'état entre différentes opérations asynchrones et joue un rôle très important dans des scénarios tels que le suivi des requêtes HTTP, les outils APM, le suivi des journaux contextuels et le suivi des journaux de liens complets basés sur les requêtes.