【问题标题】:After first successful query to heroku postgres table, every query after fails第一次成功查询heroku postgres表后,每次查询都失败
【发布时间】:2020-10-15 06:38:03
【问题描述】:

这是部署到 Heroku 的服务器端 Web 应用程序(Node.js 和 Express)。我正在使用 Heroku Postgres 插件(client 指的是连接到我的 Heroku Postgres 数据库)。

我使用this 作为参考来构建我的承诺。

第一次 GET 请求成功,返回结果为client.query('SELECT * FROM passenger WHERE username = $1;', [username])。第二个 GET 请求收到内部服务器错误,并且每个 GET 请求之后都收到相同的错误。我不知道从哪里开始寻找导致问题的原因?我不确定为什么它会工作一次,然后立即失败相同的 GET 请求。

JS 脚本

var express = require('express')
var app = express()
var bodyParser = require("body-parser")
var validator = require('validator')
var { check, validationResult } = require('express-validator')
const router = express.Router()
const data = require('./app.json')
const PORT = process.env.PORT || 5000

app.use(bodyParser.json())
app.use(bodyParser.urlencoded({extended: true}))

var cors = require('cors')
var corsOptions = {
    origin: '*',
    optionsSuccessStatus: 200
}

var connectionString = *censored*;
var { Client } = require('pg')
var client = new Client({
    connectionString: process.env.DATABASE_URL || connectionString,
    ssl:{
        rejectUnauthorized: false
    }
})
client.connect()

app.use('/', router)

router.get('/passenger.json', cors(corsOptions), check('username'), (req, res) => {
    var errors = validationResult(req)
    if (!errors.isEmpty() ||  Object.keys(req.query).length === 0){
        res.json([])
    }

    var username = req.query.username
    username = validator.escape(username)

    client
        .query('SELECT * FROM passenger WHERE username = $1;', [username])
        .then(result => res.json(result.rows))
        .catch(e => res.sendStatus(500))
        .then(() => client.end())
})

app.listen(PORT, () => console.log(`Listening on ${ PORT }`))

GET 请求尝试:

% curl -X GET "https://agile-dusk-02160.herokuapp.com/passenger.json?username=xIHNcana"
[{"username":"xIHNcana","lat":42.385408,"lng":-71.08689919999999},{"username":"xIHNcana","lat":42.385408,"lng":-71.08689919999999},{"username":"xIHNcana","lat":42.385408,"lng":-71.08689919999999},{"username":"xIHNcana","lat":42.385408,"lng":-71.08689919999999}]%                                         
% curl -X GET "https://agile-dusk-02160.herokuapp.com/passenger.json?username=xIHNcana"
Internal Server Error%  

引用两个 GET 请求的 Heroku 日志:

2020-06-24T22:25:14.123304+00:00 heroku[router]: at=info method=GET path="/passenger.json?username=xIHNcana" host=agile-dusk-02160.herokuapp.com request_id=07eca9c7-aaa2-45fd-a32c-55fe0551e4f6 fwd="73.126.3.226" dyno=web.1 connect=0ms service=20ms status=200 bytes=502 protocol=https
2020-06-24T22:25:15.520949+00:00 heroku[router]: at=info method=GET path="/passenger.json?username=xIHNcana" host=agile-dusk-02160.herokuapp.com request_id=28c34b65-c9cf-439f-901d-51ae220e90bf fwd="73.126.3.226" dyno=web.1 connect=0ms service=3ms status=500 bytes=273 protocol=https

这就是 heroku postgres 表的样子:

agile-????-?????::DATABASE=> select * from passenger;
 username |    lat    |        lng         
----------+-----------+--------------------
 xIHNcana | 42.385408 | -71.08689919999999
 USERNAME |     12.12 |              12.12
 xIHNcana | 42.385408 | -71.08689919999999
 USERNAME |     12.12 |              12.12
 xIHNcana | 42.385408 | -71.08689919999999
 USERNAME |     12.12 |              12.12
 xIHNcana | 42.385408 | -71.08689919999999
 USERNAME |     12.12 |              12.12
(8 rows)

【问题讨论】:

  • 检查 Postgres 日志。我打赌一个事务失败了,需要回滚。

标签: node.js postgresql express heroku heroku-postgres


【解决方案1】:

我通过pg-pool 模块从Client(单客户端连接)切换到Pool(连接池),现在它正在工作。从 here 开始,使用连接池的 node-postgres 注释最适合处理频繁查询的 Web 应用程序。我认为这些是我第一次尝试时遇到的问题:

  • PostgreSQL 服务器只能处理a limited number of clients at a time。根据您的 PostgreSQL 服务器的可用内存,如果您连接无限数量的客户端,您甚至可能会导致服务器崩溃。
  • PostgreSQL 一次只能在一个连接的客户端上以先进先出的方式处理一个查询。如果您的多租户 Web 应用程序仅使用一个连接的客户端,则所有同时请求中的所有查询都将一个接一个地串行执行。不好!
var express = require('express')
var app = express()
var bodyParser = require("body-parser")
var validator = require('validator')
var { check, validationResult } = require('express-validator')
const router = express.Router()
const data = require('./app.json')
const PORT = process.env.PORT || 5000

app.use(bodyParser.json())
app.use(bodyParser.urlencoded({extended: true}))

var cors = require('cors')
var corsOptions = {
    origin: '*',
    optionsSuccessStatus: 200
}

var connectionString = *censored*;
const { Pool } = require('pg')
const pool = new Pool({
    connectionString: process.env.DATABASE_URL || connectionString,
    ssl:{
        rejectUnauthorized: false
    }
})
pool.on('error', (err, client) => {
  console.error('Unexpected error on idle client', err)
  process.exit(-1)
})

router.get('/passenger.json', cors(corsOptions), check('username'), (req, res) => {
    var errors = validationResult(req)
    if (!errors.isEmpty() ||  Object.keys(req.query).length === 0){
        res.json([])
        return
    }

    var username = req.query.username
    username = validator.escape(username)

    pool.connect((err, client, done) => {
      if (err) throw err
      client.query('SELECT * FROM passenger WHERE username = $1;', [username], (err, result) => {
        done()
        if (err) {
          res.sendStatus(500)
        } else {
          res.json(result.rows)
        }
      })
    })
})

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-05-12
    • 1970-01-01
    • 2015-08-15
    • 1970-01-01
    • 2019-05-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多