Сколько сокетов может обрабатывать веб-сервер?

Скажем, если бы я получил общий, виртуальный или выделенный хостинг, я где-то читал, что сервер / машина может обрабатывать только 64000 TCP-соединений одновременно, это правда? Сколько может обрабатывать любой тип хостинга независимо от пропускной способности? Я предполагаю, что HTTP работает через TCP.

Означает ли это, что только 64 000 пользователей смогут подключиться к веб-сайту, и если бы я хотел обслуживать больше, мне пришлось бы перейти на веб-ферму?


person David    schedule 15.10.2009    source источник
comment
Извинения респондентам, я разорвал эту нить, как смерч. Просто на мой вкус было слишком много неправильных ответов, а прямого ответа все равно не было. Я много использую stackoverflow и нахожу много качественных ответов. Я надеюсь, что другие смогут найти эту ветку и найти полезный информированный ответ.   -  person Todd    schedule 28.05.2015
comment
Привет, Дэвид, ты нашел правильный ответ на этот вопрос?   -  person Dish    schedule 10.02.2016
comment
64000 TCP-соединений через один IP-адрес сервера. Вы можете модернизировать свою серверную сеть для масштабирования и поддержки более 64000.   -  person Airy    schedule 05.05.2020


Ответы (8)


Вкратце: вы сможете достичь порядка миллионов одновременных активных TCP-соединений и HTTP-запросов по расширению. Это говорит о максимальной производительности, которую вы можете ожидать от правильной платформы с правильной конфигурацией.

Сегодня меня беспокоило, будет ли IIS с ASP.NET поддерживать порядка 100 одновременных подключений (посмотрите мое обновление, ожидайте ~ 10 тыс. Ответов в секунду в более старых версиях ASP.Net Mono). Когда я увидел этот вопрос / ответы, я не смог удержаться от ответа сам, многие ответы на вопрос здесь совершенно неверны.

В лучшем случае

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

Итак, рассмотрим следующий сценарий моего ответа:

  1. Нет трафика в сеансах TCP, за исключением пакетов keep-alive (в противном случае вам, очевидно, потребуется соответствующая пропускная способность сети и другие ресурсы компьютера)
  2. Программное обеспечение, предназначенное для использования асинхронных сокетов и программирования, а не аппаратного потока на запрос из пула. (т.е. IIS, Node.js, Nginx ... веб-сервер [но не Apache] с прикладным программным обеспечением, разработанным для асинхронного программирования)
  3. Хорошая производительность / доллар CPU / Ram. Сегодня произвольно скажем i7 (4 ядра) с 8 ГБ ОЗУ.
  4. Хороший межсетевой экран / роутер под стать.
  5. Нет виртуального лимита / регулятора - т.е. Linux somaxconn, IIS web.config ...
  6. Нет зависимости от другого более медленного оборудования - нет чтения с жесткого диска, потому что это будет наименьший общий знаменатель и узкое место, а не сетевой ввод-вывод.

Подробный ответ

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

WhatsApp может обрабатывать миллион С трафиком на одной машине с ОС Unix - https://web.archive.org/web/20120108184257/https://blog.whatsapp.com/index.php/2012/01/1-миллион-is-so-2011/.

И, наконец, этот, http://highscalability.com/blog/2013/5/13/the-secret-to-10-million-concurrent-connections-the-kernel-i.html, переходит в много деталей, исследуя, как можно достичь даже 10 миллионов. Серверы часто имеют аппаратные механизмы разгрузки TCP, ASIC, предназначенные для этой конкретной роли более эффективно, чем ЦП общего назначения.

Хороший выбор дизайна программного обеспечения

Дизайн асинхронного ввода-вывода будет отличаться для разных операционных систем и платформ программирования. Node.js был разработан с учетом асинхронности. По крайней мере, вы должны использовать Promises, а когда появится ECMAScript 7, _1 _ / _ 2_. C # /. Net уже имеет полную поддержку асинхронного режима, например node.js. Независимо от ОС и платформы, следует ожидать, что асинхронный режим будет работать очень хорошо. И какой бы язык вы ни выбрали, ищите ключевое слово asynchronous, большинство современных языков будут иметь некоторую поддержку, даже если это какое-то дополнение.

На веб-ферму?

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

Развенчание мифа - 64 КБ портов

Чтобы ответить на вопрос, касающийся 64 000, это заблуждение. Сервер может подключаться к более чем 65535 клиентам. См. https://networkengineering.stackexchange.com/questions/48283/is-a-tcp-server-limited-to-65535-clients/48284

