【问题标题】:Express keeping connection open?快速保持连接打开?
【发布时间】:2014-07-05 01:23:27
【问题描述】:

我使用 node js、express 和 postgresql 作为后端。 这是我用来制作rest API的方法:

exports.schema = function (inputs, res) {
  var query = knex('schema')
    .orderBy('sch_title', 'asc')
    .select();

  query.exec(function (err, schemas) {
    if(err){
      var response = {
        message: 'Something went wrong when trying to fetch schemas',
        thrownErr: err
      };
      console.error(response);
      res.send(500, response);
    }
    if(schemas.length === 0){
      var message = 'No schemas was found';
      console.error(message);
      res.send(400, message);
      return;
    }
    res.send(200, schemas);
  });
};

它可以工作,但一段时间后 postgres 会记录一个错误并且它不再工作:

sorry, too man clients already

我是否需要以某种方式关闭每个请求?在 express 文档中找不到任何关于此的内容。有什么问题?

此错误仅发生在生产服务器上。不在开发机器上。

更新 该应用程序仅在一个“模块”中制动。该应用程序的其余部分工作正常。所以只有一些查询会给出错误。

【问题讨论】:

  • 看起来数据库连接在完成查询时没有关闭。不是快递。
  • 这绝对是你的 postgres 的问题,而不是 express 的问题。能贴出数据库代码的相关部分吗?
  • @jeremy,我只是在创建带有列的表。那里没有有趣的事情发生。我不需要在我的 REST-api 中使用任何“关闭”命令吗?
  • 你的应用应该只有一个连接调用和一个到 postgres 的连接,它不应该在典型操作期间被关闭

标签: node.js postgresql express


【解决方案1】:

只需为您的整个应用保持一个连接打开即可。 docs shows an example 怎么做呢。

此代码进入您的app.js...

var Knex  = require('knex');
Knex.knex = Knex.initialize({
  client: 'pg',
  connection: {
    // your connection config
  }
});

当你想在你的控制器/中间件中查询时......

var knex = require('knex').knex;

exports.schema = function (req, res) {
    var query = knex('schema')
        .orderBy('sch_title', 'asc')
        .select();
    // more code...
};

如果您将Knex.initialize 放在app.useapp.VERB 中,它会为每个请求重复调用,因此您最终会多次连接到PG。

在大多数情况下,您不需要为每个 HTTP 请求执行打开+查询+关闭。

【讨论】:

  • 在这种情况下,您建议在哪里执行 knex.destroy()?或者如果服务器出现故障,连接可能被破坏就足够了吗?
  • 连接会过期,但如果你想要一个更优雅的解决方案,你可以使用 Node.JS 进程监听SIGTERM 事件。像这样:gist.github.com/hyubs/2dbc0265b8079948c92b