Kilka miesięcy temu zauważyłem, że uruchomienie mojego edytora tekstu (emacs) i IDE (IntelliJ) zajęło naprawdę dużo czasu. Czas wydawał się różnić w zależności od serwerów DNS, z których korzystał OS X.
Byłem w stanie wyizolować problem, gdy pakiet testowy projektu działał powoli. Uważam, że winowajcą (wyższego poziomu) jest wezwanie do socket.getfqdn()
.
Uruchomienie następującego polecenia w terminalu w systemie OS X 10.10.2 pokazuje problem:
$ time python -c 'import socket; socket.getfqdn()'
python -c 'import socket; socket.getfqdn()' 0.02s user 0.00s system 0% cpu 5.122 total
Śledziłem kod, który działa, gdy socket.getfqdn()
jest wywoływany, a opóźnienie jest spowodowane przez getaddrinfo(3)
. Napisałem mały program, który izoluje problem i wyświetla gai_strerror(3)
ten komunikat:
$ time ./hostinfo
Hostname: MacBook-Pro.local
getaddrinfo: nodename nor servname provided, or not known
./hostinfo 0.00s user 0.00s system 0% cpu 5.101 total
Wygląda na to, że opóźnienie czeka na przekroczenie limitu czasu przez zapytanie DNS. Powyższe wyniki wykorzystywały publiczne serwery DNS Google. Jeśli jednak użyję serwerów DNS mojego usługodawcy internetowego, czas wydłuży się do 30 sekund:
$ time python -c 'import socket; socket.getfqdn()'
python -c 'import socket; socket.getfqdn()' 0.01s user 0.01s system 0% cpu 30.114 total
(co ciekawe, program C hostinfo
nadal zajmuje nieco ponad 5 sekund)
Co powoduje ten problem? Czy moja nazwa hosta jest nieprawidłowa lub powoduje problemy?
$ hostname
MacBook-Pro.local
Ten problem nie występuje na komputerze Macbook Air w tej samej sieci.
Główną różnicą, którą widzę, jest to, że na problematycznym komputerze znajduje się następująca konfiguracja DNS:
$ scutil --dns
DNS configuration
resolver #1
search domain[0] : Home
nameserver[0] : 8.8.8.8
nameserver[1] : 8.8.4.4
flags : Request A records
reach : Reachable
DNS configuration (for scoped queries)
resolver #1
search domain[0] : Home
nameserver[0] : 8.8.8.8
nameserver[1] : 8.8.4.4
if_index : 4 (en0)
flags : Scoped, Request A records
reach : Reachable
Na Macbooku Air znajduje się kilka dodatkowych wpisów dotyczących mDNS. Na przykład:
resolver #2
domain : local
options : mdns
timeout : 5
flags : Request A records
order : 300000
To wydaje się być znaczące. Co ciekawe, powyższy limit czasu jest mniej więcej taki sam, jak powyżej.
Powinienem zauważyć, że jestem podłączony do Internetu za pomocą Wi-Fi, a problem występuje tylko przy próbie rozwiązania nazwy hosta mojego komputera.
ping my_ISP_DNS_server
&ping Google_DNS_server
?