LINUX.ORG.RU

высокопроизводительный сетевой сервер


0

0

Надо написать на С/С++ сетевой мультиплексор, который будет принимать запросы от клиентов из локальной сети и транслировать их на удаленный сервер и обратно. TCP-cоединение с клиентом поддерживается постоянно. Связь с удаленым сервером возможна только по одному соединению. Все бы ничего, но клиентов ожидается несколько тысяч.

Есть ли какие-то секреты при написании таких програм? Есть ли системное ограничение на максимальное количество одновременных соединений у процесса и можно ли его преодолеть?

Если кто писал что-то подобное, поделитесь пожалуста опытом.

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

★★

может erlang?

Pi ★★★★★
()

> но клиентов ожидается несколько тысяч.

load balancer наше все. Кстати... А что говорит нам man iptables -j DNAT на это? Может статься, что можно и не писать ничего.

> при таком подходе уже при 100 клиентах начинаются проблемы с производительностью.

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

no-dashi ★★★★★
()

> Есть ли какие-то секреты при написании таких програм?

Нет, если не считать секретом man epoll и исходники существующих быстрых серверов.

> Есть ли системное ограничение на максимальное количество одновременных соединений у процесса и можно ли его преодолеть?

ulimit на количество открытых файлов.

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

select -> epoll (хотя на 100 клиентах это должно еще быть почти пофиг). Если время жизни клиентского соединения значительно - сделать thread pool, и отдавать туда новые соединения.

Как-то так.

Да, еще - а на уровне организации сети вашу проблему не получается решить? бросить от вашего краевого сервера до удаленного IPSec/OpenVPN, и маршрутизировать клиентов прямо туда.

anonymous
()

Можно еще посмотреть в сторону FreeBSD с kqueue/kevent вместо select

swizard
()

Помойму для таких вещей и придуман erlang

Motiv_studenta ★★
()

Спасбо всем за советы и ссылки.
Будем делать на базе epoll (freebsd и 
win2k сейчас использовать нельзя) и thread pool. Ну а если все равно 
мощей не хватит, то возможно придется строить иерархию 
ретрансляторов...


>select -> epoll (хотя на 100 клиентах это должно еще быть почти 
> пофиг). Если время жизни клиентского соединения значительно - 
> сделать thread pool, и отдавать туда новые соединения.

Время жизни соединения в основном 7-8 часов, кроме того все соединеня стартуют одновременно и одновременно же закрываются. Наверно придется 
делать не одно соединение на поток, а группировать их.

> Да, еще - а на уровне организации сети вашу проблему не получается 
> решить? бросить от вашего краевого сервера до удаленного 
> IPSec/OpenVPN, и маршрутизировать клиентов прямо туда.

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

>Помойму для таких вещей и придуман erlang

Может быть, не спорю, но:
1. Проект надо выпустить в продакшн максимум к следующей пятнице.
2. Я не знаю erlang
3. мне никто не будет оплачивать время потраченое на изучение erlang.
4. Заказчик будет не в восторге от того, что для поддержки продукта ему нужен будет спецалист со специфическими скилами.
в этом мире все решают деньги :)

Vinick ★★
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.