Последовательный сервер Ejabberd против параллельного сервера

#erlang #elixir #ejabberd #scalability #erlang-otp

Вопрос:

Как определено в книге Джо, параллельный TCP — сервер обрабатывает соединения, подобные этому :

 {ok, Listen}=gen_tcp:listen(....),
spawn(fun() ->parallel(Listen) end).

parallel(Listen) ->
{ok, Socket}=gen_tcp:accept(Listen),
spawn(fun() ->parallel(Listen) end),
doSomething(Socket).

doSomething(....) ->
.... 
 

Это логика, когда слушатель принимает соединение, он создает процесс для прослушивания новых входящих соединений, прежде чем обрабатывать это принятое соединение, это правило параллелизма, хорошо.
в модуле EJABBERD ejabberd_listener.erl, который представляет сетевой уровень сервера, вот что я нашел:

 case listen_tcp(Port, SockOpts) of
    {ok, ListenSocket} ->
.... 
    
    accept(ListenSocket, Module, State, Sup, Interval, Proxy), 

.... 
accept(ListenSocket, Module,... ) ->

case gen_tcp:accept(ListenSocket) of
    {ok, Socket} ->
%%%% a lot of work
....
accept(ListenSocket, Module,.... );
 

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

Ответ №1:

Я предполагаю, что вы говорите об этом коде: [1].

В этом случае, если вы посмотрите более внимательно, немного дальше, функция start_connection называется[2]. Внутри этой функции используется динамический супервизор и добавляется дочерний элемент [3]. Вы здесь не используете spawn примитив, но он абстрактен supervisor:start_child функцией[4].

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

[1] https://github.com/processone/ejabberd/blob/c3169e9eeab15f47b33a14a6b93cec67c38193a6/src/ejabberd_listener.erl#L235

[2] https://github.com/processone/ejabberd/blob/c3169e9eeab15f47b33a14a6b93cec67c38193a6/src/ejabberd_listener.erl#L266

[3] https://github.com/processone/ejabberd/blob/c3169e9eeab15f47b33a14a6b93cec67c38193a6/src/ejabberd_listener.erl#L316

[4] http://erlang.org/doc/design_principles/sup_princ.html