LINUX.ORG.RU

Быстрый сокет сервер

 ,


0

3

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

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

Есть ли возможность в Erlang добиться сравнимой скорости?

Сейчас экспериментирую, результаты пока не впечатляют. Использовал и сервер с несколькими ацепторами, и сервер с одним ацептором.

Происходит следующее - до 15 000 последовательных запросов проходят очень быстро, 16 000 - в два раза дольше, чем 15 000, и уже с не приемлемой скоростью.

Отработавшие ацепторы завершаются, не висят в запущенных процессах. Экспериментирую на тех же машинах, на которых сервер на C работает нормально.

Возможно, есть параметры для erl или опции для gen_tcp:listen, решающие проблему?

Подскажите, плиз, кто в курсе.


Правильно написанный сервер на C/C++ порвёт вообще всё, что угодно - это аксиома.

Сейчас набегут фанаты erlang/haskell/lisp/java/whatever и будут утвержать, что реализация на их любимом ЯП в три раза быстрее, чем реализация на C и в два раза быстрее, чем на другом ЯП из этого же списка. Их можно смело игнорить.

Нужно больше деталей. Как реализован самопальный сервер на C? Что значит «1000 последовательных запросов в секунду от одного клента»? Сервер не может обрабатывать запросы параллельно потому что он плохо написан? Или потому что это в принципе невозможно? Или что-то другое?

Deleted
()
Ответ на: комментарий от Deleted

Сервер на C может обрабатывать параллельно запросы. В описании задачи я указал, что в основном приходится обрабатывать последовательные запросы от клиента, поэтому при тестировании для меня главный показатель - скорость обработки последовательных запросов.
1000 последовательных запросов в секунду от одного клента - это значит, один клиент за одну секунду последовательно делает 1000 запросов, сделал запрос - получил ответ, сделал запрос...

Упаковывать в один запрос несколько не предлагать ;)

tuxin
() автор топика
Ответ на: комментарий от Deleted

сервер на C/C++ порвёт вообще всё, что угодно - это аксиома.

Ога, порвет — на хелоуворлдах на местных локалхостах.

Oxdeadbeef ★★★
()
Ответ на: комментарий от Deleted

Правильно написанный сервер на ассемблере порвёт вообще всё, что угодно - это аксиома.

Исправил, не благодари.

anonymous
()

он успевает обрабатывать около 1000 последовательных запросов

Это при том, что клиент ваще ваще один? то есть не 2000 клиентов сразу долбят?
Слабовасто как-то, если так...Сейчас вот проверил сервачок один на сосдней машине (натравил 20к запросов). отклик от пустого запроса (который не ищет ничего, просто отвечает) ~230-260 микросекунд.

Ахда .. протокол бинарный, есличо.

anonymous
()
Ответ на: комментарий от anonymous

Возможно сервер слабоват, возможно клиент, не принципиально, такая скорость устраивает.

tuxin
() автор топика
Ответ на: комментарий от theNamelessOne

> Главная фишка erlang в конкурентности.

Поправил.

Какой глупый исправлятель, иди русский выучи сперва!

anonymous
()

Сервер неблокирующий, чтение из сокета синхронное?

anonymous
()
Ответ на: комментарий от theNamelessOne

Слово конкурентность в русском имеет значение отличное от английского слова concurrency

anonymous
()
Ответ на: комментарий от anonymous

Слово конкурентность в русском имеет значение отличное от английского слова concurrency

Зато «конкурентность» более близко к оригиналу, чем «параллелизм», не находишь?

theNamelessOne ★★★★★
()

Попахивает проблемами с исчерпанием сокетов. У тебя, надеюсь, не устанавливается новое соединение на каждый запрос?

Смотри top. Если сервер «не отвечает» а загрузка проца 0 то кури в сторону SO_REUSEADDR, net.ipv4.tcp_tw_recycle, net.ipv4.tcp_tw_reuse, всяких таймаутов.... Короче, гугл в помощь.

true_admin ★★★★★
()
Ответ на: комментарий от true_admin

Да, дело похоже в лимитах. Перепроверю еще на паре машин в понедельник.

Спасибо.

tuxin
() автор топика

1000 быстрых запросов от клиента, это что у тебя клиент такое делает, что нельзя упаковать?

Ты на каждый запрос устанавливаешь/рвешь подключание?

У меня даже в Qt-шных сокетах запрос-ответ укладывается в миллисекунду (насколько реально меньше не считал).

grondek
()
Ответ на: комментарий от tuxin
-module(server).

-export([start/1, terminate/1]).

start(Port) ->
  {ok, Srv} = gen_tcp:listen(Port, [
    {active, true},
    {reuseaddr, true}]),
  {ok, spawn(fun() -> acceptor(Srv) end), Srv}.

terminate(Skt) ->
  gen_tcp:close(Skt),
  ok.

acceptor(Srv) ->
  {ok, ClientSkt} = gen_tcp:accept(Srv),
  spawn(fun() -> acceptor(Srv) end),
  servant(ClientSkt).

servant(Skt) ->
  receive
    {tcp, Skt, _Data} ->
      gen_tcp:send(Skt, "1234567890"),
      servant(Skt);
    _ ->
      ok
  end.
nanoolinux ★★★★
()
Ответ на: комментарий от tuxin

15000 обрабатывается нормально на одной ноде? Что происходит с производительностью, когда поднимается вторая, третья? Если ничего, то код, переписанный C/C++, конечно всё это порвёт.

blexey ★★★★★
()

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

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