Бесконечные таймауты или «быстрый сбой» в пользовательском сетевом протоколе? - PullRequest
2 голосов
/ 28 ноября 2009

Рассмотрим пользовательский сетевой протокол. Этот пользовательский протокол может использоваться для управления периферийными устройствами роботов по локальной сети с центральной рабочей станции на базе .NET. (Если это важно, робот занят перемещением фабов в среде производства чипов).

  • В разговоре участвуют только 2 участника: станция .NET и периферийная роботизированная плата
  • сторона робота может только получать запросы и отправлять ответы
  • сторона .NET может только инициировать запросы и получать ответы
  • всегда должен быть ровно один ответ на запрос
  • последующие запросы могут следовать сразу один за другим, не ожидая ответа, но никогда не превышать фиксированный лимит одновременно обслуживаемых запросов (например, 5)

У меня была исчерпывающая дискуссия с моим другом (который владеет дизайном, я обсуждал это как наблюдатель) обо всех приятных деталях и идеях. В конце обсуждения у нас были серьезные разногласия по поводу пропущенных тайм-аутов. Аргумент моего друга заключается в том, что программное обеспечение с обеих сторон должно ждать бесконечно долго. Мой аргумент состоял в том, что тайм-ауты всегда нужны любому сетевому протоколу. Мы просто никогда не могли согласиться.

Одно из моих соображений состоит в том, что в случае любого сбоя вы должны «быстро провалиться» любой ценой, потому что, если сбой уже произошел, стоимость восстановления продолжает расти пропорционально времени, потраченному на получение информации о сбое. Скажем, через 1 минуту в локальной сети вам определенно следует перестать ждать и просто вызвать тревогу.

Но его аргумент состоял в том, что восстановление должно включать в себя именно восстановление того, что не удалось (в данном случае восстановление сетевого подключения), и даже если требуется несколько часов, чтобы выяснить, что сеть была потеряна и исправлена, программное обеспечение должно просто продолжать прозрачно сразу после подключения кабелей локальной сети.

Я бы никогда серьезно не задумывался о бесконечных протоколах, до этой дискуссии.

Какая сторона аргумента верна? «Быстро провал» или «никогда не провал»?

Редактировать: Пример сбоя - потеря связи, обычно обнаруживаемая уровнем TCP. Эта часть также обсуждалась. В случае ошибки возврата уровня TCP, более высокий уровень пользовательского протокола будет повторять посылку, и об этом нет аргументов. Вопрос в том, как долго продолжать пытаться нижний уровень?

Изменить для принятого ответа: Ответ более сложен, чем два варианта: « Наиболее распространенный подход - никогда не отказываться от соединения, пока не произойдет сбой фактической попытки отправки с твердым подтверждением того, что соединение давно потеряно. Чтобы рассчитать, что соединение долго потеряно, используйте тактовые импульсы, но сохраняйте возраст потеря только для этого подтверждения, а не для немедленной тревоги".

Пример. Во время сеанса telnet вы можете держать свой терминал вечно включенным и никогда не узнаете, были ли между нажатиями Enter ошибки, обнаруживаемые процедурами более низкого уровня.

Ответы [ 2 ]

1 голос
/ 28 ноября 2009

В сценарии, где ...

  • Контроллер отправил запрос
  • Робот не получил запрос
  • Сбой сети

... тогда запрос был отправлен, но был потерян и никогда не поступит.

Следовательно, когда сеть восстанавливается, контроллер должен повторно отправить запрос: контроллер не может просто ждать ответа вечно.

0 голосов
/ 28 ноября 2009

Я предпочитаю твой метод "быстрого отказа", но, как я думаю, ты обнаружил, это очень предпочтительный.

Оборудование Cisco, с которым я работаю, работает очень похоже - вы отправляете запрос, они отвечают. (Через telnet.) Проблема в том, что в сети происходит сбой: я теряю соединение TCP. Однако ни одна из сторон не закроет это соединение, пока не будет предпринята попытка отправки данных, и поскольку сторона cisco делает это редко, она никогда не закрывается. Хуже того, вы можете иметь только 1 соединение за раз, так что в случае сбоя в сети вы заблокированы. (Их можно сбросить, но это просто хлопот.)

Теперь, чтобы проверить сетевое соединение, вам нужен какой-то пинг, просто "вы все еще там?" - многие протоколы, такие как AIM и IRC, делают это. Но эти пинги стоят пропускной способности, в зависимости от того, как часто вы их отправляете.

Итак, стоит ли обнаружение ошибок в полосе пропускания? Насколько большим должен быть пинг? Я бы сказал, что вы должны быть в состоянии получить <50 октетов / пинг, и вы можете пинговать раз в 10, 30, 1 м, что-то в этом роде, я бы сказал, что оно того стоит. Чем раньше вы знаете, что у вас есть проблемы, тем лучше. Если само программное обеспечение может затем использовать эти эхо-запросы, чтобы узнать, что оно потеряло соединение, и автоматически восстановить контакт, я бы сказал, что это замечательно, по принципу «Компьютер, исцели себя» и создает меньше проблем для оператора. </p>

Если вы используете TCP / IP, он может сделать это автоматически для вас - см. TCP Keepalive. Кроме того, вы можете сделать это в протоколе вашего приложения, как это делают AIM и IRC.

...