什么是错误的原因'getaddrinfo EAI_AGAIN'?

我的服务器今天抛出了这个,这是一个我以前从未见过的Node.js错误:

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)

我想知道这是否与今天影响Shopify和许多其他服务的DynDns DDOS攻击有关。这里有一篇关于这个的文章。

我的主要问题是dns.js做什么?它属于节点的哪一部分?如何在不同的域上重新创建此错误?

373856 次浏览

EAI_AGAIN是一个DNS查找超时错误,意味着它是一个网络连接错误或代理相关的错误。

我的主要问题是dns.js做什么?

  • dns.js用于节点获取域的ip地址(简而言之)。
更多信息: http://www.codingdefined.com/2015/06/nodejs-error-errno-eaiagain.html < / p >

@xerq指向正确,这里有更多的参考 http://www.codingdefined.com/2015/06/nodejs-error-errno-eaiagain.html < / p >

我得到了同样的错误,我通过更新“hosts”文件在Windows操作系统的这个位置下解决了这个问题

C:\Windows\System32\drivers\etc

希望能有所帮助!!

这是与hosts文件设置相关的问题。 在hosts文件中添加以下代码行 Ubuntu系统:/etc/hosts

. txt
127.0.0.1   localhost

windows: c:\windows\System32\drivers\etc\hosts

127.0.0.1   localhost

OP的错误指定一个主机(my-store.myshopify.com)。 我遇到的错误在所有方面都是一样的,除了没有指定域

我的解决方案可能会帮助其他被标题“错误:getaddrinfo EAI_AGAIN”吸引到这里的人

我在尝试服务一个NodeJs &VueJs应用程序从一个不同的虚拟机,从那里开发的代码最初。

文件vue.config.js读为:

 module.exports = {
devServer: {
host: 'tstvm01',
port: 3030,
},
};

当在原始机器上服务时,启动输出是:

App running at:
- Local:   http://tstvm01:3030/
- Network: http://tstvm01:3030/

在虚拟机tstvm07上使用相同的设置让我得到了一个非常类似于OP描述的错误:

 INFO  Starting development server...
10% building modules 1/1 modules 0 activeevents.js:183
throw er; // Unhandled 'error' event
^


Error: getaddrinfo EAI_AGAIN
at Object._errnoException (util.js:1022:11)
at errnoException (dns.js:55:15)
at GetAddrInfoReqWrap.onlookup [as oncomplete] (dns.js:92:26)

如果还不明显,将vue.config.js改为读…

 module.exports = {
devServer: {
host: 'tstvm07',
port: 3030,
},
};

... 解决了问题。

如果你在Firebase云函数中得到这个错误,这是由于免费层的限制(出站组网只允许谷歌业务)。

升级到火焰大火计划才能工作。

enter image description here

在对我的GraphQL API应用程序(在docker容器内操作)进行了一次微不足道的更新后,我开始得到这个错误(不同的堆栈跟踪)。不管出于什么原因,容器在解析API使用的后端服务时遇到了困难。

在四处打听了一下我正在构建的docker基础映像(顺便说一下,node:13-alpine)中是否发生了一些更改之后,我决定尝试最古老的计算机科学技巧:重新启动…我停下来启动docker容器,一切恢复正常。

显然,这不是一个有意义的解决潜在问题的方案——我只是发布这个,因为它确实为我澄清了问题,而没有深入到兔子洞。

我在使用AWS和无服务器时也遇到了同样的问题。我尝试使用eu-central-1区域,但它不起作用,所以我不得不将其更改为us-east-2作为示例。

如果你得到这个错误从docker容器内部,例如,当在alpine容器中运行npm install时,原因可能是容器启动后网络发生了变化。

要解决这个问题,只需停止并重新启动容器

docker-compose down
docker-compose up

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

正如Xerq的回答非常棒解释的那样,这是一个DNS超时问题。

