带有 NodeJS 的 Google App Engine 502(坏网关)

Posted

技术标签:

【中文标题】带有 NodeJS 的 Google App Engine 502(坏网关)【英文标题】:Google App Engine 502 (Bad Gateway) with NodeJS 【发布时间】:2016-10-27 00:54:33 【问题描述】:

我有一个使用 NodeJS、MongoDB(Mongoose 作为驱动程序)和 ExpressJS 的完整 Web 应用程序。

该项目在我的本地机器上运行良好。今天我决定把所有东西都投入生产。我正在使用 Google App Engine 来托管我的应用程序,并使用 Compose(以前称为 MongoHQ)来托管我的数据库。

App Engine 完美地为我的应用程序提供服务,尽管我的 API 似乎无法正常工作。我的 API 由 example.com/api 提供服务,每个请求(GETPOSTDELETEPUT)都返回 502(错误网关)错误。

我尝试在本地机器上运行我的应用程序,同时连接到我的远程 MongoDB 数据库,效果非常好。所以这一定是 App Engine 或 NodeJS 的问题,而不是 MongoDB。

我已尝试检查 Google Cloud 中的所有错误日志,但没有错误。

为什么 App Engine/NodeJS 可以完美地为我的应用程序的静态内容提供服务,但不允许对我的 API 发出任何请求?

【问题讨论】:

【参考方案1】:

只要确保您的服务器侦听 8080 端口即可 https://cloud.google.com/appengine/docs/flexible/custom-runtimes/build#listen_to_port_8080

【讨论】:

这正是我遇到的问题!谢谢 终于开始运行了!如果 google 的 nginx 返回了一些关于此的提示,那将会很有用,当您不熟悉该平台时,502 可能是任何东西。此外,用于启动和运行节点的文档非常多且分散【参考方案2】:

502 Bad Gateway 通常是 Nginx 端的错误。不幸的是,这些日志还没有出现在 Cloud Logging 中。

很多时候问题是您的 HTTP 数据包对于缓冲区或类似的东西来说太大了。查看 nginx 日志的方式是这样的:

仅使用 1 个虚拟机。这不是绝对必要的,但是如果您知道您的请求在一台机器上,很多时候它可以更容易地调试您的应用程序。您可以通过将其添加到您的 app.yaml 来完成此操作:

manual_scaling: instances: 1 然后重新部署

将 VM 从“Google 拥有”切换为自行管理。这可以在 Cloud Console 中完成。转到 Compute Engine,实例,单击与 App Engine 版本匹配的实例名称,您应该会看到一个将其切换为自我管理的选项。

gcloud compute ssh <instance name> SSH 到机器

docker ps 查看正在运行的容器。查找名为 nginx 的容器并获取其 id。

拥有容器 ID 后,您应该能够docker exec -it <container id> -- cat /var/log/nginx/error.log。您可能想要ls 整个日志目录。

您可能会在那里看到一个错误,这将是一个更大的提示,说明出了什么问题。

我知道这比它应该的要复杂得多:-\ 如果您对上述步骤有任何问题,请发表评论。如果您确实发现了错误并且不确定如何处理它,也请发表评论。

【讨论】:

这里有一个情节转折。只需将manual_scaling: instances: 5 添加到我的app.yaml 文件并部署它即可解决整个问题。知道为什么会这样吗? 虽然,当尝试访问我更高级的 API 之一时,例如图片上传,它仍然失败。这可能是因为我正在向我的 API 发送一个大的 Base64 字符串。有没有办法增加可以发送到我的服务器 API 的数据量? 哇,刚刚意识到我的意思是手动缩放:实例设置为 1,而不是 5!这样你就可以确定你正在查看什么请求。我仍然会按照其余步骤来查看您是否找不到错误日志。无论如何,如果您的数据包对于缓冲区而言太大,则无法直接增加,因此最好的办法是弄清楚如何将需要传输的数据分解为多个数据包。 好的..我为我的项目vplan-147418.appspot.com做了所有这些。见gist.github.com/sureshvv/4d7adbd495ba17fb4c468a120f55ec74 很棒的解释。但是您可以使用他们的终端在谷歌云网站内进行调试。按照谷歌的教程“调试实例”:cloud.google.com/appengine/docs/flexible/nodejs/…【参考方案3】:

我遇到了同样的问题,在 GAE 标准环境中出现“nginx 502 bad gateway”错误。这有很多原因,但我终于让它工作了。试试这些:

1) 在正确的端口上运行应用程序。 Google 将设置 PORT 环境变量。我在端口 8080 上运行,在堆栈驱动程序日志中我收到此警告:

应用正在侦听端口 8080。我们建议您的应用侦听 由 PORT 环境变量定义的端口,以利用 NGINX 层在 8080 端口上。

下面的代码从环境中获取端口,如果设置了PORT,否则默认为8080:

const PORT = process.env.PORT || 8080;

2) 转到google cloud console -> logging -> logs viewer。选择Google App Engine,然后从下方选择您的服务并检查您的日志。您是否收到了请求,或者看起来请求对您的服务器没有反应。就我而言,即使我修复了端口,我也没有得到它们:

2020-03-02 21:50:07 后端[20200302t232314] 服务器监听端口 8081! 2020-03-02 21:50:08 后端 [20200302t232314] "GET /create-user HTTP/1.1" 502

如果您的应用程序无法启动、抛出异常等,请修复任何错误。

3) 运行服务器时不要传递 IP。 Google 似乎在预定义的 IP 地址上运行该应用程序,并且不希望您对其进行修改:

server.listen(PORT);

4) 不要尝试在 https 上运行! Google 在您的应用程序前面运行一个 nginx 服务器,它正在处理 SSL 并通过 http 重定向到您的应用程序。您可以使用环境变量NODE_ENV(在 GAE 环境中设置为“生产”)在生产环境的 http 和其他地方的 https 上运行,如下所示:

let https = require('https');
let http = require('http');

if (process.env.NODE_ENV == "production") 
    http.createServer(app).listen(PORT, function () 
        console.log(`Server listening on port $PORT!`)
    );
 else 
    https.createServer(
        key: fs.readFileSync('host.key'),
        cert: fs.readFileSync('host.cert')
    , app).listen(PORT, function () 
        console.log(`Server listening on port $PORT!`)
    );

5) 我不需要在我的 yaml 文件中设置任何处理程序,如果您的配置不正确,它可能会导致错误。我的 yaml 文件非常简单:

runtime: nodejs12
env: standard
instance_class: F1

【讨论】:

以上是关于带有 NodeJS 的 Google App Engine 502(坏网关)的主要内容,如果未能解决你的问题,请参考以下文章

带有 Google 日历 API(时隙)React/NodeJS 的预约系统

NodeJS 中的 Google App Engine 日志记录

Google Cloud App Engine 上的 Nodejs 应用程序未启动

运行一个 Google App Engine 实例,前端在 nodejs 中,后端服务器在 python 中

带有 vhost 和 greenlock-express 的 NodeJS 子域

带有Firebase的Google App Engine-无法添加依赖项