2010-03-29 3 views
1

Nginx использует epoll или другие методы мультиплексирования (выбирает) для обработки нескольких клиентов, то есть он не порождает новый поток для каждого запроса, в отличие от apache., обслуживающий большой файл с использованием select, epoll или kqueue

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

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

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

ответ

4

простейшего подход для создания потока для каждого запроса, но это, конечно, не самый масштабируемого подхода. Я думаю, что в это время в основном все высокопроизводительные веб-серверы используют различные асинхронные подходы, основанные на таких вещах, как epoll (Linux), kqueue (BSD) или IOCP (Windows).

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

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

5

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

0

Я думаю, что вы используете свой обратный вызов для обработки одного соединения. Это не то, как он был разработан. Ваш обратный вызов должен обрабатывать любую тысячу подключений, которые вы планируете обслуживать, то есть из числа дескрипторов файлов, которые вы получаете как параметр, вы должны знать (читая глобальные переменные), что делать с этим клиентом, либо читать () или отправить() или ... независимо от того,

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

  • Нет связанных вопросов^_^