我一直在玩一个玩具网络服务器,我把它放在重负荷下。我发现它表现得非常好,除了一些异常值。这是相关的代码:
init() ->
%Gets the listen socket ({active,false}), generates acceptor threads
case gen_tcp:listen(?LISTEN_PORT, ?TCP_OPTS) of
{ok, Listen} ->
?MODULE:gen_accepts(50,Listen)
end,
?MODULE:supervisor_loop(Listen).
supervisor_loop(LS) ->
receive
_ -> ok
after 60000 -> ok
end,
?MODULE:supervisor_loop(LS).
gen_accepts(0,_) -> ok;
gen_accepts(I,LS) ->
spawn(?MODULE,accept_loop,[LS]),
?MODULE:gen_accepts(I-1,LS).
accept_loop(Listen) ->
case gen_tcp:accept(Listen) of
{ok, Sock} ->
spawn(?MODULE,accept_loop,[Listen]),
?MODULE:process_sock(Sock);
{error,_} -> ?MODULE:accept_loop(Listen)
end.
现在所有?MODULE:process_sock(Sock)确实发送一些文本并关闭连接,没有IO或任何东西。然而,当我在其上运行apache benchmark(ab)时,我会得到大约1/5的结果:
Percentage of the requests served within a certain time (ms)
50% 3
66% 3
75% 4
80% 4
90% 271
95% 271
98% 271
99% 271
100% 271 (longest request)
总共有20个请求,并发级别为20.所以基本上我一次发出了20个请求。正如您所看到的,大多数请求在很短的时间内完成,但是一两个请求需要很长时间。当我加载时,最长的请求可能最多3秒,我见过的最高请求是9!
我做了一些调试,发现问题出在接受代码中。我计算从process_sock开始到结束需要多长时间并且发现它永远不变,但是当我将计时器的启动移动到gen_tcp:accept之前时,可以看到时间差。由于某种原因,接受不接受。我尝试增加最初生成的接受器数量,并尝试使用不同的设计模式来生成process_sock工作器,但没有任何变化。我应该注意,现在我从50个接受者开始,但是在上面的ab输出中只有20个请求,所以我不认为工人的数量是答案。
我正在运行erlang R14B04,如果有帮助的话。
答案 0 :(得分:3)
{backlog,integer()} 是否设置为?TCP_OPTS中的合理数字?默认为5,如果是,则可能会丢失连接积压的速度不够快。