我知道 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 作為引數傳遞給啟動函式Module 并繼續接受其他連接,最重要的部分代碼是:
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
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 的經驗可以幫助我嗎?
uj5u.com熱心網友回復:
這兩種變體實際上是平行的。 ejabberd_listener呼叫startlistener 模塊中的函式,至少在ejabberd_c2s呼叫的情況下xmpp_stream_in:start,它會啟動一個新的 gen_server 行程。ejabberd_listener然后該行程可以自由地gen_tcp:accept再次呼叫,等待另一個傳入連接。
Joe Armstrong 書中的代碼片段則相反:它生成一個新行程來接受進一步的傳入連接,并在現有行程中處理當前連接。目前尚不清楚(至少對我而言)任何一種方式都必須比另一種方式更高效。
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/313382.html
標籤:插座 二郎 长生不老药 埃贾伯德 erlang-otp
