問題描述
PHP 寫的後端程序,一旦涉及數據庫操作,響應就會變得異常得慢(這裏的異常是指:同樣的程序在 Linux 下執行,速度沒有問題),常常需要等待數十秒,但每次的返回結果中,實際用於執行 SQL 查詢的時間均短至毫秒量級。
PHP 版本:7.2.25、7.2.13、7.1.33、5.3.3,無論老版本還是目前 7.2 最新的子版本都有一樣的問題,看來官方似乎並不想處理。
問題排查
進行查詢操作請求時,我用的代碼是如下的形式:
$db_host = "localhost";
$db_connect = mysqli_connect($db_host,$db_username,$db_password,$db_targetdb);
// mysqli_query ...
通過搜索瞭解到 PHP 在 Windows 下運行時,遇到 localhost 會嘗試先將其解析成 IPv6 地址,當無法解析或者無法用 IPv6 連接數據庫時會等待超時,再嘗試解析成 IPv4 地址,因此一旦遇到此類操作時就會出現很長的等待時間。
流傳的解決方法
目前網上給出的方法主要有:
- 修改 Windows 的 hosts 文件,加上一行
127.0.0.1 localhost
,隨後需要 flushdns 一下。
—— 這樣似乎能夠顯式指定將 localhost 解析爲 IPv4,但在自己的機器和服務器上都沒有任何效果,懷疑 CGI 方式調用 PHP 的時候是無視主機文件的。 - 修改所有涉及 localhost 的 PHP 代碼,把 localhost 替換成
127.0.0.1
的形式。
—— 這樣做確實解決了一部分問題,但畢竟不是穩妥之計;而且對於 phpMyAdmin 等工具而言就只能冒險修改已經調試完善的代碼。 - 禁用相關服務,Win + R 運行命令
services.msc
進入服務項管理,停止一個名稱叫 IP Helper,服務名爲iphlpsvc
的服務。
—— 與方法 1 類似,看起來有道理但實際上也沒起到任何效果。 - 迴避問題,使用 5.2 以降的 PHP,甚至使用虛擬網卡、虛擬機這些辦法。
—— 拜託,認真的嗎??
比較好的解決辦法
最後通過修改註冊表禁用 IPv6 組件,較好地解決了問題。新建一個註冊表項(擴展名 .reg
的純文本)文件,內容如下:
Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip6\Parameters]
"DisabledComponents"=dword:000000ff
保存,雙擊導入(或者按照文件的內容自行修改註冊表),重啓計算機即可。