所有 vagrant PHP CLI 脚本挂起等待 Mac OS X 上的主机解析

All vagrant PHP CLI scripts hang waiting on host resolution on Mac OS X

在我的 Homestead vagrant box 运行ning Ubuntu 上执行 PHP 命令时,我遇到了问题。在控制台甚至开始 php cli 执行之前存在明显的滞后。

运行 strace -vyT -S time php artisan help 来自 vagrant box。在第一次到最后一次调用 recvfrom(3 时,一切都卡住了几分钟,但我不知道为什么:

open("/etc/resolv.conf", O_RDONLY|O_CLOEXEC) = 3 <0.000010>
fstat(3</run/resolvconf/resolv.conf>, {st_dev=makedev(0, 16), st_ino=7632, st_mode=S_IFREG|0644, st_nlink=1, st_uid=0, st_gid=0, st_blksize=4096, st_blocks=8, st_size=171, st_atime=2015/10/17-04:53:56, st_mtime=2015/10/17-04:53:54, st_ctime=2015/10/17-04:53:54}) = 0 <0.000007>
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fed9385c000 <0.000008>
read(3</run/resolvconf/resolv.conf>, "# Dynamic resolv.conf(5) file fo"..., 4096) = 171 <0.000010>
read(3</run/resolvconf/resolv.conf>, "", 4096) = 0 <0.000006>
close(3</run/resolvconf/resolv.conf>)   = 0 <0.000008>
munmap(0x7fed9385c000, 4096)            = 0 <0.000011>
uname({sysname="Linux", nodename="homestead", release="3.13.0-65-generic", version="#106-Ubuntu SMP Fri Oct 2 22:08:27 UTC 2015", machine="x86_64", domainname="(none)"}) = 0 <0.000006>
stat("/etc/resolv.conf", {st_dev=makedev(0, 16), st_ino=7632, st_mode=S_IFREG|0644, st_nlink=1, st_uid=0, st_gid=0, st_blksize=4096, st_blocks=8, st_size=171, st_atime=2015/10/17-04:53:56, st_mtime=2015/10/17-04:53:54, st_ctime=2015/10/17-04:53:54}) = 0 <0.000008>
open("/etc/hosts", O_RDONLY|O_CLOEXEC)  = 3 <0.000009>
fstat(3</etc/hosts>, {st_dev=makedev(8, 1), st_ino=1161, st_mode=S_IFREG|0644, st_nlink=1, st_uid=0, st_gid=0, st_blksize=4096, st_blocks=8, st_size=251, st_atime=2015/10/16-18:57:29, st_mtime=2014/10/03-01:16:42, st_ctime=2014/10/03-01:16:42}) = 0 <0.000005>
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fed9385c000 <0.000008>
read(3</etc/hosts>, "127.0.0.1 localhost\n\n# The follo"..., 4096) = 251 <0.000009>
read(3</etc/hosts>, "", 4096)           = 0 <0.000007>
close(3</etc/hosts>)                    = 0 <0.000007>
munmap(0x7fed9385c000, 4096)            = 0 <0.000010>
socket(PF_INET, SOCK_STREAM, IPPROTO_IP) = 3 <0.000012>
fcntl(3<socket:[78362]>, F_SETFL, O_RDONLY|O_NONBLOCK) = 0 <0.000006>
connect(3, {sa_family=AF_INET, sin_port=htons(9000), sin_addr=inet_addr("127.0.0.1")}, 16) = -1 EINPROGRESS (Operation now in progress) <0.000094>
select(4, [3<socket:[78362]>], [3<socket:[78362]>], [3<socket:[78362]>], {0, 200000}) = 1 (out [3], left {0, 199997}) <0.000010>
getpeername(3, {sa_family=AF_INET, sin_port=htons(9000), sin_addr=inet_addr("127.0.0.1")}, [16]) = 0 <0.000007>
fcntl(3<socket:[78362]>, F_SETFL, O_RDONLY) = 0 <0.000006>
setsockopt(3, SOL_TCP, TCP_NODELAY, "[=13=][=13=][=13=][=13=][=13=][=13=][=13=]", 8) = 0 <0.000008>
write(3<socket:[78362]>, "478[=13=]<?xml version=\"1.0\" encoding"..., 483) = 483 <0.000042>
brk(0x2f93000)                          = 0x2f93000 <0.000472>
recvfrom(3, 0x7ffc489b16d0, 128, 0, 0, 0) = ? ERESTARTSYS (To be restarted if SA_RESTART is set) <4.940291>
--- SIGWINCH {si_signo=SIGWINCH, si_code=SI_KERNEL} ---
recvfrom(3, 0x7ffc489b16d0, 128, 0, 0, 0) = ? ERESTARTSYS (To be restarted if SA_RESTART is set) <0.072574>
--- SIGWINCH {si_signo=SIGWINCH, si_code=SI_KERNEL} ---
recvfrom(3, 0x7ffc489b16d0, 128, 0, 0, 0) = ? ERESTARTSYS (To be restarted if SA_RESTART is set) <0.033758>
--- SIGWINCH {si_signo=SIGWINCH, si_code=SI_KERNEL} ---
recvfrom(3, 0x7ffc489b16d0, 128, 0, 0, 0) = ? ERESTARTSYS (To be restarted if SA_RESTART is set) <0.038904>
--- SIGWINCH {si_signo=SIGWINCH, si_code=SI_KERNEL} ---
recvfrom(3, 0x7ffc489b16d0, 128, 0, 0, 0) = ? ERESTARTSYS (To be restarted if SA_RESTART is set) <0.026003>
--- SIGWINCH {si_signo=SIGWINCH, si_code=SI_KERNEL} ---
recvfrom(3, 0x7ffc489b16d0, 128, 0, 0, 0) = ? ERESTARTSYS (To be restarted if SA_RESTART is set) <0.024057>
--- SIGWINCH {si_signo=SIGWINCH, si_code=SI_KERNEL} ---
recvfrom(3, 0x7ffc489b16d0, 128, 0, 0, 0) = ? ERESTARTSYS (To be restarted if SA_RESTART is set) <0.055221>
--- SIGWINCH {si_signo=SIGWINCH, si_code=SI_KERNEL} ---
recvfrom(3, 0x7ffc489b16d0, 128, 0, 0, 0) = ? ERESTARTSYS (To be restarted if SA_RESTART is set) <0.058240>
--- SIGWINCH {si_signo=SIGWINCH, si_code=SI_KERNEL} ---
recvfrom(3, 0x7ffc489b16d0, 128, 0, 0, 0) = ? ERESTARTSYS (To be restarted if SA_RESTART is set) <0.027569>
--- SIGWINCH {si_signo=SIGWINCH, si_code=SI_KERNEL} ---
recvfrom(3, 0x7ffc489b16d0, 128, 0, 0, 0) = ? ERESTARTSYS (To be restarted if SA_RESTART is set) <0.056877>
--- SIGWINCH {si_signo=SIGWINCH, si_code=SI_KERNEL} ---
recvfrom(3, 0x7ffc489b16d0, 128, 0, 0, 0) = ? ERESTARTSYS (To be restarted if SA_RESTART is set) <0.025934>
--- SIGWINCH {si_signo=SIGWINCH, si_code=SI_KERNEL} ---
recvfrom(3, 0x7ffc489b16d0, 128, 0, 0, 0) = ? ERESTARTSYS (To be restarted if SA_RESTART is set) <0.076699>
--- SIGWINCH {si_signo=SIGWINCH, si_code=SI_KERNEL} ---
recvfrom(3, 0x7ffc489b16d0, 128, 0, 0, 0) = ? ERESTARTSYS (To be restarted if SA_RESTART is set) <0.089092>
--- SIGWINCH {si_signo=SIGWINCH, si_code=SI_KERNEL} ---
recvfrom(3, 0x7ffc489b16d0, 128, 0, 0, 0) = ? ERESTARTSYS (To be restarted if SA_RESTART is set) <0.254680>
--- SIGWINCH {si_signo=SIGWINCH, si_code=SI_KERNEL} ---
recvfrom(3, 0x7ffc489b16d0, 128, 0, 0, 0) = ? ERESTARTSYS (To be restarted if SA_RESTART is set) <0.131634>
--- SIGWINCH {si_signo=SIGWINCH, si_code=SI_KERNEL} ---
recvfrom(3, 0x7ffc489b16d0, 128, 0, 0, 0) = ? ERESTARTSYS (To be restarted if SA_RESTART is set) <0.065721>
--- SIGWINCH {si_signo=SIGWINCH, si_code=SI_KERNEL} ---
recvfrom(3, 0x7ffc489b16d0, 128, 0, 0, 0) = ? ERESTARTSYS (To be restarted if SA_RESTART is set) <0.042778>
--- SIGWINCH {si_signo=SIGWINCH, si_code=SI_KERNEL} ---
recvfrom(3, 0x7ffc489b16d0, 128, 0, 0, 0) = ? ERESTARTSYS (To be restarted if SA_RESTART is set) <0.072277>
--- SIGWINCH {si_signo=SIGWINCH, si_code=SI_KERNEL} ---
recvfrom(3, 0x7ffc489b16d0, 128, 0, 0, 0) = ? ERESTARTSYS (To be restarted if SA_RESTART is set) <0.044424>
--- SIGWINCH {si_signo=SIGWINCH, si_code=SI_KERNEL} ---
recvfrom(3, 0x7ffc489b16d0, 128, 0, 0, 0) = ? ERESTARTSYS (To be restarted if SA_RESTART is set) <0.080704>
--- SIGWINCH {si_signo=SIGWINCH, si_code=SI_KERNEL} ---
recvfrom(3, 0x7ffc489b16d0, 128, 0, 0, 0) = -1 ECONNRESET (Connection reset by peer) <113.777721>

这里是/etc/hosts的内容:

127.0.0.1 localhost

# The following lines are desirable for IPv6 capable hosts
::1 ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
ff02::3 ip6-allhosts
127.0.1.1 homestead homestead

/etc/resolve.conf的内容:

# Dynamic resolv.conf(5) file for glibc resolver(3) generated by resolvconf(8)
#     DO NOT EDIT THIS FILE BY HAND -- YOUR CHANGES WILL BE OVERWRITTEN
nameserver 10.0.2.3

这个问题现在影响到我拥有的每一个不相关的 vagrant box,而不仅仅是 Homestead box。对于每次 CLI 执行,几乎每个盒子上的每个 PHP 命令都会延迟 5-15 分钟。如果必须调用一系列命令,则可能需要一个小时才能完成本应需要 30 秒的过程。

这是在 Mac 这些盒子 运行 升级到 El Capitan 之后开始的。

根据 vagrant box,有时这条 strace 行:

connect(3, {sa_family=AF_INET, sin_port=htons(9000), sin_addr=inet_addr("127.0.0.1")}, 16) = 0

被替换为:

connect(3, {sa_family=AF_INET, sin_port=htons(9000), sin_addr=inet_addr("192.168.56.1")}, 16) = 0

IP 192.168.56.1 似乎是 VirtualBox 的默认路由器。

请注意,所有 vagrant boxes 要么是标准配置,要么是在我的其他团队成员的 Mac/Windows 系统上正常工作的配置。

Vagrant 1.7.4 和 VirtualBox 4.3.30。

响应请求route -n

Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
0.0.0.0         10.0.2.2        0.0.0.0         UG    0      0        0 eth0
10.0.2.0        0.0.0.0         255.255.255.0   U     0      0        0 eth0
192.168.10.0    0.0.0.0         255.255.255.0   U     0      0        0 eth1

sudo netstat -tulnp | grep 9000 的结果:

tcp6       0      0 :::9000                 :::*                    LISTEN      1317/hhvm

为什么会出现 hhvm,我不知道,因为盒子应该使用标准 PHP 解释器。

问题似乎与主机名解析有关。如果您尝试使用您的 ip 而不是 localhost ip 127.0.0.1。最好在 /etc/hosts 中使用,例如:

yourip  hostname.example.com hostname

例如

10.0.2.20 test.example.com test

并从 /etc/hosts 中删除相关的 localhost 或最后保留。系统将尝试获取第一个条目,如果您没有使用 ipv6,那么您也可以删除与 ipv6 相关的条目。

编辑: 您的 /etc/resolv.conf 文件应包含以下行

nameserver 127.0.0.1

还要添加 vagrant default 网络,因为您的输出显示它正在尝试连接该网络,但如果您不想使用,则可以跳过。你正在使用 127.0.0.1 所以至少它应该是 there.you 可以寻求帮助从 here and here.

改变

tl;dr:我怪 xdebug 客户端。尝试在 Ubuntu.

上禁用 xdebug

我的理由:

我在 strace 日志中没有看到任何主机解析问题。

它首先检查 /etc/resolv.conf,然后 /etc/hosts 并连接到 127.0.0.1:9000 connect(3, {sa_family=AF_INET, sin_port=htons(9000), sin_addr=inet_addr("127.0.0.1")}, 16) = -1 EINPROGRESS (Operation now in progress) <0.000094>

端口 9000 是 xdebug 的默认端口,除非在 /etc/php5/mods-available/xdebug.ini 或类似的地方重新定义。

write(3<socket:[78362]>, "478[=14=]<?xml version=\"1.0\" encoding"..., 483) = 483 <0.000042> 看起来像是从 xdebug 扩展程序发送到客户端的消息。

它等待 2 分钟 recvfrom(3, 0x7ffc489b16d0, 128, 0, 0, 0) = ? ERESTARTSYS,然后放弃并执行您的 php 脚本。

从 v2.2.4 开始,等待时间已减少到 200 毫秒:https://github.com/xdebug/xdebug/pull/90

假设禁用 xdebug 可以解决问题,有几个选项:

  • 升级 xdebug
  • 将 xdebug 配置为仅使用 xdebug.remote_autostart=off 按需启动
  • 保持 enabling/disabling xdebug
  • 保持 xdebug 客户端始终打开并确保端口映射正确并且它不会挂起

嗯,感觉像是 DNS 问题。我的猜测是您的机器无法通过给定的主机名解析 DNS,或者 DNS 服务器速度很慢。我的建议是在本地安装一个缓存 DNS 服务器,并使用它,然后将私有网络中的任何内容添加到 /etc/hosts 文件,DNS 不会提供这些内容。使用 NetworkManager 或您必须添加 127.0.0.1 作为可行(和首选)DNS 服务器的任何网络服务,事情应该会顺利进行。如果您使用的是 ubuntu,那应该和 sudo apt-get install bind9 一样简单。

如果你想诊断问题,首先安装 dnsutils,获取 dig 和 nslookup,然后尝试查询一些东西,比如 www.google.co.uk,看看需要多长时间以及哪个服务器是权威的。然后试试用dig,具体点,直接问server,直接问SOA,看能不能找出最薄弱的地方link。

这可能是路由器通过 DHCP 将自己宣传为 DNS 服务,但在按下时无法正常工作。