在Google App Engine上连接Mongoose

时间:2017-10-02 14:27:59

标签: node.js mongodb google-app-engine mongoose google-compute-engine

我已成功在Google App引擎上部署了自定义Node.js应用。但是我在启动应用时遇到问题,因为在尝试连接时猫鼬超时了。令人沮丧的是,猫鼬在我的本地机器上与完全相同的参数连接得很好。

我的MongoDb URI的格式为:

 mongodb://<dbuser>:<dbpassword>@xxxx.mlab.com:<portNumber>/d‌​b-name

如URI所示,db由mlab托管。它是Google Cloud Platform上的沙箱实例。但是我没有使用Google Compute Engine部署数据库。在mlab上完成设置过程时,我只是选择在GCP上主持。

我在SO上遇到过类似的问题,但大多数人都没有接受答案。只是在评论中不同的话语,没有公认的解决方案。

因此,我的问题是,在尝试连接上述URI时,我的App Engine实例与本地计算机有何不同?我选择让mlab在GCP上托管它的事实是什么?如果我选择在亚马逊AWS上托管它会有什么不同吗?究竟是什么问题的根源?

供参考,以下是我发现的类似问题:

此外,如果有帮助,mongodb将用作业务模型的数据库,应用程序的Express会话的数据存储区以及用于存储来自socket.io的临时数据。

部署后来自App Engine的堆栈跟踪错误:

2017-10-18 02:13:46 default[20171017t215757]  npm ERR! enoent ENOENT: no such file or directory, open '/app/package.json'
2017-10-18 02:13:46 default[20171017t215757]  npm ERR! enoent ENOENT: no such file or directory, open '/app/package.json'
2017-10-18 02:13:46 default[20171017t215757]  npm ERR! enoent This is most likely not a problem with npm itself
2017-10-18 02:13:46 default[20171017t215757]  npm ERR! enoent and is related to npm not being able to find a file.
2017-10-18 02:13:46 default[20171017t215757]  npm ERR! enoent
2017-10-18 02:13:46 default[20171017t215757]
2017-10-18 02:13:46 default[20171017t215757]  npm ERR! Please include the following file with any support request:
2017-10-18 02:13:46 default[20171017t215757]  npm ERR!     /app/npm-debug.log
2017-10-18 02:23:41 default[20171017t215757]  npm ERR! Linux 3.16.0-4-amd64
2017-10-18 02:23:41 default[20171017t215757]  npm ERR! argv "/nodejs/bin/node" "/nodejs/bin/npm" "start"
2017-10-18 02:23:41 default[20171017t215757]  npm ERR! node v6.11.3
2017-10-18 02:23:41 default[20171017t215757]  npm ERR! npm  v3.10.10
2017-10-18 02:23:41 default[20171017t215757]  npm ERR! path /app/package.json
2017-10-18 02:23:41 default[20171017t215757]  npm ERR! code ENOENT
2017-10-18 02:23:41 default[20171017t215757]  npm ERR! errno -2
2017-10-18 02:23:41 default[20171017t215757]  npm ERR! syscall open

在Google Cloud Shell中本地运行应用程序时出现堆栈跟踪错误:

/home/myuser/src/project-id/teammate-express-server/node_modules/mongodb/lib/mongo_client.js:421
          throw err
          ^
MongoError: failed to connect to server [ds147454.mlab.com:47454] on first connect [MongoError: connection 1 to ds147454.mlab.com:47454 timed out]
    at Pool.<anonymous> (/home/myuser/src/project-id/teammate-express-server/node_modules/mongodb-core/lib/topologies/server.js:336:35)
    at emitOne (events.js:96:13)
    at Pool.emit (events.js:188:7)
    at Connection.<anonymous> (/home/myuser/src/project-id/teammate-express-server/node_modules/mongodb-core/lib/connection/pool.js:280:12)
    at Connection.g (events.js:292:16)
    at emitTwo (events.js:106:13)
    at Connection.emit (events.js:191:7)
    at Socket.<anonymous> (/home/myuser/src/project-id/teammate-express-server/node_modules/mongodb-core/lib/connection/connection.js:197:10)
    at Socket.g (events.js:292:16)
    at emitNone (events.js:86:13)
    at Socket.emit (events.js:185:7)
    at Socket._onTimeout (net.js:338:8)
    at ontimeout (timers.js:386:14)
    at tryOnTimeout (timers.js:250:5)
    at Timer.listOnTimeout (timers.js:214:5)

2 个答案:

答案 0 :(得分:6)

正如已经指出的那样,您可以按照https://cloud.google.com/nodejs/getting-started/deploy-mongodb上的说明进行操作 使用config.json文件配置Google App Engine。 (更新:链接不再有效,请尝试:https://cloud.google.com/community/tutorials/nodejs-mongodb-on-appengine

由于您使用的是mongoose,因此模型将决定集合的使用情况。即save(),update()。 如果您直接使用node.js进行连接,则还可以在代码中轻松更改数据库/集合。

  

尝试连接上述URI时,我的App Engine实例与本地计算机有何不同?

Google App Engine是一个完全托管的平台。从某种意义上说,serverless,您正在利用一组工作人员来扩展/缩小您的应用程序。当请求进入您的应用程序时,池中的实例将处理任务/请求。

与您的本地计算机不同,您的计算机也会处理请求。

您可能还会发现Google App Engine FAQ有用。

  

我选择让mlab在GCP上托管它的事实是什么?

不是很多。正如您所提到的,您目前正在使用GCP进行SandBox(免费)计划。目前,这将在us-central1区域部署您的MongoDB实例,并且没有其他区域选择。不同云提供商之间的RAM /存储/价格也略有不同。

您也可以通过在us-central1区域选择GAE来减少网络延迟。

  

问题的根本原因究竟是什么?

如果没有正确的堆栈跟踪或错误日志来描述超时问题,很难确定问题是什么。

通常node.js项目包含一个名为config.js的JavaScript文件,其下面有一行:

  nconf.argv()
       .env()
       .file({ file: path.join(__dirname, 'config.json') })
       .defaults()

其中基本上尝试按以下顺序读取配置:

  • 命令行参数
  • 环境变量
  • 配置文件(指定路径)
  • 默认值

另见Google Cloud Platform: nodejs-getting-started

另外GoogleCloudPlatform/nodejs-docs-samples/appengine/mongodb项目的例子。

答案 1 :(得分:2)

嗯,这花了我太长时间,但问题出在我的Dockerfile上。

我正在扩展node.js运行时但我的Dockerfile缺少行来复制app目录并安装npm。

要创建适当的Dockerfile,我使用了以下命令:

gcloud beta app gen-config --custom

有关该命令和扩展node.js运行时的更多信息,请参见here

我添加了所需的依赖项后,我的最终Dockerfile看起来像这样:

注意:我只能在部署后连接到我的MongoDb实例。在Cloud Shell中本地运行仍然超时。

# Dockerfile extending the generic Node image with application files for a
# single application.
FROM gcr.io/google_appengine/nodejs
COPY . /app/

RUN apt-get -y update && apt-get install -y libav-tools && apt-get install -y graphicsmagick

# You have to specify "--unsafe-perm" with npm install
# when running as root.  Failing to do this can cause
# install to appear to succeed even if a preinstall
# script fails, and may have other adverse consequences
# as well.
# This command will also cat the npm-debug.log file after the
# build, if it exists.
RUN npm install --unsafe-perm || \
  ((if [ -f npm-debug.log ]; then \
      cat npm-debug.log; \
    fi) && false)
CMD npm start