Ejabberd 网络层性能不佳

Ejabberd network layer is not performant

我知道 ejabberd 服务器是高效的并且专为高性能和容错而设计,但我不明白为什么我看到它的侦听器模块按顺序处理连接,在 Joe Armestrong 的书中我看到并行服务器是这样工作的:

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

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

handling(Socket) ->
....

但是在名为 ejabberd_listener.erl 的 EJABBERD 侦听器中,侦听机制很简单:主管有工人 children,每个 child 代表一个模块侦听器及其侦听选项(端口, network protocole, ip,...) ,有 4 或 5 children 和所有 children 运行 两个功能之一在开始时:TCP 或 UDP,最后一个代表监听传入连接的函数,当接受连接并创建套接字时,侦听器将套接字作为参数传递给模块的启动函数,并继续接受其他连接,代码中最重要的部分是:

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

init_tcp(PortIP, Module, Opts, SockOpts, Port, IPS) ->

%% Some of work
.... 

ListenSocket = listen_tcp(PortIP, Module, SockOpts, Port, IPS), 

%% Some of work
.... 

accept(ListenSocket, Module,.... ), 

%% Some of work
.... 

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

listen_tcp(....) ->

Res = gen_tcp:listen(....),

%% Some of work
.... 

case Res of {ok, ListenSocket} ->Listensocket;

%% Some of work
.... 

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

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

case gen_tcp:accept(ListenSocket) of
    {ok, Socket} ->

%% Some of work
....

Module:start(....,Socket,....),

%% Some of work
.... 

accept(ListenSocket, Module,.... );

很明显这是一个顺序侦听器,它 运行 比并行慢,那么为什么他们不使用并行机制来提高效率和性能呢?可能是我搞砸了什么,或者这是因为它是社区版,你需要修改代码,所以有 Erlang 和 Ejabberd 经验的人可以帮助我吗?

这两种变体实际上是平行的。 ejabberd_listener 调用侦听器模块中的 start 函数,至少在 ejabberd_c2s 的情况下最终会调用 xmpp_stream_in:start,后者 starts a new gen_server process。然后 ejabberd_listener 进程可以再次调用 gen_tcp:accept,等待另一个传入连接。

Joe Armstrong 书中的代码片段恰恰相反:它生成一个新进程以接受更多传入连接,并在现有进程中处理当前连接。目前尚不清楚(至少对我而言)这两种方式是否必然比另一种方式更高效。