SkillGridИзучай computer science на практике

Отладка вместо угадывания

Метод вместо наития: идти по слоям в фиксированном порядке, начинать с самой дешёвой проверки, изолировать по одному подозреваемому и точно знать, что доказывает каждый инструмент.

17 мин · 55 XP

Отладка сети не в том, чтобы знать больше команд. Она в том, чтобы заменить догадки последовательностью вопросов, ответы на которые нельзя оспорить. В методе три правила. Начинайте с проверки, самой дешёвой по времени и отсекающей больше всего. Меняйте ровно одну вещь за раз. И после каждой проверки спрашивайте, что её результат доказывает, а что нет: проверка, которая могла пройти по двум разным причинам, не сказала вам ничего.

Самое дешёвое сначала означает: прежде чем трогать конфигурацию, спросите, работает ли это вообще отсюда и работает ли оно из другого места. Сравнение двух точек наблюдения стоит одной команды и делит пространство проблем пополам. Попросить пользователя попробовать другую сеть или выполнить тот же запрос с другой машины обычно полезнее, чем час чтения логов.

Лесенка вопросов снизу вверх: есть ли у машины вообще адрес и маршрут по умолчанию? Превращается ли имя в адрес? Отвечает ли адрес на уровне IP? Открыт ли порт и отвечает ли на нём служба? Возвращает ли приложение правильный ответ? На каждый вопрос отвечает свой инструмент, и каждый ответ сужает круг подозреваемых, пока не останется один слой. Смысл лесенки в том, что она заканчивается: хорошая отладка уменьшает множество возможных причин, а не увеличивает его.

ClientResolverRouterServerdig api.example.org93.184.216.34, TTL 300ping 192.168.1.1reply 1.2 msping 93.184.216.34reply 104 msTCP SYN to port 443SYN-ACKTLS ClientHelloTLS alert: handshake failureDNS and routing are fine, the failure is inside TLS

Каждый инструмент доказывает что-то узкое, и использовать его для большего — верный способ прийти к неверному выводу. ping доказывает, что хост отвечает на ICMP и что путь существует в обе стороны; он не доказывает, что веб-сервер запущен. dig доказывает, что ответил резолвер и насколько ответ закэширован; он не доказывает, что адрес достижим. curl доказывает, что весь стек делает для одного конкретного запроса; он не доказывает, что другие клиенты получат тот же ответ. ss доказывает, что именно слушает на этой машине и на каком адресе; он не доказывает, что межсетевой экран кого-то впускает.

$ dig api.example.org +short
198.51.100.20

$ dig api.example.org +short
198.51.100.20

$ dig api.example.org @1.1.1.1 +short
203.0.113.7

$ dig api.example.org @8.8.8.8 +short
203.0.113.7Два резолвера, два разных ответа: это кэш и устаревшая запись, а не сломанная сеть.
$ curl -v https://api.example.org/health
*   Trying 198.51.100.20:443...
* connect to 198.51.100.20 port 443 failed: Connection timed out
* Failed to connect to api.example.org port 443: Connection timed out

$ curl -sv https://api.example.org/health -o /dev/null
*   Trying 93.184.216.34:443...
* Connected to api.example.org (93.184.216.34) port 443
* Server certificate: CN=*.example.org
< HTTP/2 200
< content-type: application/jsonОдна и та же команда с таймаутом на порт и с адресом, который действительно работает.

На ss стоит посмотреть отдельно: он разделяет два отказа, которые снаружи выглядят одинаково — никто не слушает порт, или кто-то слушает, но только на петлевом адресе. Сервер, привязанный к 127.0.0.1, принимает соединения с той же машины и отказывает всем снаружи, что бы ни говорил межсетевой экран. Это одно различие объясняет большую долю случаев, когда служба работает локально и недоступна отовсюду ещё.

$ ss -tlnp
State   Local Address:Port   Process
LISTEN  127.0.0.1:8080       users:(("node",pid=4127,fd=21))
LISTEN  0.0.0.0:22           users:(("sshd",pid=880,fd=3))

