Website-Suche

javascript - Was ist die Ursache des Fehlers 'getaddrinfo EAI_AGAIN'?


Mein Server hat dies heute ausgegeben, was ein Node.js-Fehler ist, den ich noch nie zuvor gesehen habe:

Error: getaddrinfo EAI_AGAIN my-store.myshopify.com:443
    at Object.exports._errnoException (util.js:870:11)
    at errnoException (dns.js:32:15)
    at GetAddrInfoReqWrap.onlookup [as oncomplete] (dns.js:78:26)

Ich frage mich, ob dies mit dem DynDns-DDoS-Angriff zusammenhängt, der heute Shopify und viele andere Dienste betroffen hat. Hier ist ein Artikel darüber.

Meine Hauptfrage ist, was dns.js macht. Zu welchem Teil von Node gehört es? Wie kann ich diesen Fehler mit einer anderen Domain reproduzieren?

Antwort #1

EAI_AGAIN ist ein DNS-Lookup-Zeitüberschreitungsfehler, bedeutet, dass es ein Netzwerkverbindungsfehler oder ein Proxy-bezogener Fehler ist.

Meine Hauptfrage ist, was dns.js macht?

  • Die dns.js ist da, damit Node die IP-Adresse der Domain erhält (kurz gesagt).

Weitere Informationen: http://www.codingdefined.com/2015/06/nodejs-error-errno-eaiagain.html

Antwort #2

Wenn Sie diesen Fehler mit Firebase Cloud Functions erhalten, liegt dies an den Einschränkungen des kostenlosen Tarifs (ausgehendes Netzwerk nur für Google-Dienste erlaubt).

Upgrade auf die Flame- oder Blaze-Pläne, damit es funktioniert.

Antwort #3

Wenn Sie diesen Fehler innerhalb eines Docker-Containers erhalten, z. B. beim Ausführen von npm install in einem Alpine-Container, könnte die Ursache sein, dass sich das Netzwerk seit dem Start des Containers geändert hat.

Um dies zu lösen, stoppen und starten Sie einfach den Container neu

docker-compose down
docker-compose up

Quelle: https://github.com/moby/moby/issues/32106#issuecomment-578725551

Antwort #4

Für diejenigen, die täglich Tausende oder Millionen von Anfragen durchführen und eine Lösung für dieses Problem benötigen:

Es ist ganz normal, getaddrinfo EAI_AGAIN-Fehler zu bekommen, wenn man viele Anfragen auf seinem Server ausführt. Node.js selbst führt kein DNS-Caching durch, es delegiert alles, was mit DNS zu tun hat, an das Betriebssystem.

Sie müssen im Hinterkopf behalten, dass jede http/https-Anfrage eine DNS-Abfrage durchführt, dies kann ziemlich teuer werden. Um dieses Nadelöhr und getaddrinfo-Fehler zu vermeiden, können Sie einen DNS-Cache implementieren.

http.request (und https) akzeptiert eine lookup-Eigenschaft, die standardmäßig dns.lookup() ist

http.get('http://example.com', { lookup: yourLookupImplementation }, response => {
    // do something here with response
});

Ich empfehle dringend, ein bereits getestetes Modul zu verwenden, anstatt einen eigenen DNS-Cache zu schreiben, da Sie unter anderem die TTL korrekt handhaben müssen, um schwer zu verfolgende Fehler zu vermeiden.

Ich persönlich verwende cacheable-lookup, das ist das, das got verwendet (siehe dnsCache-Option).

Sie können es bei bestimmten Anfragen verwenden

const http = require('http');
const CacheableLookup = require('cacheable-lookup');

const cacheable = new CacheableLookup();

http.get('http://example.com', {lookup: cacheable.lookup}, response => {
    // Handle the response here
});

oder global

const http = require('http');
const https = require('https');
const CacheableLookup = require('cacheable-lookup');

const cacheable = new CacheableLookup();

cacheable.install(http.globalAgent);
cacheable.install(https.globalAgent);

HINWEIS: Bedenken Sie, dass, wenn eine Anfrage nicht über das Node.js-http/https-Modul ausgeführt wird, die Verwendung von .install am globalen Agenten keine Auswirkungen auf diese Anfrage hat, zum Beispiel Anfragen, die mit undici gemacht werden.


Wenn Sie undici verwenden, können Sie undici.setGlobalDispatcher() verwenden

import { Agent, setGlobalDispatcher } from 'undici';
import CacheableLookup from 'cacheable-lookup';

const cacheable = new CacheableLookup();

const agent = new Agent({
    connect: {
        lookup: cacheable.lookup
    }
});

setGlobalDispatcher(agent);

await fetch('https://google.com'); // will be cached

Wenn Sie es nicht für alle Anfragen festlegen möchten, könnten Sie Folgendes tun:

await fetch('https://google.com', {
    dispatcher: agent
});

Antwort #5

Wie xerqs ausgezeichnete Antwort erklärt, handelt es sich hierbei um ein DNS-Timeout-Problem.

Ich wollte eine weitere mögliche Antwort für diejenigen von euch beitragen, die Windows Subsystem für Linux verwenden - es gibt einige Fälle, in denen nach dem Aufwachen von Windows aus dem Schlafmodus etwas im Client-Betriebssystem nicht stimmt. Ein Neustart des Host-Betriebssystems behebt diese Probleme (wahrscheinlich wird auch ein Neustart des WSL-Dienstes dasselbe tun).

Verwandte Artikel