错误:握手不活动超时(MySQL + Node.js)

Posted

技术标签:

【中文标题】错误:握手不活动超时(MySQL + Node.js)【英文标题】:Error: Handshake inactivity timeout (MySQL + Node.js) 【发布时间】:2021-04-19 19:10:29 【问题描述】:

将 docker-compose 与 ngnix、节点后端和 mysql.js 一起使用。发生了这个错误:

api      | there was an error connecting to pool:  Error: Handshake inactivity timeout
api      |     at Handshake.<anonymous> (/app/node_modules/mysql/lib/protocol/Protocol.js:160:17)
api      |     at Handshake.emit (node:events:376:20)
api      |     at Handshake._onTimeout (/app/node_modules/mysql/lib/protocol/sequences/Sequence.js:124:8)
api      |     at Timer._onTimeout (/app/node_modules/mysql/lib/protocol/Timer.js:32:23)
api      |     at listOnTimeout (node:internal/timers:556:17)
api      |     at processTimers (node:internal/timers:499:7)
api      |     --------------------
api      |     at Protocol._enqueue (/app/node_modules/mysql/lib/protocol/Protocol.js:144:48)
api      |     at Protocol.handshake (/app/node_modules/mysql/lib/protocol/Protocol.js:51:23)
api      |     at PoolConnection.connect (/app/node_modules/mysql/lib/Connection.js:116:18)
api      |     at Pool.getConnection (/app/node_modules/mysql/lib/Pool.js:48:16)
api      |     at Pool.query (/app/node_modules/mysql/lib/Pool.js:202:8)
api      |     at /app/db/connect.js:18:10
api      |     at new Promise (<anonymous>)
api      |     at Object.connectionFunc (/app/db/connect.js:17:21)
api      |     at Object.<anonymous> (/app/routes/index.js:17:12)
api      |     at Module._compile (node:internal/modules/cjs/loader:1108:14) 
api      |   code: 'PROTOCOL_SEQUENCE_TIMEOUT',
api      |   fatal: true,
api      |   timeout: 10000
api      | 

正如另一篇文章提到的,我尝试更改超时但没有奏效。

我必须使用网络来连接我的 docker-compose 文件。我在不使用内部网络的情况下间歇性地让它工作,但其他时候我收到以下消息:

ERROR: could not find an available, non-overlapping IPv4 address pool among the defaults to assign to the network

这本身很奇怪,因为只有 3 个默认网络(也是我创建的一个)。其他帖子说,如果您使用超过 30 个或更多的网络,这应该会成为一个问题 -

root@ubuntu-s-1vcpu-1gb-nyc1-01:~/blog/blog# docker network ls
NETWORK ID     NAME       DRIVER    SCOPE
430e230e6641   bridge     bridge    local
915d73adee82   host       host      local
8cd9e79fd644   none       null      local
9f936dc688b7   underdev   bridge    local

也就是说,我已经在我的 docker-compose.yml 中尝试过这个

  db:
    container_name: db
    build: ./db
    command: --default-authentication-plugin=mysql_native_password
    restart: always
    ports:
      - "3306:3306"
    environment:
      - MYSQL_ALLOW_EMPTY_PASSWORD=True
      - MYSQL_DATABASE=secret
      - MYSQL_USER=secret
      - MYSQL_ROOT_PASSWORD=secret
      - MYSQL_PASSWORD=secret
    volumes:
      - db_data:/var/lib/mysql
    networks:
      - underdev
volumes:
  db_data: 
networks:
 underdev:
  external: true

我也试过这个:

networks:
  default:
    driver: bridge
    ipam:
      config:
        - subnet: 172.16.57.0/24

两者都修复了 ipv4 错误,但我仍然收到握手不活动超时错误。有人建议使用network_mode: bridge,但是网络不应该自动使用默认网桥吗?如果有人有任何想法,请告诉我。

PS:

这是与数据库的连接 - 我尝试向连接处理程序添加超时 - 超时有效,但连接仍然没有握手。