$ curl -s -o /dev/null -w "%{http_code}\n" http://127.0.0.1:8080/
200Одна служба доступна из сети, вторая только с этой машины.

Практика

  1. Постройте лесенку изоляции: расставьте проверки для сайта, который не открывается, от первой доступной до последней.

    Нажми узел-источник, затем тот, на который он указывает. Повторный клик по паре удаляет связь.

    Подсказки
    • Каждый шаг спрашивает свой слой, поэтому расставьте их от самого простого вопроса к самому конкретному.
    • Имя должно стать адресом прежде, чем появится что-то достижимое, а порт можно проверить только когда адрес отвечает.
    • Ответ приложения — последнее, что вообще можно наблюдать, поэтому он стоит в конце цепочки.
  2. Коллега говорит, что API лежит. На его машине dig возвращает 198.51.100.20, а curl на порт 443 отваливается по таймауту. На вашей машине тот же dig возвращает 203.0.113.7, а curl отвечает 200. Какое объяснение наиболее вероятно?

    Подсказки
    • Его ping по имени уже доказывает две разные вещи: имя разобралось и пакеты ходят.
    • Сравните два ответа dig: один пришёл от локального резолвера, второй от публичного.
    • Спросите, чем отличаются две машины, а не что не так с сервером.
  3. Расставьте первые четыре шага расследования страницы, которая медленно грузится у части пользователей в одном городе.

    1. 1запустить curl -v и увидеть полученный адрес и какая фаза медленная
    2. 2повторить из второй точки, чтобы отличить расстояние от локальной проблемы
    3. 3повторить тот же запрос на тёплом соединении, чтобы отделить рукопожатие от передачи
    4. 4воспроизвести медленность из пострадавшего места и записать времена
    Подсказки
    • Начните с вопроса, который ничего не стоит и при провале отсекает целый слой.
    • curl -v называет хост, полученный адрес и порт, в этом самом порядке.
    • Повторите один и тот же запрос дважды из пострадавшего места и сравните два времени, прежде чем винить что-то ещё.

Вопросы по этому уроку

Зачем вообще учить сети?

Почти всё, что ты делаешь, в итоге с чем-то общается. Понимание того, как данные реально ходят, превращает «не работает» из загадки в список того, что можно проверить по очереди.

В чём реальная разница между TCP и UDP?

TCP следит, чтобы всё дошло и по порядку, и повторяет потерянное — за это платит временем. UDP отправляет и не оглядывается, поэтому видеозвонки и игры предпочитают его: опоздавший кадр хуже пропавшего.

Что такое DNS простыми словами?

Это телефонная книга интернета. Ты знаешь имя, а компьютеру нужен номер. DNS превращает имя вроде example.org в IP-адрес и запоминает ответ, чтобы не спрашивать каждый раз.

Это бесплатно?

Да. Первый уровень каждого предмета бесплатный и не требует аккаунта. Дальше уровни и старшие грейды платные — именно это позволяет проекту существовать.

На какой возраст рассчитано?

Для любознательных подростков примерно с 12 лет и для взрослых, начинающих с нуля. Опыт программирования не предполагается: уроки по сетям и физике не требуют математики сверх школьной.

Нужно ли уже уметь программировать?

Нет. Логика, физика и сети начинаются с нуля. Код ты пишешь в разделе языков — и он тоже начинается с самого начала.

Нужно что-то устанавливать?

Нет. Всё работает в браузере: теория, практика и интерактивные симуляции. Скачивать нечего и настраивать нечего.

Сколько времени занимает один предмет?

Урок — от 10 до 15 минут. Грейд «джун» это примерно 12–20 уроков, то есть несколько недель регулярных занятий, а не один вечер.

Обязательно идти по порядку?

Внутри грейда уровни открываются по очереди: каждый опирается на предыдущий. А между предметами ты свободен — начинай с логики, физики или сетей.