Запрос Node PostgreSQL никогда не возвращается в некоторых веб-приложениях, но в других все в порядке

#node.js #postgresql #azure #node-postgres

#node.js #postgresql #azure #узел-postgres

Вопрос:

У меня есть веб-приложение, которое содержит программное обеспечение моего серверного узла, которое подключается к серверу PostgreSQL, который отлично работает в рабочей среде. Я запускаю свое веб-приложение в Azure.

Я создал 2 дополнительных слота развертывания (/ devel и /staging ), чтобы настроить достойный конвейер развертывания CI. И теперь я развертываю код в слоте devel (выбирая переключение на промежуточный этап, а затем на производство).

К сожалению, при тестировании веб-приложения от devel я столкнулся с проблемой, из-за которой мой запрос никогда не возвращается. Хотя это хорошо работает с моего Macbook на localhost. Когда I 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')
 

Когда вы запускаете код, вы получаете это в веб-приложении, где он работает:

 $ 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
 

И это можно получить при запуске из веб-приложения, откуда оно не работает:

 $ 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
 

Комментарии:

1. Я думаю, что это связано с сетью. Можете ли вы проверить брандмауэр, заблокированные порты и зоны доступности из своих инстансов?

Ответ №1:

Наконец-то я нашел решение:

Выясняется, что слоты, где испытательный стенд работал хорошо, где node 12-lts , в то время как другие, где node 14 early access слоты. Понизив их все, чтобы node 12-lts все вернулось в форму, и теперь все везде работает хорошо.