Ejabberd 顺序服务器与并行服务器

Ejabberd sequential vs parallel server

正如 Joe 的书中所定义的那样,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]。

在那种情况下,如果你仔细观察,再进一步观察,函数 start_connection 被调用 [2]。 在该函数内部,使用了一个动态主管并添加了一个 child [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