Кстати, Http.sys в Windows позволяет нескольким приложениям использовать один и тот же порт сервера в соответствии со схемой URL-адреса HTTP. Каждый из них регистрирует отдельную привязку к домену, но в конечном итоге существует одно серверное приложение, проксирующее запросы к правильным приложениям.

Обновление 2019-05-30

Вот актуальное сравнение самых быстрых библиотек HTTP - https://www.techempower.com/benchmarks/#section=data-r16&hw=ph&test=plaintext

  • Дата тестирования: 2018-06-06
  • Используемое оборудование: Dell R440 Xeon Gold + 10 GbE
  • Лидер имеет ~ 7 миллионов ответов в открытом виде в секунду (ответы, а не соединения)
  • Второй Fasthttp для golang рекламирует 1,5 миллиона одновременных подключений - см. https://github.com/valyala/fasthttp
  • Ведущими языками являются Rust, Go, C ++, Java, C и даже C #, получивший 11-е место (6,9 Мбайт в секунду). Еще ниже идут Scala и Clojure. Python занимает 29-е место со скоростью 2,7 млн ​​в секунду.
  • В конце списка отмечу laravel и cakephp, rails, aspnet-mono-ngx, symfony, zend. Все ниже 10к в секунду. Обратите внимание, что большинство этих фреймворков построены для динамических страниц и довольно старые, могут быть более новые варианты, которые находятся выше в списке.
  • Помните, что это открытый текст HTTP, а не для специализации Websocket: многие люди, приходящие сюда, вероятно, будут заинтересованы в одновременных подключениях для websocket.
