Erlang: странное отставание при приеме соединений - PullRequest
4 голосов
/ 19 ноября 2011

Я поиграл с игрушечным веб-сервером, который я создал, поместив его под большую нагрузкуЯ считаю, что это работает очень хорошо, за исключением нескольких выбросов.Вот соответствующий код:

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.

Прямо сейчас все? МОДУЛЬ: process_sock (Sock) делает, это отправляет некоторый текст и закрывает соединение, нет ввода-вывода или что-то еще.Когда я запускаю 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, если это поможет.

1 Ответ

3 голосов
/ 19 ноября 2011

Установлено ли {backlog, integer ()} разумное число в вашем ? TCP_OPTS? По умолчанию 5, и вы можете потерять соединения в конце, если отставание не недостаточно быстро очищается.

...