Hi Nuts, net.LookupHost is taking a long time (up to 5 seconds) to resolve localhost, where I expect it to be instant. At other times it can take anywhere from 1-100ms, but it seems to reliably return a result shortly after 5 seconds.
The details: * I'm doing local development inside a docker container (alpine linux: `docker run alpine sh`). Outside of this environment I can't seem to easily get the problem to manifest, but I haven't tried hard. * The problem manifests as many things having an additional random amount of latency of order 100ms-5s. * Inside the container, various services are talking to each other through URLs which read `http://localhost:...` * Resolv.conf has `nameserver 8.8.8.8` which may or may not be unreachable at different times. If it is unreachable, then it takes 5 seconds to resolve localhost. * I'm on a slow mobile network, so I hit this frequently. * I experience 5 second timeouts even on fast networks where the resolver should be reachable, though this could perhaps be explained by an out-of-date resolv.conf inside the docker container. * Tweaking GODEBUG=netdns= to either go or cgo seems to fix the problem. * The presence or absense of an empty /etc/nsswitch.conf has no effect. * An empty resolv.conf still selects "dns,files" but then returns a result fast (in microseconds). My test program: func main() { start := time.Now() _, err := net.LookupHost("localhost") if err != nil { log.Fatal(err) } log.Printf("Took %v", time.Since(start)) } This seems to be the fundamental problem: # GODEBUG=netdns=2 ./tmp-1 go package net: dynamic selection of DNS resolver go package net: hostLookupOrder(localhost) = dns,files Took 351.143424ms Why is go choosing "dns,files"? If I choose either cgo or go as my resolver (see end of mail), it correctly chooses `files,dns` then everything goes quickly, taking microseconds rather than hundreds of milliseconds. On a Debian host, it seems to correctly select `files,dns`. Am I missing something? Also, in the interests of trimming latency, is there any reason the Go resolver shouldn't just directly return 127.0.0.1 as a hard-coded result for "localhost"? I understood it may be required by the RFC, but the strongest language I could find was in RFC2606: The ".localhost" TLD has traditionally been statically defined in host DNS implementations as having an A record pointing to the loop back IP address and is reserved for such use. Any other use would conflict with widely deployed code which assumes this use. Thanks, - Peter Selecting either resolver has the correct behaviour, compared with that shown above: # GODEBUG=netdns=go+2 ./tmp-1 go package net: GODEBUG setting forcing use of Go's resolver go package net: hostLookupOrder(localhost) = files,dns Took 376.164µs # GODEBUG=netdns=cgo+2 ./tmp-1 go package net: using cgo DNS resolver go package net: hostLookupOrder(localhost) = cgo Took 102.334µs -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.