var mysql = require('mysql');
  var testconnection = mysql.createConnection(
    host: 'db',
    port: '3306',
    user: 'root',
    password: process.env.MYSQL_ROOT_PASSWORD,
    database: 'blog',
    debug: true
  )
  var pool  = mysql.createPool(
    connectionLimit : 100,
    host            : 'db',
    port            : '3306',
    //connectTimeout  : 20000,
    //acquireTimeout  : 20000,
    //timeout         : 20000,
    user            : 'root',
    password        : process.env.MYSQL_ROOT_PASSWORD,
    database        : 'blog'
  );
  console.log("-----------------------------------------------------");
  console.log("value of testconnection: ", testconnection);
  console.log("-----------------------------------------------------");
  testconnection.query("SELECT * from blogs", function(err, rows, fields)
    console.log("value of err: ", err);
    console.log("value of rows: ", rows);
    console.log("value of fields: ", fields);
  )
  console.log("-----------------------------------------------------");
  console.log("value of pool: ", pool);
  console.log("-----------------------------------------------------");
  let poolPromise = new Promise(resolve=>
    pool.query("SELECT * FROM blogs", function(err,rows,fields)
      /*
      console.log("value or err: ", err);
      console.log('value of rows: ', rows);
      console.log('value of fields: ', fields);
      */
      if (err)
        console.log('there was an error connecting to pool:', err);
        process.exit();
        resolve(false);
      else
        resolve(pool);
      
    )
  )

  return poolPromise;


module.exports = 
  connectionFunc

         

编辑:

我已经编写了完全卸载并完全重新安装 docker(包括所有文件夹和子目录)的脚本,但我仍然收到以下错误消息:

ERROR: could not find an available, non-overlapping IPv4 address pool among the defaults to assign to the network

这是删除所有 docker 的脚本:

#!/bin/bash
  
sudo apt-get purge -y docker-engine docker docker.io docker-ce docker-ce-cli
sudo apt-get autoremove -y --purge docker-engine docker docker.io docker-ce

sudo apt-get remove docker docker-engine docker.io containerd runc

sudo rm -rf /var/lib/docker /etc/docker
sudo rm /etc/apparmor.d/docker
sudo groupdel docker
sudo rm -rf /var/run/docker.sock

这是我用来安装 docker 的脚本(我确认它可以与 hello world 测试一起使用),它来自文档的此页面 (https://docs.docker.com/engine/install/ubuntu/) 中的命令:

#!/bin/bash
  

echo 'apt-get update'
echo '-------------------------------------------------------------------------------'
sudo apt-get update
echo '-------------------------------------------------------------------------------'
echo 'sudo apt-get install'
echo '-------------------------------------------------------------------------------'
yes | sudo apt-get install \
    apt-transport-https \
    ca-certificates \
    curl \
    gnupg-agent \
    software-properties-common
echo 'curl software'
echo '-------------------------------------------------------------------------------'
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
echo '-------------------------------------------------------------------------------'
echo 'add-apt-repository'
echo '-------------------------------------------------------------------------------'
sudo add-apt-repository \
   "deb [arch=amd64] https://download.docker.com/linux/ubuntu \
   $(lsb_release -cs) \
   stable"
echo 'sudo apt-get update'
echo '-------------------------------------------------------------------------------'
sudo apt-get update
echo '-------------------------------------------------------------------------------'
echo 'install docker-ce-cli'
echo '-------------------------------------------------------------------------------'
yes | sudo apt-get install docker-ce docker-ce-cli containerd.io
echo '-------------------------------------------------------------------------------'

编辑:

在 docker-compose 文件中将 links 变量添加到 tha api 容器并不能解决问题:

    networks:
      - underdev
    links:
      - db:db

编辑:

尝试重新启动服务器。那没有用,同样的错误。我也试过 通过

升级服务器
sudo apt-get upgrade && sudo apt-get dist-upgrade

并再次运行应用程序 - 同样的错误。

我目前正在运行 18.04.5 ubuntu bionic:

root@ubuntu-s-1vcpu-1gb-nyc1-01:~# lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description:    Ubuntu 18.04.5 LTS
Release:        18.04
Codename:       bionic

尝试升级到 20.04.1 还是不行。


【问题讨论】:

【参考方案1】:

我用另一种方式解决了这个问题。 这不是入站问题。 我正在使用“基于 SSH 的标准 TCP/IP”来连接 AWS 中的 Mysql-server。 正常是没有问题的。但它突然发生了。

“握手不活动超时”!!

我发现另一个应用程序正在绑定开发环境的3306端口。 您可以使用命令“netstat -anb”。 删除它并再次重新连接“标准 TCP/IP over SSH”后,问题就消失了。

【讨论】:

以上是关于错误:握手不活动超时(MySQL + Node.js)的主要内容,如果未能解决你的问题,请参考以下文章

连接节点 v5.10.1 时握手不活动超时错误。到 aws mysql RDS

Sails js错误:握手不活动超时

net/http:使用 KOPS 的 TLS 握手超时

使用 kops 在 gcp 上验证集群时出现 TLS 握手超时错误

Netty 设置 SSL 握手超时不起作用

WCF 不活动超时