2014-10-01 7 views
0

Я понимаю, что я получу хотя бы один ответ в строке «(re), чтобы написать код, чтобы он не зависал», но предположим, что мы не живем в этом блестящая счастливая утопия еще ...Программно определить, висел ли локальный веб-сервер

В нашей встроенной системе у нас есть большой SDK, включая веб-сервер (Boa), который является основным методом взаимодействия с пользователем.

Возможно, что на некоторых этапах Луны что-то может привести к зависанию веб-сервера или его застреванию, чтобы процесс работал нормально (не разбился/был мертв/с использованием 100% CPU) но не обслуживает веб-страницы.

Итак, вопрос в том, как мы тестируем/обнаруживаем эту ситуацию?

+2

Отправить небольшой, четко определенный запрос к нему и проверить, что вы получите ожидаемый ответ в течение заданного срока? – isedev

+0

Ну, да, я догадываюсь, что широкие штрихи будут такого порядка, то, что мне нужно, - это метод * отправки HTTP-запроса или похожа на веб-сервер с минимальным размером. –

+0

Простым решением будет сценарий оболочки, выполняющий 'wget -q -O/dev/null TESTURL' и проверяющий код состояния, возвращаемый' wget'. – isedev

ответ

2

Чтобы проверить, висел ли сервер, создайте сокет TCP и подключитесь к порту 80 по IP-адресу 127.0.0.1 (адрес обратной связи). Затем отправить следующий текст над гнездом

GET/HTTP/1.1\r\n\r\n 

Большинство серверов будет интерпретировать это как запрос на index.html. В качестве альтернативы вы можете реализовать недокументированный URL для тестирования (что позволяет получить более короткий, предопределенный ответ), например.

GET /test/fdoaoqfaf12491r2h1rfda HTTP/1.1\r\n\r\n 

Затем вам необходимо прочитать ответ с сервера. Это включает в себя использование select с разумным таймаутом, чтобы определить, вернулись ли какие-либо данные с сервера, и если да, используйте recv для чтения данных. Ответ с сервера будет состоять из заголовка, за которым следует содержимое. Заголовок состоит из строк текста с пустой строкой в ​​конце заголовка. Линии заканчиваются на \r\n, поэтому конец заголовка \r\n\r\n.

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


Это все очень хорошо, но вам действительно нужно перепишите свой код, чтобы он не зависал.

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

Первое, что нужно проверить, это значение тайм-аута TCP. Один проект, над которым я работал, имел тайм-аут по умолчанию 5 часов, а это означало, что болтающиеся сокеты оставались открытыми в течение 5 часов. Разумный тайм-аут составляет 1 минуту.

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

  • оставляя гнездо открытым без чтения ответа сервера
  • резко закрывает сокет при чтении ответа
  • изящно закрывает сокет при чтении ответа

первая ситуация должна решаться таймаутом TCP. Остальные два должны быть надлежащим образом обработаны кодом сервера. Изящное и крутое закрытие гнезда контролируется с помощью опции SO_LINGER ioctl и функции shutdown. После того, как клиент ошибся, check the number of open file descriptors в серверном процессе, убедитесь, что сервер правильно обработал ситуацию.

+0

Хороший ответ. Ref the 2nd half: Это не мой код, это Boa, который был взломан Elbonian Code Slaves как часть массивного волосатого и недокументированного SDK, зависания вызваны неудачными вызовами в другие части SDK, мы постепенно бритьем и избиение его в подчинение, но искоренение * всех * отвратительных может занять человеко-годы, поэтому смягчение последствий является нашим лучшим вариантом в качестве прилипающей штукатурки. –

+0

Я слышу тебя, и у тебя есть мои соболезнования. Удивительно, как плохо какой-то открытый исходный код, учитывая его очевидное широкое распространение. В какой-то момент вам нужно решить, лучше ли начинать с нуля, а не тратить человеко-годы, распутывая чужой шар спагетти. В моем случае я заработал код стороннего сервера и сделал свой собственный. – user3386109

+0

Хуже того, это коммерческий SDK от Texas Instruments, хотя они стараются дистанцироваться от стороннего эльфийского наряда, который произвел много от их имени. –