Erlang: weird lag in receiving connections

I played with a toy web server that I built, putting it under heavy load. I find that it works very well, with the exception of a few outliers. Here is the relevant code:

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. 

Is that all now? MODULE: process_sock (Sock) does, sends some text and closes the connection, there is no I / O or anything else. However, when I run the apache (ab) test on it, about 1 to 5 times, I get these results:

 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) 

This was with 20 full queries, with a concurrency level of 20. So basically I made 20 queries at the same time. As you can see, most requests are executed in a very short time, but one or two takes a very long time. When I load the load, the longest request can be up to 3 seconds, the highest that I saw is 9!

I did some debugging and found that the problem is in the receiving code. I calculated how long it took to get from the beginning of process_sock to the end and found that it never changes, but when I moved the timer start just before gen_tcp: accept, then you can see the time difference. For some reason, the reception is not accepted. I tried to increase the number of acceptors generated, and also try different design patterns for spawning process_sock, but nothing changes. I should note that now I start with 50 acceptors, but in the output of ab above, only 20 requests were made, so I do not think that the number of workers is the answer.

I am running erlang R14B04 if this helps.

+4
source share
1 answer

Is {backlog, integer ()} a reasonable number in ? TCP_OPTS? . By default, it is 5, and you can lose connections at the end if the backlog is not cleared quickly enough.

+3
source

Source: https://habr.com/ru/post/1381983/


All Articles