【问题标题】:Ejabberd network layer is not performantEjabberd 网络层性能不佳
【发布时间】:2021-11-30 06:56:37
【问题描述】:

我知道 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 侦听器中,侦听机制很简单:主管有工人子级,每个子级代表一个模块侦听器及其侦听选项(端口、网络协议、IP、...),有 4 个或 5 个孩子和所有孩子在开始时运行两个函数之一:TCP 或 UDP,最后一个表示传入连接的侦听函数,当接受连接并创建 Socket 时,侦听器将 Socket 作为参数传递给模块的启动函数并继续接受其他连接,代码中最重要的部分是:

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

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 的经验可以帮助我吗?

【问题讨论】:

    标签: sockets erlang elixir ejabberd erlang-otp


    【解决方案1】:

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

    Joe Armstrong 书中的 sn-p 则相反:它产生一个新进程来接受进一步的传入连接,并在现有进程中处理当前连接。目前尚不清楚(至少对我而言)任何一种方式都必然比另一种方式更高效。

    【讨论】:

    • 我认为你是对的,所以经过一些分析,我认为它就像 Joe 的实现一样,谢谢 legoscia,但它仍然效率不高,并且在真实服务器中,如果我们考虑,那将无法正常工作100 个连接同时出现(我说的只是小服务器)最后一个将等待服务器接受 99 个连接来接受它,所以解决方案是启动一个有 100 个等待孩子的动态主管,当孩子接受时一个连接它会启动一个新的等待孩子总是得到 100 个免费的接受者,这就是 Cowboy 的工作方式,那么为什么 Ejabberd 没有呢?
    • 好问题。我的猜测是,这是因为 XMPP 连接与 HTTP 连接不同——它们以 STARTTLS 握手和身份验证开始,因此已经存在如此多的开销,以至于接受连接的小延迟并不明显——但只有 ejabberd 开发人员可以给一个明确的答案。
    • 是的,我认为身份验证是一种阻塞机制,需要一些时间,但在中型到大型服务器中(Whatsapp 中使用 Ejabberd 来处理 60 亿用户)我确信这永远不会起作用,而且免费的接受者是在我看来,必须且仅在我看来 Process One 团队考虑了各种性能不佳且无法处理 24/24 小时快速并行连接的服务器硬件,因此我开始理解为什么您应该在使用现有代码之前掌握 Erlang根据您的需求和能力定制最后一个。
    • 但正如您所提到的,Ejabberd 开发人员可以给出最后一句话。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-10-20
    • 2014-05-11
    • 1970-01-01
    • 2013-05-06
    • 2013-01-14
    • 1970-01-01
    • 2016-01-07
    相关资源
    最近更新 更多