首页 > 解决方案 > 节点 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.jspostgresqlazurenode-postgres

解决方案


我终于找到了解决方案:

可以看出,测试台运行良好的插槽在哪里,node 12-lts而其他node 14 early access插槽在哪里。通过将它们全部降级,node 12-lts一切都恢复了原状,现在一切都很好。


推荐阅读