Проблема поддержки поддерживающих сокетов на домашнем http-сервере - PullRequest
11 голосов
/ 22 апреля 2011

В настоящее время я экспериментирую с созданием http-сервера. Сервер является многопоточным одним прослушивающим потоком с использованием select (...) и четырьмя рабочими потоками, управляемыми пулом потоков. В настоящее время я обрабатываю около 14k-16k запросов в секунду с длиной документа 70 байтов, время отклика 6-10 мс на Core I3 330M. Но это без поддержки, и все розетки, которые я обслуживаю, я немедленно закрываю, когда работа закончена.

РЕДАКТИРОВАТЬ : рабочие потоки обрабатывают «задания», которые были отправлены при обнаружении активности в сокете, т.е. запросы на обслуживание. После завершения «задания», если «заданий» больше нет, мы спим до тех пор, пока не будет отправлено больше «заданий» или если уже есть какие-то доступные, мы приступаем к обработке одного из них.

Мои проблемы начались, когда я начал пытаться реализовать поддержку keep-alive. С активированной поддержкой активности я управляю только запросами 1.5k-2.2k в секунду при 100 открытых сокетах. Это число увеличивается примерно до 12 тысяч с 1000 открытых розеток. В обоих случаях время отклика составляет около 60-90 мс. Я чувствую, что это довольно странно, поскольку мои текущие предположения говорят о том, что запросы должны увеличиваться, а не уменьшаться, а время отклика должно уменьшаться, но определенно не увеличиваться.

Я пробовал несколько разных стратегий для исправления низкой производительности:

Сокеты keep-alive хранятся в простом связанном списке List, методы добавления / удаления которого заключены в блокировку pthread_mutex, и функция, отвечающая за восстановление FD_SET, также имеет эту блокировку.

Я подозреваю, что основным виновником здесь является постоянная блокировка / разблокировка мьютекса, я пытался профилировать проблему, но ни gprof, ни google-perftools не очень помогали друг другу, либо создавали крайнюю нестабильность, либо просто отказывались собирать любые данные по всем (это может быть я не знаю, как правильно использовать инструменты.). Но снятие блокировок может привести к тому, что связанный список окажется в ненормальном состоянии и, возможно, вылетит или запустит программу в бесконечный цикл. Я также подозревал время ожидания select (...) / pselect (...), когда использовал его, но я вполне уверен, что это не было проблемой, поскольку низкая производительность поддерживается даже без нее.

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

  • Если вам нужна дополнительная информация, чтобы правильно ответить на мой вопрос, не стесняйтесь спрашивать ее, и я сделаю все возможное, чтобы предоставить вам необходимую информацию и обновить вопрос этой новой информацией.

Ответы [ 5 ]

6 голосов
/ 22 апреля 2011

Попробуйте полностью избавиться от выбора.Вы можете найти какое-то уведомление о событии на любой популярной платформе: kqueue / kevent в freebsd (), epoll в Linux и т. Д. Таким образом, вам не нужно перестраивать FD_SET и вы можете добавлять / удалять просматриваемые fds в любое время.

0 голосов
/ 03 мая 2011

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

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

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

http://www.techrepublic.com/article/using-the-select-and-poll-methods/1044098

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

0 голосов
/ 03 мая 2011

То, что вы пытаетесь сделать, было сделано раньше. Вы можете прочитать о шаблоне сетевого сервера Leader-Follower, http://www.kircher -schwanninger.de / michael / publishing / lf.pdf

0 голосов
/ 03 мая 2011

Ваши тестовые клиенты повторно используют сокеты? Правильно ли они справляются, чтобы поддерживать жизнь? Я мог видеть тот случай, когда вы вносите минимальное возможное изменение в свой код тестирования, просто передавая заголовок keep alive, но затем не меняя свой код, чтобы сокет закрывался на стороне клиента после получения платного пакета. Это повлечет за собой все расходы по поддержанию жизни без каких-либо преимуществ.

0 голосов
/ 27 апреля 2011

Есть много альтернатив:

  • Использование процессов вместо потоков и передача файловых дескрипторов через сокеты Unix.
  • Ведение списков сокетов для каждого потока. Вы можете даже accept() непосредственно в рабочих потоках.
  • и т.д ...
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...