web-dev-qa-db-fra.com

Node.js dns.resolve () vs dns.lookup ()

J'ai besoin de rechercher un hôte donné à son IP correspondante dans Node.js. Il semble y avoir deux méthodes natives pour ce faire:

> dns.resolve('google.com', (error, addresses) => { console.error(error); console.log(addresses); });
QueryReqWrap {
  bindingName: 'queryA',
  callback: { [Function: asyncCallback] immediately: true },
  hostname: 'google.com',
  oncomplete: [Function: onresolve],
  domain:
   Domain {
     domain: null,
     _events: { error: [Function] },
     _eventsCount: 1,
     _maxListeners: undefined,
     members: [] } }
> null
[ '216.58.194.174' ]

Et:

> dns.lookup('google.com', (error, address, family) => { console.error(error); console.log(address); console.log(family); });
GetAddrInfoReqWrap {
  callback: { [Function: asyncCallback] immediately: true },
  family: 0,
  hostname: 'google.com',
  oncomplete: [Function: onlookup],
  domain:
   Domain {
     domain: null,
     _events: { error: [Function] },
     _eventsCount: 1,
     _maxListeners: undefined,
     members: [] } }
> null
216.58.194.174
4

Les deux renvoient la même adresse IPv4. Quelle est la différence entre dns.lookup() et dns.resolve()? Aussi, qu'est-ce qui est plus performant pour beaucoup de requêtes par seconde?

15
Justin

La documentation dns décrit déjà la différence:

Bien que dns.lookup () et les diverses fonctions dns.resolve * ()/dns.reverse () aient le même objectif d'associer un nom de réseau à une adresse réseau (ou vice versa), leur comportement est assez différent. Ces différences peuvent avoir des conséquences subtiles mais importantes sur le comportement des programmes Node.js.

dns.lookup ()
Sous le capot, dns.lookup () utilise les mêmes fonctionnalités de système d'exploitation que la plupart des autres programmes. Par exemple, dns.lookup () résoudra presque toujours un nom donné de la même manière que la commande ping. Sur la plupart des systèmes d'exploitation de type POSIX, le comportement de la fonction dns.lookup () peut être modifié en modifiant les paramètres dans nsswitch.conf (5) et/ou resolv.conf (5), mais notez que la modification de ces fichiers modifiera le comportement de tous les autres programmes s'exécutant sur le même système d'exploitation.

Bien que l'appel à dns.lookup () soit asynchrone du point de vue de JavaScript, il est implémenté comme un appel synchrone à getaddrinfo (3) qui s'exécute sur le pool de threads de libuv. Étant donné que le pool de threads de libuv a une taille fixe, cela signifie que si, pour une raison quelconque, l'appel à getaddrinfo (3) prend beaucoup de temps, d'autres opérations qui pourraient s'exécuter sur le pool de threads de libuv (telles que les opérations du système de fichiers) verront leurs performances se dégrader. Afin d'atténuer ce problème, une solution potentielle consiste à augmenter la taille du pool de threads de libuv en définissant la variable d'environnement 'UV_THREADPOOL_SIZE' à une valeur supérieure à 4 (sa valeur par défaut actuelle). Pour plus d'informations sur le pool de threads de libuv, consultez la documentation officielle de libuv.

dns.resolve (), dns.resolve * () et dns.reverse ()
Ces fonctions sont implémentées différemment de dns.lookup (). Ils n'utilisent pas getaddrinfo (3) et effectuent toujours une requête DNS sur le réseau. Cette communication réseau est toujours effectuée de manière asynchrone et n'utilise pas le pool de threads de libuv.

Par conséquent, ces fonctions ne peuvent pas avoir le même impact négatif sur un autre traitement qui se produit sur le pool de threads de libuv que dns.lookup () peut avoir.

Ils n'utilisent pas le même ensemble de fichiers de configuration que celui utilisé par dns.lookup (). Par exemple, ils n'utilisent pas la configuration de/etc/hosts.

En ce qui concerne l'accès simultané , il vaut mieux utiliser dns.resolve*() car ces requêtes ne se retrouvent pas dans le pool de threads, tandis que dns.lookup() requêtes font car elles appellent le résolveur DNS du système d'exploitation qui bloque généralement (bien qu'il existe maintenant une sorte d'interfaces asynchrones - - mais elles ne sont pas forcément implémentées partout).

Actuellement, le nœud utilise en interne dns.lookup() pour toute résolution DNS automatique, comme lorsque vous passez un nom d'hôte à http.request().

16
mscdex

La réponse @mscdex est vraiment complète et explicative. Je peux ajouter une information sur l'approche que nous utilisons pour contourner le blocage des threads.

Nous avons développé un module qui remplace/étend la méthode dns.lookup Du nœud. Le module met en cache les réponses, a une résolution multi-enregistrements et TTL support. Nous avons également une bonne unité et fonctionnelle tests avec une couverture à 100% . Le module a été testé dans des environnements de production et à haute charge . Sous MIT license. La voici: https://github.com/LCMApps/dns-lookup-cache

Si vous avez besoin de la prise en charge de la méthode de recherche mais ne travaillez pas d'effets négatifs comme le blocage de l'application ou les ralentissements des réponses, vous pouvez utiliser notre module. Je crois que ça va aider!

0
WoZ