对于一些可能会跌倒在这里的人!
如果这没有意义,并且您最近将 Nodejs 升级到了 v14!这可能是原因!
上次我就遇到了这个问题,把头发拉了一会儿!
我在尝试跟踪我所做的不同之后,以某种方式使用了 nvm!因为它之前工作过!我想到了并用v13测试了它!它又起作用了!
所以要注意!这可能会为您节省大量时间和压力!
Problem
Nodejs v14 做出了重大更改!和pg
模块受到影响! pg 开始让进程退出connect() call
!
修复节点 v14+
如果您正在使用postgres
!使用 Nodejs v14 及以上版本!确保使用驱动模块pg
在版本>=8.0.3
!并更好地升级到最新
npm install pg@latest --save
如果您不使用postgres
!尝试更新您的数据库驱动程序!可能是一样的吧!也尝试使用nodejsV13
。确认是同样的问题!
v14 中发生了什么
如果像我一样你想知道细节以及发生了什么!?
使用节点 V14! API 发生了一些重大变化!还有很多东西都改变了!包括Openssl版本!
对于postgres!和pg
模块!问题是这样描述的comment https://github.com/brianc/node-postgres/issues/2170#issuecomment-617556848根据这个thread https://github.com/brianc/node-postgres/issues/2170:
初始的readyState(一个私有/未记录的API,
net.Socket 的 pg 使用)似乎已从“关闭”更改为“开放”
在节点 14 中。
很难以完美的向后兼容性来修复,但我想我
有一个足够接近的补丁。
并且根据这个PR https://github.com/brianc/node-postgres/pull/2171!
您可以看到以下变化这个差异 https://github.com/brianc/node-postgres/pull/2171/commits/149f48232445da0fb3022044e4f1c53509040ad3
简而言之,如上所述! onReady 的 api 更改为net.Socket
!
实施的解决方案是根本不使用 onReady!
并且根据这个
现在,当在其上调用 connect 时,Connection 始终会在其流上调用 connect。
在旧版本中,仅当套接字打开时才调用 connectclosed
state! readyState
使用被消除!
Check 这条线 https://github.com/charmander/node-postgres/blob/149f48232445da0fb3022044e4f1c53509040ad3/packages/pg/lib/connection.js#L54
你能明白!
取决于实施!许多事情可能会或不会受到这些核心变化的影响!
Nodejs v14相关变更
因为我想看看变化发生在哪里!干得好
https://github.com/nodejs/node/pull/32272 https://github.com/nodejs/node/pull/32272
人们也可以检查更改日志:
https://github.com/nodejs/node/blob/master/doc/changelogs/CHANGELOG_V14.md https://github.com/nodejs/node/blob/master/doc/changelogs/CHANGELOG_V14.md
详细原因+退出并且没有日志记录错误
还要提一下重大变化!制成pg
使进程退出connect() call
。这就是它退出的原因!日志记录是可见的!
对此更详细!这是怎么发生的! Sequelize 有 postgres 方言实现!哪个用pg!还有pg客户端!创建连接!该连接有一个connect
事件!当它连接时它会发出它!而且因为节点 v14 将流的行为更改为以 open 开头!流连接被跳过!因为readyState
检查(预计已关闭,但实际上已打开!)!并且流被视为已连接(否则为块)!哪里不是!还有connect
事件直接发出!当这种情况发生时!客户端要么会调用requestSsl()
or startup()
连接对象的方法!两者都会调用this._stream.write
。因为流没有连接!发生错误!这个错误没有被catch!那么续集驱动程序中的承诺!将一直悬而未决!然后事件循环变空! Nodejs 默认行为只是退出!
您可以通过代码行看到该步骤:
- Sequelize pg 适配器将调用 pg 客户端来创建连接和承诺 https://github.com/sequelize/sequelize/blob/febc083adee2cd3e6f24b18a556acdc4c4f50f96/src/dialects/postgres/connection-manager.js#L123
- pg 客户端在连接对象上调用 connect https://github.com/brianc/node-postgres/blob/aafd8ac64e588e689ed08e7957bc3c91f8fe01e3/packages/pg/lib/client.js#L108
- PG连接connect()调用并发出connect!认为流已连接是因为 V14 更改 https://github.com/brianc/node-postgres/blob/aafd8ac64e588e689ed08e7957bc3c91f8fe01e3/packages/pg/lib/connection.js#L56
- PG客户端connect事件被捕获并回调运行!requestSsl() or startup()将运行 https://github.com/brianc/node-postgres/blob/aafd8ac64e588e689ed08e7957bc3c91f8fe01e3/packages/pg/lib/client.js#L115
- 其中一种方法运行并
stream.write
将被称为(请求SSL() https://github.com/brianc/node-postgres/blob/aafd8ac64e588e689ed08e7957bc3c91f8fe01e3/packages/pg/lib/connection.js#L140, 启动() https://github.com/brianc/node-postgres/blob/aafd8ac64e588e689ed08e7957bc3c91f8fe01e3/packages/pg/lib/connection.js#L164)
- 流错误(未捕获)
-
Promise https://github.com/sequelize/sequelize/blob/febc083adee2cd3e6f24b18a556acdc4c4f50f96/src/dialects/postgres/connection-manager.js#L123在sequelize postgres 适配器中!还是没有解决!
- 事件循环为空 => Nodejs => 退出
为什么nodejs退出(未解决的承诺)
https://github.com/nodejs/node/issues/22088 https://github.com/nodejs/node/issues/22088
节点退出时没有错误并且不等待承诺(事件回调) https://stackoverflow.com/questions/46914025/node-exits-without-error-and-doesnt-await-promise-event-callback
当 Promise 永远无法解决时会发生什么? https://stackoverflow.com/questions/46966890/what-happens-when-a-promise-never-resolves