Поделиться через


Предотвращение зависаний на стороне клиента

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

Существует два способа предотвратить это: сохранить жизнь и тайм-ауты.

TCP Keep Alives

Клиент можно настроить для периодической проверки связи с сервером, чтобы убедиться, что сервер работает и работает. Проверки связи — это проверки активности TCP для последовательностей протоколов ncacn_ip_tcp и ncacn_http , поэтому они эффективны в использовании ЦП и пропускной способности сети. Чтобы включить функцию поддержания активности при данном удаленном вызове процедуры, используйте функцию RpcMgmtSetComTimeout перед началом вызова. Эта функция принимает дескриптор привязки и время ожидания в качестве аргументов. Каждый удаленный вызов процедуры для этого дескриптора привязки после RpcMgmtSetComTimeout использует указанное время ожидания.

Параметр Timeout для функции RpcMgmtSetComTimeout указывает, сколько времени выполнения RPC ожидает, прежде чем оно включит функцию поддержания активности. Время ожидания — это значение от 0 до 10, где 0 — минимальное время ожидания, а 10 — бесконечное время ожидания (без времени ожидания). Сам тайм-аут не в секундах; Преобразование значения времени ожидания, предоставленного функции RpcMgmtSetComTimeout , в секунды выполняется во время выполнения RPC и зависит от реализации.

В следующей таблице представлен перевод в секунды для Windows 2000 и Windows XP. В будущих версиях Windows может измениться сопоставление между параметром Timeout и значением времени ожидания в секундах:

Параметр timeout Фактическое время ожидания в секундах
0 (RPC_C_BINDING_MIN_TIMEOUT) 120
1 240
2 360
3 480
4 600
5 (RPC_C_BINDING_DEFAULT_TIMEOUT) 720
6 840
7 960
8 1080
9 (RPC_C_BINDING_MAX_TIMEOUT) 1200
10 (RPC_C_BINDING_INFINITE_TIMEOUT) Бесконечное время ожидания

 

После включения поддержки активности клиент отправляет один пакет keep alive каждую секунду. Если на сервере нет подтверждения для трех или более значений активности, клиент объявляет подключение неработоным и завершается сбоем удаленного вызова процедуры. Если сервер отправляет ответ в течение указанного времени ожидания, функция поддержания активности не будет включена. Если сервер отвечает на сохранение активности, но не отвечает на удаленный вызов процедуры, клиент продолжает отправлять данные keep alive. После того как сервер ответит на вызов RPC, функция поддержания активности отключается. В Windows 2000 функция поддержания активности включена только для синхронных вызовов RPC. В Windows XP функция поддержания активности также включена для асинхронных вызовов RPC.

Заманчиво задать для keep alives наименьшее значение, чтобы клиентское приложение своевременно реагировал на проблемы с сетью. Следует тщательно рассмотреть такое искушение и тщательно проверить, оправдана ли агрессивная ценность. Сервер, который временно теряет возможность подключения, может оказаться затопленным множеством клиентов после восстановления подключения. Кроме того, длительные вычислительные задачи могут занять более двух минут, а сервер может тратить больше времени ЦП на ответы на поддержание активности, чем выполнение полезной работы. Таким образом, держать живых следует использовать с умеренности. Если клиент не допускает длительной привязки потока, следует рассмотреть асинхронный RPC.

Другие последовательности протоколов могут реализовывать различные механизмы обнаружения серверов, не отвечающих на запросы, в зависимости от используемого транспорта. Транспорт ncalrpc не использует функцию поддержания активности. Так как все обмен данными в ncalrpc являются локальными, если сервер перестает отвечать на запросы во время выполнения вызова, время выполнения RPC на клиенте немедленно завершает вызов.

Время ожидания звонка

При потере сетевого подключения или при аварийном сбое сервера можно обеспечить работоспособность TCP. Но если сервер заблокирует в пользовательском режиме, tcp-сервер сохраняет работоспособность, возвращается успешно, но вызов никогда не вернет. Для работы с этим сценарием был добавлен новый параметр времени выполнения для Windows XP: RPC_C_OPT_CALL_TIMEOUT. Этот параметр указывает времени выполнения RPC настраивать таймер при каждой отправке запроса на сервер. Если срок действия таймера истекает, вызов автоматически отменяется и завершается RPC_S_CALL_CANCELLED. Пока сервер ответит в течение указанного ограничения времени, клиент не отменит вызов. Это означает, что для выполнения многофакторного вызова может потребоваться больше времени ожидания, так как каждый ответ от сервера получается в течение периода ожидания, даже если период времени для получения всех ответов был больше времени ожидания.

Кроме того, при отмене вызова сервер не получает уведомление об отмене. Таким образом, сервер, скорее всего, выполнит вызов в какой-то момент, а клиент просто проигнорирует ответ от сервера.

Самая опасная ошибка с тайм-аутами звонков — это создание короткого тайм-аута и повторная попытка вызова на том же сервере. В следующем сценарии иллюстрируются опасности этого подхода.

Представьте себе сервер, который работает близко к емкости. Он имеет несколько клиентов с очень коротким тайм-аутом, например пять секунд. Временная потеря сетевого подключения или перегрузка на маршрутизаторе приводит к задержке ответов сервера в течение нескольких секунд. В сетях Ethernet такая ситуация может быть легко вызвана всплеском активности по каналу, который сервер использует совместно с другим компьютером. Серверу не удается отправить все ответы до истечения пятисекундного тайм-аута. Клиенты отменяют свои звонки и немедленно повторяют попытку. Сервер не знает, что вызовы являются повторными попытками, и выполняет их. Таким образом, вместо выполнения обычной рабочей нагрузки вызовов она выполняет на 30–50 % больше вызовов в зависимости от того, сколько клиентов истекло. Если это превышает свою емкость и сервер не может ответить всем клиентам в течение пяти секунд, на сервер отправляется еще один раунд вызовов. Клиенты продолжают повторно отправлять одни и те же вызовы, и так как сервер перегружен обработкой предыдущих вызовов, он не может ответить в течение времени ожидания. После ответа клиенты истекли время ожидания, выполнили новый вызов и отклонили ответ. В худшем случае сервер не будет восстановлен до перезагрузки и, в зависимости от шаблона клиентского доступа, может не восстановиться, пока не будет остановлено достаточное количество клиентов.

Примечание

Тайм-ауты звонков работают только для последовательностей ncacn_ip_tcp и ncacn_http протоколов.