person Todd    schedule 28.03.2014
comment
Спасибо, что включили ссылки на людей, рассказывающих о том, как они это делают. - person Rick Smith; 02.06.2015
comment
Что, если единственный сервер, к которому подключился клиент, выйдет из строя? А что, если все ваши SPA случайно подключены к одному серверу и перегружают его? Идея использования балансировщиков нагрузки заключается не только в использовании одного, вы можете использовать их сколько угодно. - person ; 11.11.2015
comment
Клиенты выбирали сервер случайным образом. Шансы на то, что все случайно подключатся к одному, практически невозможны. Хотя можно проследить количество клиентов, и сервер может попросить клиента перейти на другой сервер, если он слишком переполнен. - person Todd; 11.11.2015
comment
Re: ограничение в 64 КБ - то, что вы говорите, верно, но для серверного приложения довольно часто прокси-запросы через какую-либо внутреннюю службу (службы), и в этом случае сервер теперь становится клиентом и, возможно, придется беспокоиться об эфемерности исчерпание порта (например: nginx.com/blog/overcoming- эфемерный порт-исчерпание-nginx-plus). Я уверен, что вы это знаете, но упомяну об этом для других (: - person jwd; 30.01.2017
comment
@jwd - хороший момент, контекстный для nginx в веб-приложении, но для базового веб-сайта такое проксирование не требуется. То же самое можно сказать и о подключении к базе данных через TCP через веб-приложение. Теоретически это решается за счет использования всех адресов в диапазоне 127. *. *. *, Но на практике я не знаю, доступен ли этот вариант. - person Todd; 31.01.2017
comment
@Todd Я как бы ищу реализацию Server Sent Event с использованием Nginx и ExpressJS. Просто я хотел знать, сколько одновременных подключений SSE будет обрабатывать мой сервер Ubuntu с его одноядерным процессором и 2 ГБ ОЗУ? Мне нужно будет отправлять push-уведомления для получения обновлений в реальном времени. Насколько хорошо он масштабируется? - person thewebjackal; 02.03.2020
comment
См. serverfault.com / questions / 384686 /. Нет запретительного ограничения протокола, это будет зависеть от специфики нашей системы, программного обеспечения (версий) и кода. Вы можете попробовать найти несколько примеров тестов, чтобы дать вам представление о парке с мячом (я только что попробовал - сам не нашел) - person Todd; 02.03.2020

Это довольно сложный вопрос. Нет никаких реальных программных ограничений на количество активных подключений, которые может иметь машина, хотя некоторые ОС более ограничены, чем другие. Проблема становится одним из ресурсов. Например, предположим, что одна машина хочет поддерживать 64 000 одновременных подключений. Если сервер использует 1 МБ ОЗУ на соединение, ему потребуется 64 ГБ ОЗУ. Если каждому клиенту необходимо прочитать файл, нагрузка доступа к диску или массиву хранения становится намного больше, чем могут обрабатывать эти устройства. Если серверу необходимо разветвить один процесс для каждого соединения, тогда ОС будет тратить большую часть своего времени на переключение контекста или нехватку процессорного времени для процессов.

На странице проблема C10K есть очень хорошее обсуждение этого вопроса.

person Variable Length Coder    schedule 15.10.2009
comment
Немного неоднозначный ответ. OP, по-видимому, относится к лучшему сценарию и включает в себя то, как он будет полезен, вместо того, чтобы находить худший случай и затем ссылаться на статью, в которой может быть решение. Полезно отметить узкое место на диске. Используя асинхронный ввод-вывод, можно охватить очень большое количество одновременных клиентов. - person Todd; 28.05.2015
comment
Как вы могли сказать, что настоящего программного ограничения нет, поскольку размер порта сам по себе составляет 16 бит, что делает максимальное количество портов, недоступных в любой момент, составляет не более 65,5 КБ. Я считаю, что ваш ответ неверен. - person आनंद; 17.06.2017
comment
У вашего компьютера может быть более 1 IP, поэтому доступно более 2 ^ 16 портов. - person Arman Ordookhani; 06.03.2018

Чтобы добавить мои два цента к разговору, процесс может одновременно открыть количество подключенных сокетов, равное этому количеству (в системах типа Linux) / proc / sys / net / core / somaxconn

cat / proc / sys / net / core / somaxconn

Этот номер может быть изменен на лету (конечно, только root-пользователем)

эхо 1024> / proc / sys / net / core / somaxconn

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

person Abraham Covelo    schedule 03.01.2012
comment
Хотя это, возможно, верно для Linux, это относится к виртуальному пределу, а не к тесту возможностей. Этот ответ на мой вкус немного специфичен и не дает никакого количества или указания количества одновременных подключений. Несмотря на ваши усилия, это не очень полезно. Возможно, вы могли бы самостоятельно ответить на вопрос: почему я не могу обслуживать более X одновременных TCP-соединений в Linux? - person Todd; 28.05.2015
comment
Насколько я могу судить, это неправильно. somaxconn - максимальное количество подключений в очереди на открытом сокете (т.е. это максимальное значение параметра невыполненной работы listen(int socket, int backlog). Оно не связано с количеством сокетов, которые процесс может открыть. - person Timmmm; 01.09.2015

Похоже, что ответ - минимум 12 миллионов, если у вас мощный сервер, ваше серверное программное обеспечение оптимизировано для него, у вас достаточно клиентов. Если вы тестируете от одного клиента к одному серверу, количество номеров портов на клиенте будет одним из очевидных ограничений ресурсов (каждое TCP-соединение определяется уникальной комбинацией IP-адреса и номера порта в источнике и месте назначения).

(Вам нужно запустить несколько клиентов, иначе вы сначала достигнете предела 64 КБ для номеров портов)

Когда доходит до этого, это классический пример остроумия о том, что «разница между теорией и практикой намного больше на практике, чем в теории» - на практике достижение более высоких чисел кажется циклом a. предложить конкретные изменения конфигурации / архитектуры / кода, b. протестируйте его, пока не достигнете предела, c. Я закончил? Если нет, то d. выяснить, что было ограничивающим фактором, e. вернитесь к шагу а (промойте и повторите).

Вот пример с 2 миллионами TCP-подключений к мощному компьютеру (128 ГБ ОЗУ и 40 ядер), на котором запущен Phoenix http://www.phoenixframework.org/blog/the-road-to-2-million-websocket-connections - им потребовалось около 50 достаточно значительных серверов, просто чтобы обеспечить клиентскую нагрузку (их первоначальные меньшие клиенты были максимально ранены, например, «довели до максимума нашу 4-ядерную / 15-гигабайтную коробку @ 450 тыс. клиентов»).

Вот еще одна ссылка на go на этот раз в 10 миллионов: http://goroutines.com/10m.

Это похоже на Java и 12 миллионов подключений: https://mrotaru.wordpress.com/2013/06/20/12-million-concurrent-connections-with-migratorydata-websocket-server/

person iheggie    schedule 06.04.2017
comment
Отличные новые ссылки, с правильным пониманием вопроса. Мне нравится общий совет по установке защитного барьера - ›почините барьер. У каждого своя конкретная ситуация, но, по крайней мере, у них есть указание на то, что экономически / практически достижимо. Не стоит обещать заказчику 100 миллионов на сервер в ближайшее время. - person Todd; 11.04.2017

Обратите внимание, что HTTP обычно не поддерживает TCP-соединения открытыми дольше, чем требуется для передачи страницы клиенту; и обычно пользователю требуется гораздо больше времени для чтения веб-страницы, чем для загрузки страницы ... пока пользователь просматривает страницу, он не добавляет никакой нагрузки на сервер.

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

person Jeremy Friesner    schedule 15.10.2009
comment
Это вообще не отвечает на вопрос. Независимо от точности того, что вы сказали, в данный момент все равно будет существовать несколько одновременных TCP-подключений, каков максимум? В этом суть вопроса. - person Todd; 29.03.2014
comment
Если у вас есть что-то стоящее, Тодд, обязательно сделайте это. - person Jeremy Friesner; 30.03.2014
comment
28 марта у меня уже был ответ, должно быть, вы его пропустили. В современном мире одностраничных приложений с длительным опросом и подключениями через веб-сокеты HTTP не всегда недолговечен. Но даже если он недолговечен, все еще существует максимальное количество одновременных подключений. Попытка объяснить вопрос не является ответом ИМО. Этот ответ лучше было бы поместить в качестве комментария к вопросу, он, безусловно, полезен, но вопрос относится к соединениям сокетов, а не к людям. Вопрос о соотношении (пользователи: активные соединения) при желании должен быть отдельным вопросом. - person Todd; 28.05.2015
comment
Keep Alive on HTTP TCP-соединения существуют и запрашиваются браузерами с последнего тысячелетия - это зависит от сервера, если он позволяет соединению оставаться активным, и каков будет период ожидания простоя. Разрешение Keep Alive снижает задержку группы запросов (например, HTML-страницы и связанных с ней ресурсов), но увеличивает использование ресурсов на сервере. - person iheggie; 06.04.2017

в случае протокола IPv4 сервер с одним IP-адресом, который прослушивает только один порт, может обрабатывать 2 ^ 32 IP-адреса x 2 ^ 16 портов, то есть 2 ^ 48 уникальных сокетов. Если вы говорите о сервере как о физической машине, и вы можете использовать все 2 ^ 16 портов, тогда может быть максимум 2 ^ 48 x 2 ^ 16 = 2 ^ 64 уникальных сокета TCP / IP для одного IP-адреса. Обратите внимание, что некоторые порты зарезервированы для ОС, поэтому это число будет меньше. Подводить итоги:

1 IP и 1 порт -> 2 ^ 48 сокетов

1 IP и все порты -> 2 ^ 64 сокета

все уникальные сокеты IPv4 во вселенной -> 2 ^ 96 сокетов

person Lukasz Ochmanski    schedule 29.08.2018

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

Другое - сколько портов может прослушивать ваш сервер? Думаю, отсюда и пришло число 64К. Фактически, протокол TCP использует 16-битный идентификатор порта, который преобразуется в 65536 (чуть больше 64 КБ). Это означает, что у вас может быть столько разных «слушателей» на сервере для каждого IP-адреса.

person tunafish24    schedule 24.11.2015
comment
Для вашего удобства я добавил к своему ответу дополнительный раздел, посвященный вашему заблуждению. Также этот вопрос относится к соединениям сокетов, а не к людям, что является важным различием в контексте этого вопроса. - person Todd; 29.01.2016
comment
Если мы говорим об одном сервере и маршрутизаторе, я думаю, что это правильный ответ. Но @Todd имеет дело с фермой серверных машин, к которым пользователь может подключаться к любой из них случайным образом через балансировщик нагрузки. - person Amr; 04.04.2017
comment
@amr это неверно. Мой ответ - об одной машине. Веб-ферма? Раздел предназначен для контраста и советов по выходу за рамки и заключает, что балансировщики нагрузки не нужны с хорошей архитектурой. Вы просто еще не прочитали мой ответ досконально. - person Todd; 05.04.2017

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

Чтобы проиллюстрировать это, если каждое соединение сокета потребляет 1 МБ ресурсов сервера, а на сервере доступно 16 ГБ ОЗУ (теоретически), это будет означать, что он сможет обрабатывать только (16 ГБ / 1 МБ) одновременные подключения. Я думаю, это так просто ... ДЕЙСТВИТЕЛЬНО!

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

person Oladipo Olasemo    schedule 06.12.2017