问题描述
PHP 写的后端程序,一旦涉及数据库操作,响应就会变得异常得慢(这里的异常是指:同样的程序在 Linux 下执行,速度没有问题),常常需要等待数十秒,但每次的返回结果中,实际用于执行 SQL 查询的时间均短至毫秒量级。
PHP 版本:7.2.25、7.2.13、7.1.33、5.3.3,无论老版本还是目前 7.2 最新的子版本都有一样的问题,看来官方似乎并不想处理。
问题排查
进行查询操作请求通过PHP 在 Windows 下运行时,遇到 localhost 会尝试先将其解析成 IPv6 地址,当无法解析或者无法用 IPv6 连接数据库时会等待超时,再尝试解析成 IPv4 地址,因此一旦遇到此类操作时就会出现很长的等待时间。
而通常情况下,大部分windows服务器、本地调试环境都是没有IPV6网络支持的,该问题的显著特征是:
在配置数据库连接信息时,使用127.0.0.1作为数据库连接地址响应比localhost快很多倍,毫秒计量。
流传的解决方法主要有:
1.修改 Windows 的 hosts 文件,加上一行 127.0.0.1 localhost,随后需要 flushdns 一下。
—— 这样似乎能够显式指定将 localhost 解析为 IPv4,但在自己的机器和服务器上都没有任何效果,怀疑 CGI 方式调用 PHP 的时候是无视主机文件的。
2.修改所有涉及 localhost 的 PHP 代码,把 localhost 替换成 127.0.0.1 的形式。
—— 这样做确实解决了一部分问题,但毕竟不是稳妥之计;而且对于 phpMyAdmin 等工具而言就只能冒险修改已经调试完善的代码。
3.禁用相关服务,Win + R 运行命令 services.msc 进入服务项管理,停止一个名称叫 IP Helper,服务名为 iphlpsvc 的服务。
—— 与方法 1 类似,看起来有道理但实际上也没起到任何效果。
4.回避问题,使用 5.2 以降的 PHP,甚至使用虚拟网卡、虚拟机这些办法。
—— 拜托,认真的吗??
很明显,以上方法效果基本没有,因此,通过大量时间对比分析,发现cmd中ping[localhost]其实指向的是::1,你这就好说了,::1是IPV6回环地址,那么只需要将本机的IPV6优先级降低即可。
只需在windows徽标键上点击右键选择Windows PowerShell(管理员)选项,
并执行以下两行命令,再ping一下[localhost],你就会发现解析地址变成了127.0.0.1,同时PHP站点响应也就恢复到了正常情况。
贴一下命令: [Shell] 纯文本查看 复制代码 netsh int ipv6 set prefix ::/96 50 0
先执行上面的
netsh int ipv6 set prefix ::1/128 1 9
|