Как системы Actor функционируют для предотвращения переполнения памяти в очередях, а также для предотвращения блокировки потоков при записи в очереди? - PullRequest
1 голос
/ 10 января 2020

Актеры отправляют сообщения друг другу. Если очереди ограничены, что происходит при попытках записи / отправки в полные очереди? Блокировка или сброс? Если они не ограничены, возможна память cra sh. Сколько можно настроить?

Ответы [ 4 ]

2 голосов
/ 13 января 2020

Почтовые ящики по умолчанию в Akka не ограничены, поэтому не помешают памяти cra sh. Однако вы можете настроить актеров для использования разных почтовых ящиков, среди которых есть как почтовые ящики, которые отбрасывают (переходят на мертвые буквы) сообщения при достижении максимального размера, так и те, которые блокируют (я бы не рекомендовал их использовать). Вы можете найти все реализации почтовых ящиков, которые поставляются с Akka, в документации здесь: https://doc.akka.io/docs/akka/current/typed/mailboxes.html#mailbox -implementations

1 голос
/ 14 января 2020

Почтовые ящики по умолчанию в Akka не ограничены. Но если вы хотите ограничить максимальное количество сообщений в почтовых ящиках, вы можете создать поток Akka в актере, тогда по требованию может использоваться OverflowStrategy.

Например:

val source: Source[Message, SourceQueueWithComplete[Message]] =
    Source.queue[Message](bufferSize = 8192,
      overflowStrategy = OverflowStrategy.dropNew)

1 голос
/ 12 января 2020

очередь актера в erlang не имеет ограничений, это ограничено объемом памяти виртуальной машины, если объем памяти в виртуальной машине заполнен, сбой виртуальной машины. для монитора или управления распределением памяти и загрузки процессора вы можете использовать os_mon в Erlang

, вы можете протестировать в оболочке erlang

F = fun() -> timer:sleep(60000),
             {message_queue_len, InboxLen} = erlang:process_info(self(), message_queue_len),
              io:format("Len ===> ~p", [InboxLen]) 
    end.
PID = erlang:spawn(F).
[PID ! "hi" || _ <- lists:seq(1, 50000)].

, если вы увеличите количество сообщений, которое вы может переполнить память

1 голос
/ 12 января 2020

Вы можете легко проверить поведение Erlang VM в этой ситуации. В оболочке:

F = fun F() -> receive done -> ok end end,
P = spawn(F),
G = fun G(Pid,Size,Wait) -> Pid ! lists:seq(1,Size), receive done -> ok after Wait -> G(Pid,Size,Wait) end end,
H = fun(Pid,Size,Wait) -> T = fun() -> G(Pid,Size,Wait) end, spawn(T) end,
D = fun D() -> io:format("~p~n~p~n",[erlang:time(),erlang:memory(processes_used)]), receive done -> ok after 10000 -> D() end end,
P1 = spawn(D).

P2 = H(P,100000,5).

Вы увидите, что вы получаете исключение выделения памяти, виртуальная машина записывает дамп ядра и вылетает.

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

Если вы когда-нибудь попадете в такую ​​ситуацию, я не думаю, что первое Реакция заключается в увеличении размера, вам нужно сначала поискать

  • непрочитанных сообщений,
  • узкое место процесса
  • архитектура приложения
  • адаптировано для Erlang ваша проблема
  • ...
...