我想为那些使用Linux的Windows子系统——在某些情况下,在Windows从睡眠状态恢复后,客户端操作系统中似乎出现了一些问题的人提供另一个可能的答案。重新启动主机操作系统将解决这些问题(重新启动WSL服务也可能会解决同样的问题)。

启用了火焰,它仍然不工作?

大多数情况下,你需要从正确的路径require('dotenv').config({ path: __dirname + './../.env' }); 不会起作用(或任何其他路径)设置.env。简单地将.env文件放在functions目录中,从该目录部署到Firebase

在我的情况下,问题是docker网络ip分配范围,详见这篇文章

我在码头合成上遇到了问题。原来我忘了把我的自定义隔离命名网络添加到我的服务中,但找不到。

TLDR;确保在compose文件中,在需要相互通信的两个服务上定义了custom-networks

我的错误是这样的:Error: getaddrinfo EAI_AGAIN minio-service。当使用minio-service主机名调用minio-service时,错误来自我的服务器后端。这告诉我minio-service的运行服务不能被我的server的运行服务访问。我能够解决这个问题的方法是我改变了docker-compose中的minio-service:

  • docker-compose.yml
version: "3.8"


# ...


services:
server:
# ...
networks:
my-network:
# ...
minio-service:
# ... (missing networks: section)


# ...


networks:
my-network:

包括我的自定义隔离命名网络,像这样:

  • docker-compose.yml
version: "3.8"


# ...


services:
server:
# ...
networks:
my-network:
# ...
minio-service:
# ...
networks:
my-network:
# ...


# ...


networks:
my-network:

更多关于docker-compose网络的细节可以在这里找到

在我的例子中,连接到VPN,当在Windows终端中运行Ubuntu时发生错误,但当直接从Windows(不是从Windows终端中)打开Ubuntu时不会发生错误。

enter image description here

我最近在我的docker-compose文件中添加了一个新的network后得到了这个错误。

我最初有这些服务:

services:
frontend:
depends_on:
- backend
ports:
- 3005:3000
  

backend:
ports:
- 8005:8000

我决定添加一个新的网络,它承载着我希望frontend服务能够访问的其他服务,所以我这样做了:

networks:
moar:
name: moar-network
attachable: true


services:
frontend:
networks:
- moar
depends_on:
- backend
ports:
- 3005:3000
  

backend:
ports:
- 8005:8000

不幸的是,上述情况导致我的frontend服务在default网络中不再可见,而只在moar网络中可见。这意味着frontend服务不能再代理请求到backend,因此我得到如下错误:

试图代理到:localhost:3005/graphql/时发生错误

解决方案是将default网络添加到frontend服务的网络列表中,如下所示:

networks:
moar:
name: moar-network
attachable: true


services:
frontend:
networks:
- moar
- default # here
depends_on:
- backend
ports:
- 3005:3000
  

backend:
ports:
- 8005:8000

现在我们好了!


最后一件事,如果你想查看在给定网络中运行的服务,你可以使用docker network inspect <network_name>命令来这样做。这帮助我发现frontend服务不再是默认网络的一部分。

对于那些每天执行数千或数百万个请求,并且需要解决此问题的人:

在服务器上执行大量请求时,得到getaddrinfo EAI_AGAIN错误是很正常的。Node.js本身不执行任何DNS缓存,它委托所有与操作系统相关的DNS。

你需要记住,每个http/https请求都会执行一个DNS查找,这可能会变得相当昂贵,为了避免这个瓶颈和getaddrinfo错误,你可以实现一个DNS缓存。

http.request(和https)接受一个默认为dns.lookup()lookup属性

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

强烈推荐使用一个已经测试过的模块,而不是自己写一个DNS缓存,因为你必须正确处理TTL,在其他事情中,以避免难以跟踪错误。

我个人使用cacheable-lookup,这是got使用的(参见dnsCache选项)。

您可以在特定的请求中使用它

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
});

或全球

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);

注意:请记住,如果一个请求不是通过Node.js的http/https模块执行的,在全局代理上使用.install将不会对所述请求产生任何影响,例如使用undici发出的请求