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 原语创建的普通进程。
正如 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 原语创建的普通进程。