Node PostgreSql查询在某些Web应用程序上永远不会返回,但在其他应用程序上可以



我有一个Webapp,其中包含我的服务器节点软件,该软件连接到PostgreSql服务器,该服务器在生产中运行良好。我正在Azure上运行我的Web应用程序。

我创建了两个额外的部署槽(/devel和/staring(,以便设置一个像样的CI部署管道。现在,我将代码部署到devel插槽(选择切换到暂存,然后切换到生产(。

不幸的是,在测试来自devel的Webapp时,我遇到了一个问题,导致我的查询永远不会返回。尽管它在本地主机上的Macbook上运行得很好。当我sy从未返回时,这意味着我既没有返回也没有任何错误。

我设法制作了一个紧凑的自包含代码片段来演示这个问题:要运行它,只需要在DATABASE_URL环境变量中提供一个连接字符串。

经过几天的搜寻,我真的不了解情况。希望你有一些线索。顺便说一句,有没有办法追踪PostgreSql?

[更新]我忘了提一下,我可以在PostgreSql日志中看到一些'could not receive data from client: An existing connection was forcibly closed by the remote host.'

// == environment variables
require('dotenv').config()
// == PostgreSql object
const { Pool } = require('pg')
const sw = 'server.test.sql.js'
const prefix =  'PostgreSql>>  '
// == Make sure a connection string is provided
console.log(`${prefix}Checking PostgresSql connection string presence`)
if (!process.env.DATABASE_URL) throw new Error(`${prefix}*** error in '${sw}': YOU MUST PROVIDE 'process.env.DATABASE_URL' in your .env or configuration in order to be abl to connect to PostgreSql server`)
// == Create the client instance
console.log(`${prefix}Creating PostgresSql Pool instance`)
const pool = new Pool({connectionString: process.env.DATABASE_URL})
console.log(`${prefix}pool is OK`)//, pool)
//pool.connection.on('message', console.log)
/**
* @summary Test actual connection to the PostgreSql backend
*/
async function testConnection() {
try {
console.log(`--> ${prefix}.testConnection()`)
const response = await pool.query('SELECT NOW();')
const [ cols ] = response.rows
const now = cols.now
console.log(`<-- ${prefix}.testConnection() returned`, now)
return now
}
catch(err) {
console.log(`x-- ${prefix}.testConnection() error`, err)
}
finally {
console.log(`<-- ${prefix}.testConnection()`)
}
}
// == Actually connect to the server
console.log(`${prefix}Testing connection to PostgresSql`)
// == Check the connection
console.log(`--> calling ${prefix}.testConnection()`)
const res = testConnection()
.then((data) => {
console.log(`--- calling ${prefix}.testConnection() OK, returned`, data)
})
.catch(err => {
console.error(err)
})
.finally(() => {
console.log(`<-- calling ${prefix}.testConnection()`)
console.log(`--> calling ${prefix}.pool.end()`)
pool.end()
.then(data => {
console.log(`--- calling ${prefix}.pool.end() OK`)
})
.catch(err=> {
console.log(`x-- calling ${prefix}.pool.end() error`, err)
})
.finally(() => {
console.log(`<-- calling ${prefix}.pool.end()`)
console.log(`THE END: successfully exiting '${sw}', see you soon.`)
process.exit(0)
})
})


// === BELOW CODE IS HERE PREVENTS NODE TO TERMINATE BEFORE THE ABOVE PROMISE COMPLETES ===
// == Now wait for the connection completes before exiting (or CTRL-C)
process.stdin.resume();//so the program will not close instantly
function exitHandler(options, exitCode) {
if (options.cleanup) console.log('clean')
if (exitCode || exitCode === 0) console.log(exitCode)
if (options.exit) process.exit()
}
//== do something when app is closing
process.on('exit', exitHandler.bind(null,{cleanup:true}))
//== catches ctrl+c event
process.on('SIGINT', exitHandler.bind(null, {exit:true}))
//== catches "kill pid" (for example: nodemon restart)
process.on('SIGUSR1', exitHandler.bind(null, {exit:true}))
process.on('SIGUSR2', exitHandler.bind(null, {exit:true}))
//== catches uncaught exceptions
process.on('uncaughtException', exitHandler.bind(null, {exit:true}))

console.log('Now waiting for the connection to PostgreSql completes or use CTRL-C to exit')

当一个人运行代码时,你会在它工作的网络应用程序上得到这个:

$ node src/server.test.sql.js 
PostgreSql>>  Checking PostgresSql connection string presence
PostgreSql>>  Creating PostgresSql Pool instance
PostgreSql>>  pool is OK
PostgreSql>>  Testing connection to PostgresSql
--> calling PostgreSql>>  .testConnection()
--> PostgreSql>>  .testConnection()
Now waiting for the connection to PostgreSql completes or use CTRL-C to exit
<-- PostgreSql>>  .testConnection() returned 2020-12-22T20:48:40.293Z
<-- PostgreSql>>  .testConnection()
--- calling PostgreSql>>  .testConnection() OK, returned 2020-12-22T20:48:40.293Z
<-- calling PostgreSql>>  .testConnection()
--> calling PostgreSql>>  .pool.end()
--- calling PostgreSql>>  .pool.end() OK
<-- calling PostgreSql>>  .pool.end()
THE END: successfully exiting 'server.test.sql.js', see you soon.
clean
0

当从一个不起作用的Web应用程序运行时,就会出现这种情况:

$ node src/server.test.sql.js 
PostgreSql>>  Checking PostgresSql connection string presence
PostgreSql>>  Creating PostgresSql Pool instance
PostgreSql>>  pool is OK
PostgreSql>>  Testing connection to PostgresSql
--> calling PostgreSql>>  .testConnection()
--> PostgreSql>>  .testConnection()
Now waiting for the connection to PostgreSql completes or use CTRL-C to exit

我终于找到了解决方案:

结果表明,测试台运行良好的插槽位于node 12-lts,而其他插槽则位于node 14 early access。通过将它们全部降级为node 12-lts,一切都恢复了状态,现在一切都很好。

最新更新