2015-07-12 3 views
0

У меня есть программа-слушатель на сервере Linux с высокоскоростным интернет-соединением высокой пропускной способности, которое принимает и вставляет в базу данных SQL данные, загруженные с удаленных станций мониторинга через GPRS/GSM.Настройка параметров TCP для каждого соединения

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

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

Есть ли способ настроить сетевой стек на Linux, чтобы соединения с высокой и низкой задержкой работали одинаково хорошо?

ответ

0

В общем случае вы не можете завершить транзакцию на подключении tcp, которое может выйти из строя. Единственный способ реализовать такой протокол в подключении tcp - добавить простую команду в commit (подтвержденная команда) и поместить ее в конце каждой такой команды (они могут быть буферизованы группами по tcp). Команда должна быть двумя командами рукопожатия (commit -> ack), и вы должны зафиксировать всю транзакцию при получении command и откат, если время ожидания до получения сообщения commit. Мобильное устройство должно принимать во внимание сообщение, получающее сообщение ack (ну, вам не нужно указывать транзакции, поскольку TCP обеспечивает порядок прибытия и последовательность пакетов), и подумайте о совершении всех транзакций, за которые он получил сообщение ack. Учтите, что tcp выполняет тайм-аут и переадресацию, поэтому вам нужно использовать только одну отправку на сообщение и никогда не отправлять повторно отправленное сообщение. Если вы тайм-аут, просто снимите соединение и снова его откройте, учитывая, что последняя транзакция прервана.

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

Это все необходимо, чтобы быть правым в обоих местах (сервер и клиент) и не пытайтесь что-то сэкономить или потеряете данные.

Последнее замечание: у вас нет чего-то вроде тайм-аута для подключения tcp, вы должны реализовать его в своем протоколе внутри протокола. Соединение tcp может находиться в состоянии READY в течение недель или даже лет без обмена одним пакетом только потому, что обеим сторонам нечего сказать друг другу. Для этого есть опция KEEP_ALIVE, но вы можете ее активировать, у вас нет возможности исправить задержку таймаута, чтобы она не срабатывала.

Хорошим примером всех этих протоколов для обнаружения сбоев является протокол X. Это протокол, основанный на транзакции, где есть команды, выданные клиентом (есть как стили, команды с ответом, так и команды, которые не запрашивают такой ответ), а также асинхронные события (сигналы, поступающие с сервера на клиент без подтверждения приема или команда с просьбой)

в этом протоколе, у вас есть так называемая SYNC команды/сервис, который позволяет клиенту получить в синхронизации с сервером (вы его используете, когда вы хотите, чтобы заверить сервер обрабатывал все команды до сих пор).Кроме того, сервер всегда посылает ответы/события с неявным запросом id (приращения для каждой клиентской команды) последнего запрошенного клиента , поэтому это позволяет сэкономить много команд SYNC (и задержек на оба конца) клиенту.

0

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

Во-вторых, я не думаю, что настройка сервера даже помогла бы, если бы клиенты выбрали тайм-аут (что я предполагаю, это так, поскольку это было непонятно). Предположим, вы настроили сервер; вы увеличиваете значения таймаута и добавляете частые keepalives. Какая польза от этого, если клиенты ожидают ответа от сервера в течение определенного периода времени? Это ограничение, наложенное клиентом на уровне приложения (если только время соединения TCP не истекает, что маловероятно, поскольку они по умолчанию довольно надежны и долговечны).

Смежные вопросы