<div dir="ltr"><div>I worte a tcp proxy to forward data from peer to peer, but i find the CPU usage of beam is high in test</div>
<div>The client make 1000 connections per second and get 16K data from server, and the server send 8K to client per second, because we want to decrease the traffic.</div>
<div>And the compute's CPU is Intel(R) Xeon(TM) CPU 3.20GHz, so the proxy's usage is on avenage 26%</div>
<div>Is my codes have some problem or erlang need some optimization.</div>
<div>Anyone can tell me </div>
<div> </div>
<div>here is my codes</div>
<div> </div>
<div>%%%----------------------------------------------------------------------<br>%%% File : tcp.erl<br>%%% Author : Zhao Liang<<a href="mailto:realaqura@gmail.com">realaqura@gmail.com</a>><br>%%%----------------------------------------------------------------------</div>
<div>-module(tcp).<br>-author(<a href="mailto:'realaqura@gmail.com'">'realaqura@gmail.com'</a>).</div>
<div>-compile(export_all).</div>
<div><br>-define(MAIN_MODULE, tcp).</div>
<div><br>-record(cfg, {<br> listen_port = 10080,<br> idle = 30000}).</div>
<div><br>main(Port) -><br> Cfg = #cfg{listen_port=Port},<br> case gen_tcp:listen(Port, [{reuseaddr,true}, {active,false}, {backlog,64}, binary]) of<br> {ok, LSock} -></div>
<div> create_accept_thread(LSock, Cfg, self()),<br> tcp_ctl_loop(LSock, Cfg, self());<br> ERR -> ERR<br> end.</div>
<div>tcp_ctl_loop(LSock, Cfg, Self) -><br> receive <br> {_, next} -><br> create_accept_thread(LSock, Cfg, Self),</div>
<div> tcp_ctl_loop(LSock, Cfg, Self);<br> _ -><br> tcp_ctl_loop(LSock, Cfg, Self)<br> end.</div>
<div>create_accept_thread(LSock, Cfg, Pid) -><br> spawn_link(?MAIN_MODULE, accept_thread, [LSock, Cfg, Pid]).</div>
<div>accept_thread(LSock, Cfg, Parent) -><br> accept_loop(LSock, Cfg, Parent).</div>
<div>accept_loop(LSock, Cfg, Parent) -><br> case prim_inet:async_accept(LSock, -1) of<br> {ok, Ref} -><br> receive<br> {inet_async, LSock, Ref, {ok,CSock}} -><br> Parent ! {self(), next},<br>
tcp_start(CSock, Cfg);<br> {inet_async, LSock, Ref, _} -><br> accept_loop(LSock, Cfg, Parent)<br> end;<br> _ -><br> accept_loop(LSock, Cfg, Parent)<br>
end.</div>
<div>tcp_start(CSock, Cfg) -><br> case prim_inet:getopts(CSock, [original_dst]) of<br> {ok, [{original_dst, {Oport, Oip}}]} -><br> case gen_tcp:connect(Oip, Oport, [{active,true}, {packet,raw}, binary], Cfg#cfg.idle) of<br>
{ok, SSock} -><br> tcp_start(CSock, SSock, Cfg);<br> _ -><br> inet:tcp_close(CSock)<br> end;<br> _ -> <br> inet:tcp_close(CSock)<br>
end.<br>tcp_start(CSock, SSock, Cfg) -><br> inet:setopts(CSock, [{active, true}, {packet,raw}, binary]),<br> tcp_data_loop(CSock, SSock, Cfg).</div>
<div>tcp_data_loop(CSock, SSock, Cfg) -><br> receive <br> {tcp, Socket, Data} -><br> if<br> Socket == CSock -><br> case prim_inet:send(SSock, Data) of<br> ok -><br>
tcp_data_loop(CSock, SSock, Cfg);<br> _ -><br> gen_tcp:close(CSock),<br> gen_tcp:close(SSock)<br> end;<br>
Socket == SSock -><br> case prim_inet:send(CSock, Data) of<br> ok -><br> tcp_data_loop(CSock, SSock, Cfg);<br> _ -><br>
gen_tcp:close(CSock),<br> gen_tcp:close(SSock)<br> end;<br> true -><br> tcp_data_loop(CSock, SSock, Cfg)<br> end;<br>
{tcp_closed, Socket} -><br> if<br> Socket == CSock -><br> gen_tcp:close(SSock);<br> Socket == SSock -><br> gen_tcp:close(CSock);<br>
true -><br> gen_tcp:close(CSock),<br> gen_tcp:close(SSock)<br> end;<br> _ -><br> gen_tcp:close(CSock),<br> gen_tcp:close(SSock)<br>
after<br> Cfg#cfg.idle -><br> gen_tcp:close(CSock),<br> gen_tcp:close(SSock)<br> end.<br></div></div>