Как сохранить один миллион одновременных соединений TCP?

Я должен разработать сервер, который должен служить миллионам клиентов, которые одновременно соединены с сервером через TCP.

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

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

Кто-либо знает, как сделать это, и какие аппаратные средства/программное обеспечение необходимы (по наименьшему количеству стоимости)?

40
задан Mike Pennington 22 November 2012 в 14:09
поделиться

4 ответа

Какие операционные системы вы рассматриваете для этого?

Если вы используете ОС Windows и используете что-то позднее, чем Vista, у вас не должно возникнуть проблем с тысячами подключений на одной машине. Я провел тесты (здесь: http://www.lenholgate.com/blog/2005/11/windows-tcpip-server-performance.html ) на машине Windows Server 2003 с низкими характеристиками и легко достигло более 70 000 активных TCP-соединений. Некоторые ограничения ресурсов, влияющие на количество возможных подключений, были значительно сняты в Vista (см. Здесь: http://www.lenholgate.com/blog/2005/11/windows-tcpip-server-performance.html ), поэтому вы, вероятно, сможете достичь своей цели с помощью небольшого кластера машин. Я не знаю, что вам понадобится перед ними для маршрутизации соединений.

Windows предоставляет средство, называемое портами завершения ввода-вывода (см .: http://msdn.microsoft.com/en-us/magazine/cc302334.aspx ), которое позволяет обслуживать многие тысячи одновременные соединения с очень небольшим количеством потоков (вчера я запускал тесты с 5000 подключениями, насыщая ссылку на сервер двумя потоками для обработки ввода-вывода ...). Таким образом, базовая архитектура очень масштабируема.

Если вы хотите запустить несколько тестов, то в моем блоге есть несколько бесплатных инструментов, которые позволяют вам обрабатывать простой эхо-сервер, используя многие тысячи соединений ( 1 ) и ( 2 ) и некоторый бесплатный код, который можно использовать для начала работы ( 3 )

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

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

20
ответ дан 27 November 2019 в 01:57
поделиться

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

11
ответ дан 27 November 2019 в 01:57
поделиться

РЕДАКТИРОВАТЬ: Как отмечено в комментариях ниже, мое первоначальное утверждение о том, что существует ограничение в 64 КБ, основанное на количестве портов, неверно, однако там есть ограничение в 32 КБ на количество дескрипторов сокетов , так что мой предложенный дизайн действителен.

При типичной архитектуре сервера TCP / IP вы ограничены в количестве одновременных открытых подключений, которые вы можете иметь. У сервера есть один порт прослушивания, и когда к нему подключается клиент, сервер выполняет вызов accept, который создает новый сокет на случайном порте для остальной части соединения.

Я думаю, что для обработки более 64К одновременных подключений вам нужно вместо этого использовать UDP. Вам нужен только один порт для прослушивания сервером, и вам нужно управлять подключениями, используя 32-битный идентификатор клиента в пакетных данных, вместо того, чтобы иметь отдельный порт для каждого клиента. 32-битный идентификатор клиента может быть IP-адресом клиента, и клиент может прослушивать через известный порт UDP сообщения, возвращаемые с сервера. Этот порт будет единственным, который должен быть открыт на брандмауэре.

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

-4
ответ дан 27 November 2019 в 01:57
поделиться

Некоторое время назад я наткнулся на APE Project . Кажется, мечта сбылась. Они могут поддерживать до 100 тысяч одновременных клиентов на одном узле. Распределите их по 10 или 20 узлам, и вы сможете обслуживать миллионы. Идеально подходит для приложений RESTful. Возможно, вы захотите глубже изучить любое общее пространство имен. Одним из недостатков является то, что это автономный сервер, как дополнение к веб-серверу. Этот сервер, конечно же, с открытым исходным кодом, поэтому любые затраты связаны с оборудованием / интернет-провайдером.

4
ответ дан 27 November 2019 в 01:57
поделиться
Другие вопросы по тегам:

Похожие вопросы: