RDS连不上,报个超时或者拒绝连接,这种求助我每周都得处理好几起。大多数时候,问题不在数据库本身,而是网络链路上某个环节卡住了。
别急着去改数据库参数,按下面这个顺序捋一遍,通常十分钟内能找到症结。
第一站:安全组——RDS的防火墙
跟EC2一样,RDS也有自己的安全组,管着谁能访问它的端口(默认MySQL是3306,PostgreSQL是5432)。
去RDS控制台,点进你的实例,看“连接和安全”那一栏,找到关联的安全组。入站规则里必须有一条:允许你的应用服务器(或者你的本地IP)访问数据库端口。
最容易翻车的地方是源IP写错了。如果你的应用跑在EC2上,别写EC2的公网IP,要写EC2所在子网的CIDR段,或者直接关联EC2的那个安全组ID(比如sg-xxxxxxxx)。这样哪怕EC2重启换IP,连接也不会断。
如果你是从本地电脑直连RDS测试(不推荐,但偶尔会这么干),源IP得是你家宽带的当前公网IP。要是动态IP,每次变了都要去更新。
第二站:检查是否开启了“公共访问”
RDS默认是放在私有子网里的,不给公网IP。你在控制台能看到一个“公开访问(Public accessibility)”的选项。
选“是”:RDS会拿到一个公网IP,可以从互联网直接连(前提是安全组放行了你的IP)。不太安全,只建议临时测试用。
选“否”:只有同VPC内的资源才能访问。这是生产环境的标准做法。
如果你的RDS选了“否”,而你的应用跑在另一个VPC,或者你在家办公想直连,那肯定超时。要么把RDS改成“公开访问”(测试环境可以),要么在应用和RDS之间搭个跳板机(Bastion),或者用VPC Peering把两个VPC打通。
第三站:网络ACL和子网路由——别忽略底层网络
安全组放行了,也开了公共访问,还是不通。这时候得往下查一层:子网关联的网络ACL。
网络ACL是子网级别的无状态防火墙。说“无状态”的意思是,进站的请求允许了,返回的流量还得单独在出站规则里明确放行。很多人只改了入站,出站没动,结果请求进去了,响应出不来,一样超时。
去VPC控制台找到“Network ACLs”,查你RDS所在子网关联的那一张:
入站规则:允许你的IP或CIDR访问数据库端口。
出站规则:允许返回流量(一般规则是“允许所有出站”就省心)。
另外,确认一下子网的路由表里,通往互联网网关(IGW)或者NAT网关的路由是通的。如果你是从公网连接,但RDS所在子网没有通往IGW的路由,那光开“公开访问”也没用。
第四站:数据库本身的用户权限
网络通了,但报错“Access denied for user”。这是数据库内部的问题了。
用RDS的主账号(创建时设置的那个)登录,看看你想用来连接的用户名,有没有被授予从你的主机地址访问的权限。
拿MySQL举例,用户权限是绑定主机(Host)的。如果你创建用户时写的是'myuser'@'localhost',那你从远程肯定连不上。需要改成'myuser'@'%'(允许任意主机)或者'myuser'@'你的应用服务器的IP'。
执行这条SQL看一下:SELECT host, user FROM mysql.user;
如果Host列显示的是localhost或者127.0.0.1,就用GRANT命令重新授权,把Host改成%或者具体的IP段。
第五站:连接池和并发数——数据库被“挤爆”了
这种情况比较隐蔽:安全组、网络、用户权限都查过了,但应用还是时不时报超时。大概率是数据库的连接数打满了。
去RDS控制台的监控面板(CloudWatch),看“Database Connections”这个指标。如果曲线一直顶着max_connections那条线跑,说明连接池不够用了。
解决办法有几个:
检查应用端的连接池配置(比如HikariCP),把最大连接数调低一点,别每个实例都占一堆连接不释放。
如果业务量确实大,升级RDS实例规格,或者换成支持更高连接数的参数组(比如调大
max_connections参数)。检查有没有“僵尸连接”——程序异常退出但连接没关,时间长了占满池子。重启应用或者手动
kill掉那些Sleep太久空闲连接。
第六站:打满的CPU和磁盘IO——响应太慢导致超时
连接数没满,但查询跑太久,客户端设置的超时时间短,也会报超时。
去监控里看一眼CPU利用率和读/写IOPS。如果CPU长期80%以上,或者IOPS顶着上限跑,说明数据库忙不过来。查询响应时间变长,应用端等的超过connect_timeout或socket_timeout,就直接掐断了。
这时候要做的是优化SQL(加索引、改查询写法),或者升级实例规格。直接拉配置是治标,优化查询是治本。
最后给你一张排查速查表
遇到RDS连接超时,按这个顺序过一遍:
安全组:入站规则是否允许你的应用IP访问数据库端口?
公共访问:RDS是否开启公开访问?没开的话只允许同VPC内连接。
网络ACL:入站和出站规则都放行了?尤其是出站别漏了。
用户权限:数据库用户的Host字段是否允许远程登录?
连接数:CloudWatch看是否打满max_connections。
CPU/IOPS:是否过载导致查询响应太慢触发客户端超时?
把这六个位置挨个查一遍,99%的连接问题都能解决。别一上来就重启RDS,那跟电脑卡了按电源键一样,未必有用。