带有 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
提供服务,每个请求(GET
、POST
、DELETE
和 PUT
)都返回 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 中