在AWS EC2实例开发模式下运行Sails项目遇迁移错误求助
先理清楚你的情况:本地连接本地MySQL和AWS RDS都能正常运行迁移和种子数据,但部署到EC2实例后执行sails lift,在alter模式下迁移archive模型时出现握手超时错误,错误详情如下:
{ error: { Error: Handshake inactivity timeout at Handshake.
(/home/ubuntu/ipts/ipts-backend-sailjs/node_modules/mysql/lib/protocol/Protocol.js:164:17) at Handshake.emit (events.js:182:13) at Handshake.EventEmitter.emit (domain.js:441:20) at Handshake._onTimeout (/home/ubuntu/ipts/ipts-backend-sailjs/node_modules/mysql/lib/protocol/sequences/Sequence.js:129:8) at ontimeout (timers.js:436:11) at tryOnTimeout (timers.js:300:5) at listOnTimeout (timers.js:263:5) at Timer.processTimers (timers.js:223:10) } }
这个握手超时问题一般和网络连通性、连接配置或权限设置有关,给你几个具体的排查和解决方向:
检查EC2与RDS的网络连通性
先确认EC2实例能不能正常访问RDS的端点。你可以在EC2上执行telnet your-rds-endpoint 3306或者nc -zv your-rds-endpoint 3306测试端口是否通畅。如果不通,大概率是安全组配置出了问题:- 确保RDS的安全组允许EC2实例所在的安全组(或EC2的公网IP,若使用公网访问RDS)访问3306端口;
- 如果EC2和RDS不在同一个VPC,还要检查VPC peering是否配置正确,或者RDS是否开启了公网访问权限,同时EC2具备公网出口能力。
调整数据库连接超时配置
本地到RDS的网络环境和EC2到RDS的环境有差异,默认的连接超时时间可能太短。你可以在Sails的config/datastores.js里给数据库连接加上更长的超时参数:module.exports.datastores = { default: { adapter: 'sails-mysql', url: 'mysql://user:password@rds-endpoint:3306/dbname', // 把连接超时调整为60秒 connectTimeout: 60000, // 同时增加获取连接的超时时间 acquireTimeout: 60000 } };验证RDS数据库用户权限
虽然本地能正常执行alter操作,但RDS的数据库用户可能缺少必要权限。登录到RDS数据库,执行以下命令给用户授予ALTER权限:GRANT ALTER ON your_database_name.* TO 'your_db_user'@'%'; FLUSH PRIVILEGES;注意替换成你的实际数据库名和用户名,
%允许用户从任意地址连接,如果你限制了IP范围,就换成对应的IP段。统一MySQL客户端版本
本地和EC2上的mysqlnpm包版本不一致,可能导致握手协议兼容问题。你可以在本地执行npm list mysql查看版本号,然后在EC2上执行npm install mysql@具体版本号来统一版本。排查EC2资源瓶颈
如果EC2实例的CPU、内存资源不足,也可能引发连接超时。你可以用top或者htop命令查看EC2的资源使用情况,如果CPU长期高负载或内存不足,考虑升级EC2实例类型。
按照上面的步骤逐一排查,应该能解决这个握手超时的问题。
内容的提问来源于stack exchange,提问作者Tavish Aggarwal

