Как минимизировать количество потоков, используемых в приложении сервера tcp? - PullRequest
4 голосов
/ 28 августа 2008

Я ищу любые стратегии, которые люди используют при реализации серверных приложений, обслуживающих клиентские запросы TCP (или UDP): шаблоны проектирования, методы реализации, лучшие практики и т. Д.

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

Моя платформа - .NET, но поскольку базовая технология одинакова, независимо от платформы, мне интересно посмотреть ответы на любом языке.

Ответы [ 4 ]

6 голосов
/ 28 августа 2008

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

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

Таким образом, вам нужен только поток для каждой параллельной операции. Розетки, которые открыты, но простаивают, не будут связывать нить.

4 голосов
/ 28 августа 2008

Более подходящим подходом было бы использование портов завершения ввода-вывода. (Windows) С портами IO Completion вы оставляете операционную систему для управления опросом, что позволяет ей потенциально использовать очень высокий уровень оптимизации с поддержкой драйверов NIC. По сути, у вас есть очередь сетевых операций, которая управляется ОС, и вы предоставляете функцию обратного вызова, которая вызывается по завершении операции. Немного похоже на (жесткий диск) DMA, но для сети.

Лен Холгейт написал замечательную серию о портах завершения ввода-вывода несколько лет назад на Codeproject: http://www.codeproject.com/KB/IP/jbsocketserver2.aspx

И Я нашел статью о портах завершения ввода-вывода для .net (хотя еще не читал) http://www.codeproject.com/KB/cs/managediocp.aspx

Я бы также сказал, что использовать порты завершения проще по сравнению с попыткой написать масштабируемую альтернативу. Проблема в том, что они доступны только на NT (2000, XP, Vista)

2 голосов
/ 17 сентября 2008

Если бы вы использовали C ++ и Win32 напрямую, я бы посоветовал вам прочитать о перекрывающихся портах ввода / вывода и завершения ввода / вывода. У меня есть бесплатный C ++, IOCP, клиент / серверный фреймворк с полным исходным кодом, см. здесь для получения более подробной информации.

Поскольку вы используете .Net, вам следует обратить внимание на использование асинхронных методов сокетов, чтобы вам не требовался поток для каждого соединения; Есть несколько ссылок из этой публикации в моем блоге, которые могут быть полезными отправными точками: http://www.lenholgate.com/blog/2005/07/disappointing-net-sockets-article-in-msdn-magazine-this-month.html (некоторые из лучших ссылок есть в комментариях к исходной публикации!)

0 голосов
/ 28 августа 2008

G'day,

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

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

Или пул потоков, в котором один и тот же поток всегда прослушивает входящие запросы и затем передает запросы следующему доступному потоку в пуле потоков.

Вы можете посетить раздел Reactor Компонентов Ace, чтобы получить некоторые идеи.

НТН.

ура, Rob

...