Бесконечные таймауты или «быстрый сбой» в специальном сетевом протоколе?

StackOverflow https://stackoverflow.com/questions/1811366

Вопрос

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

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

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

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

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

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

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

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

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

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

Это было полезно?

Решение

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

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

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

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

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

Другие советы

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

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

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

Поэтому при восстановлении сети контроллер должен повторно отправить запрос:Контроллер не может просто вечно ждать ответа.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top