在php+mysql的開發過程中,連接資料庫的主機名稱填寫時,本機一般可以用localhost或127.0.0.1,實際應用過程中,Linux系統目前還沒發現過異常,但在Windows server系統中,有的時候寫localhost,網頁反應就會出現比較慢的情況,一般一頁都需要1秒以上,一步步對程式運行時間判斷,發現是mysql連線時候的問題,建立一個連線需要將近1秒,必然是有問題的,搜尋之,發現確實存在這個情況,很多程式設計師部落格都有反應,摘抄記錄如下:

HTTP://blog.斯納.com.才能/是/blog_6成本5啊76發0100一幅畫哦.HTML

最近發現程式反應時間有點慢,於是逐漸的排除,計算每段程式執行的時間,最後發現時間損耗都花在了連結資料庫上,資料庫連結也沒有什麼好的辦法,於是便放下它了。

隔天,我測試一下資料庫的遠端鏈接,發現我用IP訪問資料庫的執行時間很短要遠遠小於我在本地用localhost連接資料庫。於是便有了下面一段測驗:

set_time_limit(0) ;
$localtime = 0 ;
for($i=1;$i<=50;$i++){
 $btime = get_microtime() ;   
 $conn = new mysqli("localhost","root","admin","") ;
 $conn-close() ;
 $etime = get_microtime() ;
 $localtime += $etime-$btime ;
}
$iptime =0 ;
for($i=1;$i<=50;$i++){
 $btime = get_microtime() ;   
 $conn = new mysqli("127.0.0.1","root","admin","") ;
 $conn-close() ;
 $etime = get_microtime() ;
 $iptime += $etime-$btime ;
}
echo "localhost时间损耗为:".($localtime)/$i."<br /" ;
echo "127.0.0.1时间损耗为:".($iptime/$i)."<br /" ;
function get_microtime(){
 list($micro,$time) = explode(" ",microtime());
 return $time+$micro ;
}


輸出結果為: localhost時間損耗為:0.98833055122226

127.0.0.1時間損耗為:0.0039590807522044

 

兩種連接方式的時間損耗差異很大,若有高手幫忙解答一下就好了。

自己猜測了一下,可能是DNS解析的原因了,是不是因為localhost的解析需要時間了。 說明一下我用的是window系統。

原因解釋:

確實是作業系統解析的問題,具體參考http://www.cnblogs.com/hayywcy/p/5341550.html

今天遇到個奇怪的問題,localhost 訪問時提示 not found 404,但是有127.0.0.1可以訪問。最後找到原因,是因為windows把 localhost 解析為 ipv6 位址 ::1 而不是 127.0.0.1。我檢查了hosts把ipv6已經封鎖了,127.0.0.1 localhost 也有,就是無法正常解析。百度查了半天無果,最後用科學上網法在google找到了解決辦法,為防止原貼丟失,轉貼至此(原貼地址:http://superuser.com/questions/436574/ipv4-vs-ipv6- priority-in-windows-7/436944#436944)。

文章內容:

SOLUTION #1: ADD A PREFIX POLICY TO PREFER IPV4 ADDRESSES OVER IPV6 Prefix policy table is similar a routing table, it determines which IP addresses are preferred when making a connection。 value, exactly opposite to routing table "cost" value.

Default Windows prefix policy table:

C:\netsh interface ipv6 show prefixpolicies Querying active state...

 Precedence  Label  Prefix

 ----------  -----  ----------------------------------------- ---

 50      0  ::1/128

 40      1  ::/0

 30      2  2002::/16

 20      3  ::/96

 10      4  ::ffff:0:0/96

  5      5  2001::/32 Note that IPv6 addresses (::/0) are preferred over IPv4 addresses (::/96, ::ffff:0:0/96) .

 

We can create a policy that will make Hurricane Electric IPv6 tunnel less favourable than any IPv4 address:

netsh interface ipv6 add prefixpolicy 2001:470::/32 3 6 2001:470::/32 is Hurricane Electric's prefix, 3 is a Precedence (very low) and 6 is a Label.

I could have used a more generic prefix, but I wanted to make sure than if and when I get a direct IPv6 connectivity from an ISP, it will take precedence over IPv4.

If you adapt this solution, you need to substitute an appropriate IPv6 prefix instead of my Hurricane Electric one.

SOLUTION #2: TWEAK REGISTRY TO MAKE WINDOWS ALWAYS PREFER IPV4 OVER IPV6

This solution is more generic, but more invasive and less standards-compliant. In the end, Windows will still modify the prefix policy table for you.

Open RegEdit, navigate to HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\tcpip6\Parameters Create DisabledComponents DWORD registry value, set its value to 20 (Hexadecimal).

SeeMicrosoft KB 929852 for more info about this registry key, especially if DisabledComponentsalready exists on your system. Reboot.

對照著翻譯大概就是windows有優先解析列表,當ipv6的優先權高於ipv4時,就會出現我今天遇到的情況(雖然會這樣的原因依然沒找到)。第一個辦法是加一條優ipv4優先權高於ipv6的記錄到優先解析表中,因為很多字都看不懂,怕弄錯參數,沒敢用。我是用第二個辦法解決的,就是修改註冊表,方法如下(不懂英文的朋友就不用查了):

開啟登錄表,找到鍵HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\tcpip6\Parameters,新增類型為DWORD 名字為 DisabledComponents 的項目(已經有了的不用加直接改值)。然後修改值為20,值類型為16進位。這樣就完了,之後儲存註冊表,重新啟動電腦。重新ping 下 localhost 試試看。


發表評論