【发布时间】:2020-12-24 16:15:36
【问题描述】:
我有一个 Webapp,其中包含我的服务器节点软件,该软件连接到在生产中运行良好的 PostgreSql 服务器。我在 Azure 上运行我的 Web 应用程序。
我创建了 2 个额外的部署槽(/devel 和 /staging),以便设置一个体面的 CI 部署管道。现在我将代码部署到开发槽(选择切换到暂存,然后是生产)。
不幸的是,在从 devel 测试 Webapp 时,我遇到了一个问题,导致我的查询永远不会返回。虽然它在本地主机上的我的 Macbook 上运行良好。当我 sy 永远不会返回时,这意味着我没有任何返回或任何错误。
我设法制作了一个紧凑的自包含代码 sn-p 来演示该问题:要运行它,只需在 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')
当你运行代码时,你会在它工作的 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.js postgresql azure node-postgres