AWS RDS / EC2:TimeoutError:Knex:获取连接超时。游泳池可能已满

Posted

技术标签:

【中文标题】AWS RDS / EC2:TimeoutError:Knex:获取连接超时。游泳池可能已满【英文标题】:AWS RDS / EC2: TimeoutError: Knex: Timeout acquiring a connection. The pool is probably full 【发布时间】:2019-04-13 22:03:13 【问题描述】:

我正在尝试使用knexbookshelf ORMNode js 8.12.0 API 检索用户模型。数据库是Postgres 10.4

API 在本地运行良好,但托管在 ElasticBeanstalk EC2 和 RDS 上,出现错误:

未处理的拒绝 TimeoutError: Knex: Timeout getting a 联系。游泳池可能已经满了。你错过了一个 .transacting(trx) 调用?

我可以通过连接字符串/密码分别连接和查询RDS实例(输入后提示输入密码):

psql -h myinstance.zmsnsdbakdha.us-east-1.rds.amazonaws.com -d mydb -U myuser

安全组:

EC2 安全组(由 EB 设置)是sg-0fa31004bd2b763ce,RDS 有一个针对 PostgreSQL / TCP / 端口 5432 / 匹配源 (sg-0fa31004bd2b763ce) 的入站安全规则——所以看起来不像安全组有问题

RDS 是在 VPC 中创建的,但 VPC 的安全规则也是开放的:

- security groups attached (multiple)
    - name: mysgname
    - group ID: sg-05d003b66fe1a4a94
    - Inbound rules: 
        - All Traffic (0.0.0.0/0) 
        - HTTP (80) for TCP (0.0.0.0/0) 
        - SSH (22) for TCP (0.0.0.0/0) 
        - PostgreSQL (5432) for TCP (0.0.0.0/0) 

可公开访问:Yes

用户控制器:

router.get('/users', function(req, res) 
    new User.User('id': 1)
        .fetch(withRelated: ['addresses'])
        .then((user) => 
            res.send(user);
    );
);

Knexfile:

production: 
    client: 'pg',
    version: '7.2',
    connection: 
        host: process.env.PG_HOST || 'localhost',
        port: process.env.PG_PORT || '5432',
        user: process.env.PG_USER || 'myuser',
        password: process.env.PG_PASSWORD || '',
        database: process.env.PG_DB || 'mydb',
        charset: 'utf8',
    ,
    pool: 
        min: 2,
        max: 20
    ,
,

首先,为什么这只发生在 AWS 托管环境而不是本地。其次,我该如何解决这个问题?我应该为池增加max 吗?

【问题讨论】:

【参考方案1】:

您需要检查您的 VPC 中的网络访问控制列表 (NACL),并确保您的 INBOUND 和 OUTBOUND 配置正确。安全组是实例级别的安全,NACL 是子网级别的安全。

大多数情况下,当您在连接到自定义 VPC 中的某些内容时遇到超时错误,这将是安全组或 NACL 或两者的配置问题。

【讨论】:

为了测试,VPC 的入站安全组规则非常开放:i.imgur.com/G0HRqx3.png。这是不正确的吗?如果是这样,我在 VPC 上具体在哪里可以找到NACL 好的,我找到了 NACL — 以下是附加到 VPC 的子网列表:i.imgur.com/Vnq8QGT.png 这里是 NACL 选项卡:i.imgur.com/mQCSi0a.png — 它说“规则 100”允许所有流量,但 * 拒绝(我猜这是所有其他) 为该端口添加一个规则#200 用于入站和出站,但我在上面的代码中也注意到您为端口 5432 配置了安全组,并且您的代码显示为 5433? 抱歉 5433 是我的 SO 帖子中的错字。应该是5432【参考方案2】:

我有一个在 heroku 实例中运行的工作代码。我已经迁移到 EBS 并在这个错误中停留了几个小时。 Heroku 默认设置NODE_ENV=production,我的节点中有相应的配置。

但是 EBS 默认没有设置 NODE_ENV=production 所以我的代码被破坏了。

【讨论】:

以上是关于AWS RDS / EC2:TimeoutError:Knex:获取连接超时。游泳池可能已满的主要内容,如果未能解决你的问题,请参考以下文章

停止并启动在 EC2 和 mysql RDS 上运行 php 的 AWS Elastic Beanstalk

AWS ElasticBeanstalk EC2 到 RDS postgresql 连接

AWS EC2 向 RDS 发送 mysql_query 失败

AWS 安全组难题

如何用AWS EC2主机连接RDS

如何连接nodejs sequelize aws rds mysql数据库和ec2实例