在php+mysql的开发过程中,连接数据库的主机名填写时,本机一般可以用localhost或者127.0.0.1,实际应用过程中,Linux系统目前还没发现过异常,但在Windows server系统中,有的时候写localhost,网页反应就会出现比较慢的情况,一般一页都需要1秒以上,一步步对程序运行时间判断,发现是mysql连接时候的问题,建立一个连接需要将近1秒,必然是有问题的,搜索之,发现确实存在这个情况,很多程序员博客都有反应,摘抄记录如下:
http://blog.sina.com.cn/s/blog_6cb5a76f0100yfho.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. Note that higher precedence in prefix policies is represented by a lager "precedence" 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 试试看吧。