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

114

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

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

Дэвид
источник
2
Приношу извинения респондентам, я разорвал эту нить как смерч. На мой вкус, было слишком много неправильных ответов, а прямого ответа все равно не было. Я много использую stackoverflow и нахожу много качественных ответов. Я надеюсь, что другие смогут найти эту ветку и найти полезный информированный ответ.
Тодд
Привет, Дэвид, ты нашел правильный ответ на этот вопрос?
Блюдо
64000 TCP-соединений через один IP-адрес сервера. Вы можете модернизировать свою сеть серверов до масштабирования и поддержки более 64000.
Эйри,

Ответы:

109

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

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

Лучший случай

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

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

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

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

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

WhatsApp получает миллион с трафиком на одной машине с ОС Unix - https://blog.whatsapp.com/index.php/2012/01/1-million-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, async/ await. C # /. Net уже имеет полную поддержку асинхронного режима, такую ​​как node.js. Независимо от ОС и платформы, следует ожидать, что асинхронный режим будет работать очень хорошо. И какой бы язык вы ни выбрали, ищите ключевое слово «асинхронный», большинство современных языков будут иметь некоторую поддержку, даже если это какое-то дополнение.

В WebFarm?

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

Разрушая миф - 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.
Тодд
источник
2
Спасибо, что включили ссылки на людей, рассказывающих о том, как они это делают.
Рик Смит
Что если единственный сервер, к которому подключился клиент, выйдет из строя? А что, если все ваши SPA случайно подключены к одному серверу и перегружают его? Идея использования балансировщиков нагрузки заключается не только в использовании одного, вы можете использовать их сколько угодно
pyros2097
3
Клиенты выбирали сервер случайным образом. Шансы на то, что все случайно подключатся к одному, практически невозможны. Хотя можно было проследить количество клиентов, и сервер мог попросить клиента перейти на другой сервер, если он слишком переполнен.
Тодд,
1
Re: ограничение в 64 КБ - то, что вы говорите, верно, но для серверного приложения довольно часто прокси-запросы через какую-либо внутреннюю службу (службы), и в этом случае "сервер" теперь становится "клиентом" и вполне может иметь беспокоиться об исчерпании временного порта (например: nginx.com/blog/overcoming-ephemeral-port-exhauration-nginx-plus ). Я уверен, что вы это знаете, но упоминание об этом для других (:
jwd
@jwd - хороший момент, контекстный для nginx в веб-приложении, но для базового веб-сайта такое проксирование не требуется. То же самое можно сказать и о подключении к базе данных через TCP через веб-приложение. Теоретически это решается использованием всех адресов в диапазоне 127. *. *. *, Но на практике я не знаю, доступен ли этот вариант.
Тодд
54

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

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

Кодер переменной длины
источник
3
Немного неоднозначный ответ. OP, по-видимому, относится к лучшему сценарию и включает в себя то, как он будет полезен, вместо того, чтобы находить худший случай и затем ссылаться на статью, в которой может быть решение. Обратите внимание на узкое место на диске. Используя асинхронный ввод-вывод, можно охватить очень большое количество одновременных клиентов.
Тодд
Как вы могли сказать, что настоящего программного ограничения нет, поскольку размер порта сам по себе составляет 16 бит, что делает максимальное количество портов, недоступных в любой момент, составляет не более 65,5 КБ. Я считаю, что ваш ответ неверен.
आनंद
У вашего компьютера может быть более 1 IP, поэтому доступно более 2 ^ 16 портов.
Arman Ordookhani 05
8

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

cat / proc / sys / net / core / somaxconn

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

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

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

Авраам Ковело
источник
1
Хотя это, возможно, верно для Linux, это относится к виртуальному пределу, а не к тесту возможностей. Этот ответ, на мой вкус, немного специфичен и не дает никакого количества или указания количества одновременных подключений. Несмотря на ваши усилия, это не очень полезно. Может быть, вы могли бы самостоятельно ответить на вопрос: «Почему я не могу обслуживать более X одновременных TCP-соединений в Linux»
Тодд
2
Насколько я могу судить, это неправильно . somaxconn - максимальное количество подключений в очереди на открытом сокете (то есть это максимальное значение параметра невыполненной работы listen(int socket, int backlog). Это не связано с количеством сокетов, которые процесс может открыть.
Timmmm 01
8

Похоже, что ответ - минимум 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 000 клиентов»).

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

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

iheggie
источник
Замечательные новые ссылки, с правильным пониманием вопроса. Мне нравится общий совет для хит-барьера -> исправить барьер. У каждого своя конкретная ситуация, но, по крайней мере, у них есть указание на то, что экономически / практически достижимо. Не стоит в ближайшее время обещать заказчику 100 миллионов на сервер.
Тодд
5

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

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

Джереми Фриснер
источник
13
Это вообще не отвечает на вопрос. Независимо от точности того, что вы сказали, в данный момент все равно будет существовать несколько одновременных TCP-соединений, каков максимум? В этом суть вопроса.
Тодд
3
Если у вас есть что-то стоящее, Тодд, обязательно сделайте это.
Джереми Фриснер
8
У меня уже был ответ 28 марта, должно быть, вы его пропустили. В современном мире одностраничных приложений с длинными опросами и подключениями через веб-сокеты HTTP не всегда недолговечен. Но даже если он недолговечен, все еще существует максимальное количество одновременных подключений. Попытка объяснить вопрос не является ответом ИМО. Этот ответ лучше было бы поместить в качестве комментария к вопросу, он, безусловно, полезен, но вопрос относится к «соединениям сокетов», а не к «людям». Вопрос о соотношении (пользователи: активные соединения) при желании должен быть отдельным вопросом.
Тодд
1
Keep Alive on HTTP TCP-соединения существуют и запрашиваются браузерами с последнего тысячелетия - это зависит от сервера, если он позволяет соединению оставаться активным, и каков будет период ожидания простоя. Разрешение Keep Alive снижает задержку группы запросов (например, HTML-страницы и связанных с ней ресурсов), но увеличивает использование ресурсов на сервере.
iheggie
1

в случае протокола 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 сокетов

Лукаш Очмански
источник
0

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

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

тунец24
источник
Для вашего удобства я добавил к своему ответу дополнительный раздел, посвященный вашему заблуждению. Также этот вопрос относится к «соединениям сокетов», а не к «людям», что является важным различием в контексте этого вопроса.
Тодд
Если мы говорим об одном сервере и маршрутизаторе, я думаю, что это правильный ответ. Но @Todd берет на себя ферму серверных машин, которые пользователь может случайным образом подключать к любой из них через балансировщик нагрузки.
Amr
@amr это неверно. Мой ответ - об одной машине. "Веб-ферма?" Раздел предназначен для контраста и советов по выходу за рамки и заключает, что балансировщики нагрузки не нужны с хорошей архитектурой. Вы просто еще не прочитали мой ответ полностью.
Тодд
0

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

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

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

Оладипо Оласемо
источник