connection timed out本质是tcp连接建立阶段超时,主因包括mysql未监听对应地址端口、docker网络隔离、云平台安全组拦截、dns解析延迟或mysql的connect_timeout过小;需用telnet、mysql命令及nslookup逐层验证网络通路。

Connection timeout 错误本质是网络层或服务层阻塞
CodeIgniter 报 Connection timed out 或 (HY000/2002): Connection timed out,不是框架问题,而是 PHP 尝试建立 TCP 连接时,在指定时间内(默认 30 秒)收不到 MySQL 服务响应。常见于远程数据库、Docker 网络隔离、防火墙拦截或 MySQL 未监听公网端口等场景。
-
hostname写成localhost却走 TCP?Linux 下它默认走 Unix socket,但若你强制用 TCP(比如加了 port 参数),而 MySQL 没开skip-networking或绑定了127.0.0.1而非0.0.0.0,就会卡住等待 - Docker 容器间连接用
localhost指向容器自身,而非宿主机或另一容器——必须用服务名(如mysql)或宿主机 IP(host.docker.internal) - 云服务器(如阿里云、腾讯云)安全组默认关闭 3306 端口,即使 MySQL 配置了
bind-address = 0.0.0.0,外部请求仍被拦截 - MySQL 的
connect_timeout值过小(如设为 2 秒),而网络延迟或 DNS 解析慢,导致 PHP 层先超时
如何快速验证是网络通路问题
别急着改 CodeIgniter 配置,先绕过框架确认底层连通性:
- 在 CI 服务器上执行:
telnet 127.0.0.1 3306(或目标 IP + 端口)。如果卡住或报Connection refused,说明 MySQL 没在监听该地址+端口 - 执行:
mysql -h 127.0.0.1 -u your_user -p -P 3306,看能否手动登录。失败则重点查 MySQL 用户权限、bind-address、防火墙(ufw status或iptables -L) - 若用 Docker,进 PHP 容器执行:
ping mysql和nc -zv mysql 3306,确认服务名可解析且端口开放
database.php 中 timeout 相关参数不解决根本问题
CI3 的 $db['default']['port'] 和 $db['default']['pconnect'] 不控制连接超时;mysqli 驱动本身不暴露 connect timeout 设置入口。所谓“调大超时”只能靠 PHP 层干预:
- 在
application/config/database.php顶部加:ini_set('default_socket_timeout', 60);(仅影响部分 socket 操作,不可靠) - 更有效的是在连接前手动设置:在控制器中
$this->load->database()前插入:mysqli_options($mysqli_link, MYSQLI_OPT_CONNECT_TIMEOUT, 10);——但这需自己接管连接,违背 CI 设计初衷 - 真正该做的是:把
hostname改为明确 IP(如127.0.0.1)、关掉 MySQL 的skip-name-resolve(避免 DNS 反查拖慢)、确保wait_timeout和interactive_timeout足够大(但它们管的是已连接后的空闲超时,不是连接阶段)
容易被忽略的 DNS 解析延迟
当 hostname 是域名(如 db.example.com)而非 IP 时,PHP 每次连接都触发 DNS 查询。若 DNS 服务器响应慢或失败,就会直接触发超时——这个过程 CI 完全不报 DNS 错误,只显示笼统的 Connection timed out。
- 用
nslookup db.example.com或dig db.example.com测 DNS 响应时间 - 临时把域名换成 IP 地址测试,若立刻恢复,就是 DNS 问题
- 生产环境建议在
/etc/hosts中静态绑定关键数据库域名,绕过 DNS
超时问题最麻烦的点在于:它不报错细节,只留一个模糊提示。定位必须从网络层开始,而不是一上来就翻 CI 配置或写重试逻辑。











