AWS EC2 npm 安装突然变得非常缓慢。

7
在我的 ElasticBeanstalk 环境中,部署我的 Node.js 应用程序并使实例从“Pending”状态更改为“OK”在 EB Health 选项卡中通常需要大约 5 分钟(多年如一日)。
自 5 月 14 日以来,即使没有更改应用程序、基础架构、应用程序存储库、EB 环境或 EC2 Linux 映像,应用程序部署也需要大约 15 分钟。在生产环境和开发环境中都出现了相同的情况,两者是独立的 EB 环境,都部署了同一个应用程序。
查看 /var/log/eb-activity.log,我发现这 15 分钟花费在以下步骤:
[Application deployment <APPID>/StartupStage0/AppDeployPreHook/50npm.sh] : Starting activity...

脚本本身只运行:
/opt/elasticbeanstalk/containerfiles/ebnode.py --action npm-install

这个脚本只是进行了一些文件检查和路径组合,然后运行了:

npm --production install

为了对比,我清除了任何缓存文件并在本地运行了相同的命令,用时约11分钟:

rm -rf node_modules
node cache clean -f
npm --production install

我再次使用 --loglevel silly 命令运行,结果显示在 package.json 中有一个依赖项未从 npm 注册表中获取,而是直接从 GitHub 中获取,指向一个标签:

npm sill pacote Retrying git command: ls-remote -h -t git://github.com/<org>/<repo>.git attempt # 2
npm sill pacote Retrying git command: ls-remote -h -t git://github.com/<org>/<repo>.git attempt # 3
npm verb prepareGitDep github:<org>/<repo>#<label>: installing devDeps and running prepare script.

这些git ls-remote命令的超时时间约为1分钟,然后似乎安装devDependencies,运行prepare脚本需要另外5分钟。我不确定这是否也发生在EC2实例上,但那是我找到的唯一提示。
这3个超时的git ls-remote命令和prepare脚本总共需要约8分钟。因此,如果这是之前没有执行过的内容,可能会解释部署时间更长。但是为什么部署突然与多年来不同呢?
我看到了这篇GitHub的博客文章

2022年3月15日

做出的更改已成为永久性的。我们将永久停止接受DSA密钥。在上述截止日期之后上传的RSA密钥仅适用于SHA-2签名(但是在此日期之前上传的RSA密钥将继续使用SHA-1)。弃用的MAC、密码和未加密的Git协议将被永久禁用。

因此,GitHub停止了使用git://协议的请求。也许这就是部署时间更长并且超时也会发生在EC2上的原因。但是这个更改已经在3月15日(正好2个月前)永久生效了,那为什么问题现在才出现呢?
2个回答

1
我们的代码库也有类似的令人困惑的行为,在5月13日开始。我不知道为什么GitHub依赖要到现在才出现这些问题,但根据你分享的博客文章,看起来是一个永久性的问题。
关于这个问题,GitHub问题已经被创建,并且社区提出了各种解决问题的方法之一是:

通过将package-lock.json和package.json中的 github 协议替换为 https 解决此问题。

另外一个用户建议:

...我们发现将npm更新到版本7.16.0(至少,这是我们因其他原因选择的版本)可以解决这个问题。

对于我们来说,我们选择了后者并开始使用NPM 7版本(具体来说是`7.24.2`)。这确实需要我们将 `package-lock.json` 文件更新到2版本,并带来了许多其他问题,但它似乎对我们有效。

感谢确认,由于这似乎是目前可用的答案,我会接受它。我们改用git+https后,时间从14分钟缩短到8分钟,但仍比5月13日之前的原始时间长100%以上。 - Manuel
我们的时间是在13日早上11点之前的某个时刻。感谢您的付出。 - plinehan

1
以下是我在AWS EC2 / ElasticBeanstalk部署Node.js应用程序时解决问题的方法:
.ebextensions中运行命令
commands:
  01-configure-git:
    command: sudo git config --system url."https://github".insteadOf "git://github"
    ignoreErrors: true # optionally, so deployment doesn't fail in case the command fails for some reason

仅检查自己的package.json并更改协议可能不足够。如果有依赖项也直接使用git协议在GitHub上引用它们自己的依赖项。以上解决方案适用于所有这些情况。


嘿@manuel,很高兴在这里见到你!你是否已经成功在Amazon Linux 2上运行了它?似乎它只能在Amazon Linux 1上运行。 - Sebastien C.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接