Comments 9
Действительно крутая статья. Вот так пользуешься Go и не замечаешь, что он может втихаря делать мелкий подлости)
Вся эта "мелкая подлость" так или иначе идёт не от языка, а от платформы (по крайней мере, в последней версии).
Если в конфиге написано "hosts: dns files" — это значит что программа обязана резолвить localhost сначала через dns. Если там написано "options ndots:5" — это тоже не просто так сделано...
да просто это лишний раз говорит о том, что бывают люди которые никогда не станут даже чуть чуть devops, живут в своём мире и ничего не понимают (и не хотят) во внешним мире и окружении приложения. Поэтому и бесит вся эта devops-изация т.к. новых дураков-программистов становится ещё больше.
если нужно чтобы резолвилось финальное имя - достаточно использовать полную нотацию из спецификации (с точкой на конце). Т.е. "golang.org." будет отрезолвлено именно в golang.org. даже если там ndots=100500.
тоже самое касается localhost, хотя если какой-то дуралей забыл кривой search в resolv.conf, я бы не расчитывал на адекватную работу приложений в таком окружении =).
можно еще добавить кэширование днс запросов на какое-то время, как это сделано в fasthttp:
https://habr.com/ru/post/443378/
ndots действительно сэкономит время ожидания ответа, поскольку проверка разных search domain делается последовательно. Но какой смысл писать дополнительный код для блокирования запроса IPv6? Этот запрос явно отправляется параллельно с запросом IPv4, и не факт что Go ждёт ответов на оба запроса (а даже если и так, то отвечать на них обычно будет один и тот же DNS-сервер и придут ответы одновременно - и хотя тут, конечно, можно представить ситуацию, когда один из ответов есть в локальном кеше а второго нет, но никто не же знает который из них будет в кеше, так что этот кейс можно игнорировать). В общем, смысл данной оптимизации неясен.
Параллельно или нет, зависит от наличия опции single-request, но я в работе не встречал, чтобы кто-то ставил эту опцию. Если мы говорим про Go-резолвер, то он запускает параллельные запросы(если нет single-request), и дожидается ответа для A и AAAA запросов, но делает это всё для каждого из search domain в цикле последовательно.
Если мы говорим про Kubernetes, то тут зависит от топологии в кластере. По дефолту два запроса пошлются в один ip-адрес DNS-сервера, который является service ip. Но через правила dnat (iptables/ipvs) будут отправляться в разные реальные DNS-серверы по round robin, если конечно реальный сервер не один.
Лучше не делать запрос, если он не нужен. Для кубернетеса ещё придумали ставить на каждую машину локально DNS-сервер, чтобы udp трафик не летал между нодами и отдавался локально с машины из кэша.
правильно тут было бы нормально настроенное окружение
не поднимать ipv6 адрес вообще, если он не используется в системе
для выбора кто главнее (v4 vs v6) - gai.conf. Вы не контроллируете сеть изнутри приложения, поэтому если абстрагироваться от прямых IP адресов, то резолвить надо так как в окружении настроено и никак иначе.
Крутая статья, спасибо!
Как в восемь раз уменьшить количество DNS-запросов в Go