【问题标题】:Node-Postgres: program does not work after 30 seconds while using Express, no problems without ExpressNode-Postgres:使用 Express 时程序在 30 秒后无法运行,没有 Express 没有问题
【发布时间】:2016-09-06 22:47:37
【问题描述】:

我正在使用 node-postgres 从 NodeJS 连接到 Postgres 数据库;在运行程序 30 秒后(在第一次向服务器请求之后),它给出了一个奇怪的错误 Cannot read property 'rows' of undefined。如果我不使用 Express,错误就会消失。

我已剥离代码以重现错误:

  1 var conn_string = "pg://postgres@localhost:5432/foobardb";
  2 var express = require("express");
  3 var pg = require("pg");
  4 var router_home = express.Router();
  5 var app = express();
  6
  7 pg.connect(conn_string, function(err, client, done){
  8         router_home.get("/", function(req, res, next){
  9                 client.query("select * from visit", function(err, result){
 10                         done();
 11                         res.end(JSON.stringify(result.rows[0]));
 12                 });
 13         });
 14 });
 15 app.use("/", router_home);
 16 app.listen(8080);

在此代码示例上运行 curl -X GET http://localhost:8080/ 最初几次运行良好,然后在 30 秒后失败(在第一次运行后)并给出以下错误:

TypeError: Cannot read property 'rows' of undefined
    at null.callback (/Users/yc/nodeProjects/pgExpress.js:11:33)
    at Query.handleError (/Users/yc/nodeProjects/node_modules/pg/lib/query.js:106:17)
    at null.<anonymous> (/Users/yc/nodeProjects/node_modules/pg/lib/client.js:171:26)
    at emitOne (events.js:90:13)
    at emit (events.js:182:7)
    at Socket.<anonymous> (/Users/yc/nodeProjects/node_modules/pg/lib/connection.js:59:10)
    at emitOne (events.js:90:13)
    at Socket.emit (events.js:182:7)
    at Socket.writeAfterFIN [as write] (net.js:281:8)
    at Connection.query (/Users/yc/nodeProjects/node_modules/pg/lib/connection.js:189:15)

如果我在不使用 Express 的情况下重写相同的程序,它就可以无限期地正常工作。

  1 var conString = "pg://postgres@localhost:5432/foobardb";
  2
  3 var http = require('http');
  4 var pg = require('pg');
  5
  6 var server = http.createServer(function(req, res) {
  7     pg.connect(conString, function(err, client, done) {
  8
  9         client.query("select * from visit", function(err, result) {
 10             done();
 11             res.end(JSON.stringify(result.rows[0]));
 12           });
 13         });
 14 });
 15 server.listen(3001);

除了使用 Express 之外,代码是相同的。我真的很困惑。我的猜测是它可能与缓存有关,尽管为什么当我不使用 Express 时它会消失,这超出了我的理解。一个修复,或者如何解决这个问题(同时仍然使用 Express)将不胜感激!

【问题讨论】:

    标签: node.js postgresql express node-postgres


    【解决方案1】:

    这不是关于快递,而是关于你的数据库连接逻辑错误。

    在您的初始代码中,您首先连接到数据库,然后设置 HTTP 侦听器,然后进行查询,然后释放连接。在第二次通话中,您将泄露您的连接。你所做的事情的逻辑完全被打破了。

    你应该这样做:设置HTTP监听器,一旦你得到请求,连接到数据库,进行查询,释放连接。

    如果您想要一种不需要关心连接的更简单的方法,请查看pg-promise ;)

    【讨论】:

    • 通过 http 侦听器(使用 Express),我假设您的意思是路由。如果我先建立路由,然后建立连接:这意味着我必须在每条路由内部建立一个新的连接——在一个普通的服务器程序中,会有大量的路由。您确定在每条路由中定义一个新的客户端池(通过使用 pg.connect)是一个好主意吗?除了使用承诺之外,您会建议什么?我可以在前 30 秒内发出任意数量的请求(2 个或 30 个或 50 个),所以我不太确定这只是连接泄漏。
    • @Yogesch 你误解了pg.connect 的作用。它不会创建新池,而是从现有池中拉出连接。然后done() 将连接释放回池中。
    • @Yogesch 池在第一次调用时自动创建,在应用程序生命周期内重复使用,除非它没有被使用 poolIdleTimeout 毫秒。
    • 非常感谢!我开始对此感到相当困惑。在文档github.com/brianc/node-postgres/wiki/pg 中它说:“使用 pg 对象来创建池客户端”。我将编辑 wiki 以包含类似“它仅在第一次调用时创建一个池,而不在后续调用中创建新池,它从现有池中拉一个连接”之类的内容,以避免这种混乱。
    猜你喜欢
    • 2017-02-12
    • 1970-01-01
    • 2019-05-24
    • 2014-05-10
    • 1970-01-01
    • 2016-11-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多