[erlang-questions] erlang socket send and rcv, high CPU usage
Dmitry Kolesnikov
dmkolesnikov@REDACTED
Mon May 20 17:39:20 CEST 2013
Hello,
... and use kernel poll.
Put flag +K true to vm.
Best Regards,
Dmitry >-|-|-*>
On 20.5.2013, at 18.28, Arun Muralidharan <arun11299@REDACTED> wrote:
> Hello Niean,
> Mentioned below are few of my suggestions:
> 1) Disable Nagle in server.
> 2) Try to use {active, once} in server. {active, true} setting may overflow your TCP buffer. In between, how much have you set the TCP read-write buffer (both in OS and application)?
> 3) Not sure what you are trying to achieve with port_command. Its not clear to me..
>
> Other design related suggestions would be to:
> 1) Use async communication model using prim_inets as the listener.
> 2) Better to use an FSM for managing socket states and flow control.
>
> Thanks,
> Arun
>
> -Arun
>
>
> On Mon, May 20, 2013 at 8:00 PM, 聂安 <nieanan3602@REDACTED> wrote:
>> hi all,
>> I have a question about the high cpu usage when sending and receiving data via erlang-socket.
>> My program uses a C/S mode. First, the server start a listening socket, and then the client connect to the server by using gen_tcp:connect. When establishing a connection, the client will keep sending "info" package to the server while waiting for a response from the client ; the server will respond an "info_ack" to the client when receiving a "info" package. When there's one client, at most 20000 packages per second are sent betweent C/S, while cpu usage reaches about 90%. My package is very little, at most 10Bytes, so my netcard is idle. When doing the same thing by C language, the cpu usage is just 6% while my netcard turns busy with about 500000 packa ges per second.
>> I have no idea why erlang gets so cpu-consuming. My program goes as follows:
>>
>> Server
>> config items about socket setting:
>> {tcp_listen_opts, [binary,{packet,0},{reuseaddr,true},{exit_on_close,true},{active,false}]}
>>
>> 30 start_connection(Parent, Sock, SockTransform) ->
>> 31 process_flag(trap_exit, true),
>> 32 Name =
>> 33 case catch ?NET:connection_string(Sock, inbound) of
>> 34 {ok, Str} -> Str;
>> 35 {error, enotcon} -> ?NET:fast_close(Sock),exit(normal);
>> 36 {error, _Reason} -> ?NET:fast_clost(Sock),exit(normal)
>> 37 end,
>> 38 Msg = io_lib:format("accept connection ~p(~p)", [Name, self()]),
>> 39 ?DEBUG(Msg), log:log(notice, ?MODULE, Msg),
>> 40 ClientSock = socket_op(Sock, SockTransform),
>> 41 ClientSock = Sock,
>> 42 {PHost, PPort, Host, Port} =
>> 43 socket_op(Sock, fun(S)->?NET:socket_ends(S,inbound) end),
>> 44 State = #state{
>> 45 parent = Parent,
>> 46 sock = ClientSock,
>> 47 name = list_to_binary(Name),
>> 48 callback = undefined,
>> 49 host = Host,
>> 50 port = Port,
>> 51 peer_host = PHost,
>> 52 peer_port = PPort
>> 53 },
>> 54 try
>> 55 %ok = inet_op(),
>> 56 inet:setopts(ClientSock, [{active, true}]),
>> 57 Ret = rcv_loop(State),
>> 58 WMsg=lists:flatten(io_lib:format("closing connection ~p(~p), "
>> 59 "reason: ~p", [Name,self(),Ret])),
>> 60 ?DEBUG(WMsg), log:log(warning, ?MODULE, WMsg)
>> &nbs p;61 catch
>> 62 E:R ->
>> 63 EMsg=lists:flatten(io_lib:format("closing connection ~p(~p), "
>> 64 "reason: ~p:~p", [Name, self(), E, R])),
>> 65 ?DEBUG(EMsg), log:log(error, ?MODULE, EMsg)
>> 66 after
>> 66 after
>> 67 ?NET:fast_close(ClientSock),
>> 68 Msg2=lists:flatten(io_lib:format("connection ~p(~p) closed",
>> 69 [Name, self()])),
>> 70 ?DEBUG(Msg2), log:log(notice, ?MODULE, Msg2)
>> 71 end,
>> 72 normal.
>> 73
>> 74 rcv_loop(#state{sock=Sock}=Sta te) ->
>> 75 receive
>> 76 {tcp, Sock, Binary} ->
>> 77 NState = report_run(State, Binary),% calls port_command to send ack pkg
>> 78 %inet:setopts(Sock, [{active, once}]),
>> 79 rcv_loop(NState);
>> 80 {tcp_closed, Sock} -> 'peer closed';
>> 81 _Other -> rcv_loop(State)
>> 82 after ?RCV_TIMEOUT -> 'rcv timeout'
>> 83 end.
>>
>>
>>
>> Client
>> 10 -define(TCP_OPTIONS, [binary, {packet,0}, {active, false},
>> 11 &nb sp; {exit_on_close,true}, {reuseaddr,true}]).
>> 101 setup_short_connection(Host, Port, #state{id=Id}=State) ->
>> 102 case gen_tcp:connect(Host, Port, ?TCP_OPTIONS) of
>> 103 {ok, Socket} ->
>> 104 ?DEBUG("client(~p) connected to ~p:~p", [Id,Host,Port]),
>> 105 inet:setopts(Socket, [{active, once}]),
>> 106 send_request_and_wait_for_response(State#state{socket=Socket});
>> 107 {error, Reason} ->
>> 108 EMsg=lists:flatten(io_lib:format("client(~p) connect failed,"
>> 109 "reason: ~p", [Id, Reason])),
>> 110 ?DEBUG(EMsg),
>> 111 {error, 'connect failed'}
>> 112 end.
>> 118 send_request_and_wait_for_response(#state{id=Id,requ_cnt=RequCnt}=State) ->
>> 119 try
>> 120 Ref = RequCnt,
>> 121 NState = send_request(State, Ref),
>> 122 wait_for_response(NState, Ref)
>> 123 catch
>> 124 E:R ->
>> 125 EMsg = io:format("client(~p) failed in send_request_and_wait_for_response"
>> 126 ", reason: ~p:~p", [Id, E, R]),
>> 127 ?DEBUG(EMsg),
>> 128 {error, 'error during send or wait'}
>> 129 end.
>> 130
>> 131 send_request(#state{socket=Sock,requ_cnt=RequCnt}=State, Ref) ->
>> 132 Data = {{"business", "aos"}, {"ref", Ref}},
>> 133 Pkg = {{"type", "key"}, {"data", Data}},
>> 134 JPkg = term_to_binary(Pkg),
>> 135 true = erlang:port_command(Sock, JPkg, [nosuspend]),
>> 136 State#state{requ_cnt=RequCnt-1}.
>> 137
>> 138 wait_for_response(#state{socket=Sock}=State, Ref) ->
>> 139 receive
>> 140 {tcp, Sock, Binary} ->
>> 141 ok = inet:setopts(Sock, [{active,once}]),
>> 142 case report_run(State, Binary, Ref) of
>> 143 {response, NState} -> send_request_and_wait_for_response(NState);
>> 144 {other, _} -> wait_for_response(State, Ref)
>> 145 end;
>> 146 _Other -> wait_for_response(State, Ref)
>> 147 after 30000 -> {error, 'rcv response timeout'}
>> 148 end.
>>
>>
>> I'm sorry for my poor English. I will be very grateful if someone help me to solve this problem.
>>
>> yours
>> niean
>>
>>
>>
>> _______________________________________________
>> erlang-questions mailing list
>> erlang-questions@REDACTED
>> http://erlang.org/mailman/listinfo/erlang-questions
>
> _______________________________________________
> erlang-questions mailing list
> erlang-questions@REDACTED
> http://erlang.org/mailman/listinfo/erlang-questions
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://erlang.org/pipermail/erlang-questions/attachments/20130520/685e76ea/attachment.htm>
More information about the erlang-questions
mailing list