Подтвердить что ты не робот

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

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

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

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

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

4b9b3361

Ответ 1

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

Если вы используете ОС 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 соединениями, насыщающими ссылку на сервер с 2 потоками для обработки ввода-вывода...). Таким образом, базовая архитектура очень масштабируема.

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

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

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

Ответ 2

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

Ответ 3

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

Ответ 4

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

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

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

Ответ 5

Как отметил Грег, проблема, которую вы описываете, - это C10K (или, скорее, "C1M" в вашем случае) Недавно я сделал простой TCP-сервер эха на linux, который очень хорошо масштабируется с количеством сеансов (проверено только до 200 000), используя epoll. В BSD у вас есть что-то подобное, называемое kqueue. Вы можете проверить код, если хотите. Надеюсь, это поможет и удачи!

Ответ 6

EDIT: Как указано в комментариях ниже, мое первоначальное утверждение о том, что существует ограничение на 64 КБ, основанное на количестве портов, неверно, однако существует ограничение на количество дескрипторов сокетов на 32 КБ, поэтому мой предложенный дизайн действителен.

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

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

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