Я думаю, что проблема здесь не в потреблении памяти, а в самом подходе к рабочему процессу.
Из того, что вы говорите, я могу предположить, что вы извлекаете сообщения из MSMQ, немедленно пересылаете их рабочим, а затем извлекаете дополнительные данные, не дожидаясь, пока рабочие фактически закончат свою работу. Это традиционная проблема с потоком данных, основанным на проталкивании, без прикрепленного механизма обратного давления.
Самый простой способ решить эту проблему - изменить поток данных на модель на основе извлечения - в этом случае действующий координатор не будет пытаться извлекать данные из MSMQ, если только один из рабочих не уведомил его о том, что они закончили свою работу и ждут больше данных (в этом случае вам не нужно будет размещать их также за маршрутизатором). Уведомление может быть выражено как сообщение, отправляемое работником, когда он заканчивает обработку текущего сообщения. Недостатком этой модели является то, что у вас будут бездействующие работники, ожидающие выбора сообщений MSMQ.
Более продвинутые концепции включают модель, управляемую спросом (противодавление), в которой может использоваться буферизация сообщений, поэтому вы можете предварительно выбрать некоторое количество данных, а затем пополнить их во время их обработки. Кроме того, таким образом ни один рабочий не будет простаивать, ожидая, пока координатор выберет следующее сообщение из очереди. Подробнее об идее концепции противодавления можно прочитать здесь.
PS: Как только выйдет модуль Akka.Streams, вы получите встроенные механизмы, которые работают со встроенными принципами обратного давления.
person
Bartosz Sypytkowski
schedule
30.04.2016