node.js - 节点 PostgreSql 查询永远不会在某些 Web 应用程序上返回,但在其他应用程序上可以
问题描述
我有一个 Webapp,其中包含我的服务器节点软件,该软件连接到在生产中运行良好的 PostgreSql 服务器。我在 Azure 上运行我的 Webapp。
我创建了 2 个额外的部署槽(/devel 和 /staging),以便设置一个像样的 CI 部署管道。现在我将代码部署到开发槽(选择切换到暂存,然后是生产)。
不幸的是,在从 devel 测试 Webapp 时,我遇到了一个问题,使我的查询永远不会返回。虽然它在本地主机上的我的 Macbook 上运行良好。当我 sy 从不返回时,这意味着我没有任何返回或任何错误。
我设法制作了一个紧凑的自包含代码片段来演示该问题:要运行它,只需在 DATABASE_URL 环境变量中提供一个连接字符串。
经过几天的搜索,我真的不明白这种情况。希望你有一些线索。顺便说一句,有没有办法追踪 PostgreSql?
[更新] 我忘了提到我可以'could not receive data from client: An existing connection was forcibly closed by the remote host.'
在 PostgreSql 日志中看到一些。
// == 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')
当你运行代码时,你会在它工作的 webapp 上得到这个:
$ 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
一切都恢复了原状,现在一切都很好。
推荐阅读
- http - 如何从 http get 的正文中获取字符串模式匹配
- java - 如何为图像编写正确的 URL
- excel - 需要帮助使用 Text to Columns & Fieldinfo 在 Excel 中使用 VBA 解析列
- c# - EF - 需要定义主键
- jekyll - Jekyll - 尝试将图像添加到帖子中,但 Jekyll 找不到它们
- angular - How not to show the login page for a logged in user in angular
- javascript - Moment.js - 在同一小时内添加分钟到最后一分钟的结果
- db2 - 在 iSeries DB2 上重命名列
- nim-lang - 在 Nim 中处理 DateTime 中的 AM 和 PM
- c++ - 如何生成用于测试快速排序最佳案例的数组?