Обзор Akka.NET: как проектировать IoT-системы с помощью этой библиотеки

Всем привет! Меня зовут Влад Медведовский, и я уже 10-й год работаю в сфере IT. Начинал как разработчик .NET, впрочем удалось поработать и с С++, и с JVM-языками — Scala и Java. Сейчас я тимлид в команде .NET. За свою карьеру видел немало проектов в различных доменах. Например, строительство, медицина, SCADA-системы и IoT. Про IoT мы сейчас и поговорим: рассмотрим традиционные подходы к проектированию IoT-систем и альтернативы, возможности библиотеки Akka.NET и реальный пример ее применения.

Вообще IoT и .NET — это слова, которые редко стояли рядом до недавних пор. Но с развитием Azure-сервисов среди них появились и такие, как, например, IoT gateway. И теперь есть возможность строить решения для IoT на платформе .NET. К Azure есть ряд вопросов, а именно:

  • Итоговая стоимость обслуживания решения. На начальных этапах она не высока, но с ростом нагрузки и количества устройств стоимость будет расти. Не всегда у заказчика есть на это бюджет.
  • На предприятиях уже есть сетевая инфраструктура, и не всегда целесообразно (и возможно) переносить ее в облако.
  • Иногда данные с устройств нельзя хранить в публичном облаке, если они представляют собой конфиденциальную информацию — привет, GDPR :)
  • Некоторые устройства не поддерживают популярные протоколы типа MQTT, зато предоставляют свой уникальный протокол. Еще лучше, если устройство не поддерживает TCP-транспорт и push-модель, а, например, пишет какие-то файлы на FTP-сервер. В таком случае приходится периодически опрашивать FTP на предмет наличия новых данных.

Если вы только собираетесь проектировать IoT-решение или столкнулись с какой-то из проблем, обозначенных выше, а может, вас не устраивают готовые Azure-сервисы — добро пожаловать.

Традиционные подходы для решения IoT-задач

Из каких основных частей состоит решение для IoT? Обычно, если опустить cross-cutting concerns вроде авторизации, мониторинга и логирования, то это:

  • IoT-устройство;
  • gateway;
  • business logic API.

Никакое IoT-решение не существует без устройств, которые взаимодействуют с физическим миром. Обычно IoT-устройства проектируют автономными, а это накладывает ограничения на мощность передатчика. Поэтому для группы устройств часто добавляют стационарный gateway, в которого таких ограничений нет.

Gateway — шлюз, который обрабатывает запросы от конечных устройств. Он не только выполняет функцию ретрансляции, но и разбирает протокол, понятный API/бэкенду и по которому общается оконечное устройство, на команды. Бэкенд, в свою очередь, содержит код, что обычно реализует все бизнес-правила системы.

Для наиболее распространенных сценариев в Azure есть набор готовых сервисов. Из них можно собрать архитектуру, которая представлена на рисунке 1.

Рис. 1. Эталонная архитектура IoT-решения, по мнению Microsoft Docs

Ряд основных недостатков такой архитектуры:

  • сложности, связанные с интеграцией и развертыванием каждой подсистемы;
  • необходимость контроля версий различных подсистем и их совместимости между собой;
  • необходимость иметь raytracing для отладки;
  • необходимость иметь развитую систему мониторинга для наблюдения за отдельными компонентами системы и системой целиком;
  • «зоопарк» используемых сервисов и API в проекте:
    • повышает порог входа для новичков;
    • требует ведения документации, чтобы знания об архитектуре не потерялись.

Устранение хотя бы некоторых из вышеперечисленных недостатков требует определенного уровня навыков и дисциплины в команде. Мой опыт говорит, что это присутствует не всегда и не везде. Иногда вмешиваются дедлайны, иногда нужно инвестировать время и деньги в обучение разработчиков. Эти ресурсы (время и деньги) тоже доступны не всегда.

Акторы

Какие же существуют альтернативы подходам, построенным вокруг сервисов и традиционного слоеного подхода к проектированию IoT-систем? Попробуем представить каждое устройство или вообще каждую сущность системы как отдельный объект, который будем называть актором.

Более того, так как речь идет об устройствах, мы можем добавить ряд естественных ограничений на взаимодействие между акторами.

Акторы не могут напрямую вызывать методы друг друга. В реальности устройства используют асинхронную сеть для различного рода коммуникаций (P2P, Client-server). Вместо этого коммуникация осуществляется посредством обмена сообщениями.

IoT-устройства довольно ограничены в вычислительных мощностях. Поэтому мы можем рассматривать каждый актор как однопоточный. Это означает, что он может обрабатывать только одно сообщение в каждый момент времени.

У каждого актора должен быть уникальный адрес для коммуникации. Без него невозможно доставить сообщение тому адресату, которому оно предназначалось.

Акторы должны иметь возможность создавать другие акторы. Например, для сценария обнаружения новых устройств путем broadcast-сообщений внутри сети. Тогда устройство, которое осуществляет broadcasting, будет получать acknowledge-пакеты на свой адрес, а значит, обладать информацией про найденные устройства. В этом случае выглядит естественным, если программная сущность будет создавать дочерние самостоятельно.

Mailbox. Поскольку акторы однопоточные по своей природе, есть смысл ввести для каждого из них некую очередь, в которую будут поступать все входящие сообщения. Такая очередь в терминологии акторов называется mailbox. По умолчанию сообщения из mailbox обрабатываются по принципу FIFO — first in, first out. Однако на практике необходимо некоторые сообщения обрабатывать с повышенным или пониженным приоритетом. Это сообщения тревоги, сообщения об ошибках или о статусе устройства, которые требуют срочной реакции. Например, есть устройства, которые умеют сигнализировать о том, что их пытаются взломать (можно поискать по anti-tampering protection). Очевидно, получение такого сообщения требует быстрой реакции оператора.

Akka.NET

Все вышеперечисленное предоставляет библиотека под названием Akka.NET. Это, по сути, безальтернативная реализация модели акторов в среде .NET. Есть API как для C#, так и для F#.

Краткий список возможностей библиотеки:

  • базовые типы для создания акторов;
  • большое количество готовых типов для обычных задач вроде маршрутизации сообщений, балансировки нагрузки между акторами и так далее;
  • управление mailbox и разные варианты реализации для него;
  • «среда выполнения» для акторов — Actor System;
  • управление именами акторов (впрочем, всегда можно написать что-то свое);
  • удаленный обмен сообщениями с другими акторами по сети;
  • кластеризация системы акторов — возможность запустить приложение из коробки на нескольких машинах;
  • встроенная очередь для dead letter;
  • поддержка DI;
  • поддержка персистентных акторов.

Сразу перечислю некоторые недостатки:

  • Сложная и неочевидная конфигурация библиотеки:
    • не все задокументированные настройки работают;
    • некоторые не работают так, как задумано;
    • некоторые вообще не работают;
  • Непривычные подходы к именованию (dead letters, например) и концепции некоторых сущностей в библиотеке. Не все сразу понятно, документация тоже не всегда помогает. Благо, Akka.NET — это библиотека с открытым исходным кодом и всегда можно взять исходники, собрать из них библиотеку и посмотреть, что там и как внутри происходит.
  • Крутая кривая обучения. Гайд по библиотеке ровно один, плюс есть несколько примеров (которые не всегда рабочие). Документация не всегда исчерпывающая.

Routers and routing

В Akka.NET есть ряд встроенных типов, которые можно использовать для поочередной отправки сообщений группам акторов. Эти типы называют Routers. В библиотеке есть несколько реализаций для самых частых сценариев:

  • Round-robin — последовательная отправка сообщений акторам.
  • Hash key — адресация по ключу в сообщении.
  • Random — адресат выбирается случайным образом.
  • Weighted round robin — то же, что и Round-robin, но с помощью весовых коэффициентов можно настраивать частоту отправки сообщений конкретным адресатам.
  • Broadcast — сообщение отправляется всем акторам из группы.

Akka.NET use case

Перейдем теперь к реальному примеру использования Akka.NET. Есть некоторая система, которая обрабатывает информацию с датчиков. Как уже было сказано, датчики не подключены напрямую к серверу системы из-за довольно скромных возможностей для автономной связи на дальние расстояния и особенностей топологии их размещения.

Информация с оконечных устройств поступает в систему через стационарные шлюзы.

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

Добавим в эту иерархию актор, который будет обрабатывать ошибки оконечных устройств — между шлюзом и датчиком. Он будет периодически опрашивать датчик на предмет его состояния и отправлять команду перезагрузки, если что-то с оконечным устройством не так. Добавим также актор над шлюзом, который возьмет на себя управление нестабильным TCP-соединением и будет заниматься буферизацией, повторной отправкой сообщений от шлюза на сервер при необходимости.

На минутку перестанем добавлять акторы, остановимся и осмотримся. Как видно, основной способ расширения системы — это добавление в нее новых акторов. Они могут брать на себя произвольные функции — как расширение поведения существующих акторов, так и полностью новые сценарии в системе. Это позволяет расширять систему с минимальными затратами на внедрение нового функционала.

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

Устройства производят измерения по команде — погружают измерительный стержень, а затем каким-то образом читают показания. Сами устройства дублируют друг друга (группами по 3) и разделены на две группы. Нет смысла постоянно запрашивать измерения со всех шести датчиков — это нецелесообразно, потому что реактивы не дешевые. Вместо этого мы можем по очереди опрашивать каждую группу и отправлять команду на измерение с помощью Round-robin router.

Рис. 2. Получившаяся иерархия акторов

Это был пример базового сценария использования Akka.NET. Перейдем теперь к более сложному. Естественный вопрос, который хочется задать следующим — как мне масштабировать систему? Как сделать её более отказоустойчивой?

Akka Remoting

Прежде чем затрагивать вопросы про масштабируемость, нужно понять, как акторы на разных физических машинах обмениваются сообщениями. За счет ссылочной прозрачности и асинхронной природы обмена сообщениями в модели акторов легко сделать переход от in-process коммуникации до сетевой. Это принципиально отличает модель акторов от, например, DCOM или RPC (в виде WCF к примеру), где за синхронными вызовами методов стояли асинхронные вызовы по сети.

В Akka.NET уже есть расширение для обмена сообщениями — Akka.Remoting. Что умеет Akka.Remoting:

  • отправлять сообщения на удаленные акторы;
  • развертывать акторы удаленно (на принимающей стороне);
  • есть возможность расширения для поддержки других сетевых протоколов, не только TCP и UDP.

Важные замечания при использовании Akka.Remoting

При использовании Akka для сетевой коммуникации важно ДО того, как проект начинает разрастаться, продумать, как будут сериализоваться сообщения.

Сериализатор практически невозможно поменять после того, как ваш проект достигнет определенных размеров. Вам нужно будет поддерживать две параллельные копии системы с разными сериализаторами для апгрейда — Akka.NET (впрочем, как и любая другая распределенная система) не сможет десериализовать сообщения, если они были упакованы другим способом. Никакой метаинформации про тип транспортного протокола с сообщениями не передается. Впрочем, всегда можно написать свой сериализатор, который будет абстракцией над механизмом сериализации.

Akka Cluster

Если мы хотим объединить множество акторов, размещенных на разных машинах, в один логический кластер, то для этого существует специальное расширение — Akka.Cluster. Оно реализует логику работы кластера акторов поверх Akka.Remoting. Поговорим о том, как работает кластер в Akka.NET. Для работы кластера акторов необходимо, чтобы выполнялись следующие ограничения.

На каждой машине система акторов (ActorSystem) должна иметь одинаковое название. Не обязательно, чтобы в каждой системе был один и тот же набор акторов, важно именно название. Название системы принимает участие в построении адреса к актору внутри кластера.

В кластере обязательныо должны присутствовать seed nodes. Akka.Cluster реализован поверх протокола Gossip (рис. 3). Назначение протокола — в per-to-peer обмене информацией между узлами сети или, в нашем случае — информацией о машинах в кластере. Сам по себе протокол никак не регламентирует добавление новых участников сети в кластер. Чтобы обойти это, в Akka.Cluster есть seed nodes — это точки входа в кластер. Они указываются как доменные имена/адреса узлов в соответствующей секции конфигурационного файла приложения. Если в кластере нет seed node или она вышла из строя, то новые машины не смогут присоединиться к кластеру. Поэтому имеет смысл держать 2 и более seed nodes для обеспечения отказоустойчивости кластера.

Рис. 3. Схема работы Gossip протокола (рисунок из документации)

Akka.NET use case — cluster

Вернемся к нашему примеру. В реальности датчики довольно старые. Каждая группа датчиков была подключена к х86-устройству с Windows для считывания показаний через COM-порт. До внедрения решения поверх акторов сотрудниками предприятия вручную совершался обход и собирались файлы с информацией от датчиков. Немного расширяем схему с рисунка 2 и получаем:

Рис. 4. Кластер из измерительных устройств

Единственное отличие от предыдущего примера — в схеме появились at-least-once delivery акторы, которые отвечают за гарантированную доставку сообщений на центральный сервер. Для их реализации были взяты персистентные акторы из Akka.NET, немного модифицированы для использования оперативной памяти в качестве хранилища отправленных/доставленных сообщений.

В итоге благодаря Akka.NET получилось построить простое и понятное IoT-решение для Legacy-устройств с поддержкой масштабирования, если вдруг это понадобится в будущем. От базового варианта, который работал на одном сервере, без особых усилий получилось перейти к распределенному решению, которое уже можно разворачивать в кластере. При этом акторы, которые отвечают за бизнес-логику, остались неизменны — добавление обмена сообщениями между ними по сети никак не повлияло на первоначальный пример.

Выводы

Akka.NET — это неплохая альтернатива конвенциональным подходам для построения распределенных систем. Из коробки вы получаете большое количество расширяемой и модифицируемой функциональности. Модули в библиотеке достаточно независимы друг от друга. Используя предоставляемую функциональность как фундамент, можно ускорить разработку IoT-решения и упростить его поддержку. К тому же базовые концепции библиотеки довольно простые, и при правильном подходе к разделению ответственности между акторами можно построить легко расширяемую систему.

Полезные ресурсы:

LinkedIn

36 комментариев

Подписаться на комментарииОтписаться от комментариев Комментарии могут оставлять только пользователи с подтвержденными аккаунтами.
Akka.NET

Все вышеперечисленное предоставляет библиотека под названием Akka.NET. Это, по сути, безальтернативная реализация модели акторов в среде .NET. Есть API как для C#, так и для F#.

Авторо про проект MS Orleans нічого не чув?
ну для ознайомлення ось свіженьке
habr.com/ru/post/498326
habr.com/ru/post/499188

Тут чуть ниже тред про Orleans, почитайте, там понятно, почему Orleans не всегда подходит. TL;DR: у них разные объектные модели, akka более низкоуровневая. Orleans предоставляет только вируальные акторы. Где и какие акторы хостить, выбора у Вас нет

Где и какие акторы хостить, выбора у Вас нет

Есть. Каждому типу актора можно задать либо локальный, либо рандомный, либо load-balanced, либо кастомный деплоймент (в этом случае на вход подаётся пачка идентификаторов адресов Silo, и Ваш алгоритм сам выбирает, на какой деплоить). Также Вы можете просто добавить в сборку конкретных Silo только только те реализации акторов, которые хотите инстанцировать именно там.

Пользуясь случаем, поделюсь своей статьёй по теме (в которой, вероятно, тоже есть неточности, но тем не менее).

Спасибо, выглядит очень похоже на то, что уже есть в akka.net. Смущают только ограничения, связанные с изменениями в конфигурации кластера

Ну, я бы не сказал, что это прям ограничения — на самом деле, только

Stateless grains are not supported: all silos in the cluster must support the same set of stateless grains.

Является явным. Стримы не использовал, поэтому не могу сказать.

Connected clients will not be notified if the set of supported Grain Types changed.

Не знаю, как в Акке, но в целом выглядит достаточно очевидно для веб сервисов в целом.

If Silo 4 leaves the cluster, the client will still try to make calls to grain of type E. It will fail at runtime with a OrleansException

Вряд ли какая-то бизнес-логика обрабатывает такой кейс без последствий, ведь наша цель обратная — добиться отказоустойчивости. Если единственный экземпляр условного API отвалился, то вызовы к нему по-любому будут падать; в то же время мы не ожидаем от API сообщений «такой-то эндпойнт умер» (отдельный актор можно по аналогии сравнить, наверное, только с ним). Rule of thumb для распределённых систем — минимум 2 инстанса на сервис по дефолту и автоскейл.

If the client was connected to the cluster before Silo 4 joined it, the client will not be able to make calls to grain of type E. It will fail will a ArgumentException

Опять же, аналогично любому веб сервису).

Не знаю, как в Акке, но в целом выглядит достаточно очевидно для веб сервисов в целом.

В Акке нет понятия Grain Type, ты просто шлешь сообщения по какому-то адресу. Причем можно послать в прицнипе любое сообщение по любому адресу, вопрос только в том, будет ли оно обработано. Соответственно, никаких уведомлений об изменениях типа там не нужно.

Вряд ли какая-то бизнес-логика обрабатывает такой кейс без последствий, ведь наша цель обратная — добиться отказоустойчивости. Если единственный экземпляр условного API отвалился, то вызовы к нему по-любому будут падать; в то же время мы не ожидаем от API сообщений «такой-то эндпойнт умер» (отдельный актор можно по аналогии сравнить, наверное, только с ним).

В Akka есть dead letter queue, в которую падают все не обработанные сообщения. Можно процессить ее. Но вообще, это вопрос различия в идеологии Akka и Orleans. Мои мысли на этот счет чуть ниже.

Опять же, аналогично любому веб сервису).

В отличии от любого веб сервиса, Ваш код не упадет при отправке сообщения (или во время отправки). Акка предлагает другую ментальную модель — вы не оперируете понятием запрос/ответ (так, как это работает в Orleans, например):

// example of calling grains from the initialized client
            var friend = client.GetGrain<IHello>(0);
            var response = await friend.SayHello("Good morning, my friend!");
            Console.WriteLine("\n\n{0}\n\n", response);

Пример из оф. документации. В примере мы ждем ответа от Grain. И, если я правильно понял, упадем, если Grain, в которому мы шлем запрос, выпал из кластера. В Akka нет понятия «ответ» :). Мы можем получить обратно какое-то сообщение в ответ на то, которое мы отправили. А можем и не получить. Это заставляет проектировать системы не как обычные веб сервисы, где преимущественно используется парадигма «запрос-ответ».

Мы можем получить обратно какое-то сообщение в ответ на то, которое мы отправили. А можем и не получить. Это заставляет проектировать системы не как обычные веб сервисы, где преимущественно используется парадигма «запрос-ответ».

Т.е. в Akka всё асинхронно, и по сути обращения к акторам являются аналогом работы с очередями? И фактически ответ приходит потом в виде сообщения в другую очередь, а сразу после обращения к актору мы ничего не получаем синхронно?

Именно так. Есть, правда, метод, который таки умеет получать ответ в точке вызова, но на самом деле там под капотом тоже создается актор, который сидит и ждет ответа: Ask

Пример из оф. документации. В примере мы ждем ответа от Grain. И, если я правильно понял, упадем, если Grain, в которому мы шлем запрос, выпал из кластера. В Akka нет понятия «ответ» :).

Можно просто не await-тить таску в ответе от grain и будет тоже самое, что tell в акке

В Акке нет понятия Grain Type, ты просто шлешь сообщения по какому-то адресу. Причем можно послать в прицнипе любое сообщение по любому адресу, вопрос только в том, будет ли оно обработано. Соответственно, никаких уведомлений об изменениях типа там не нужно.

Никому не надо пулять сообщения «вникуда» как минимум у них должен быть получать — эту задачу решает абстракция виртуальных акторов куда лучше чем в низкоуровневом апи акки. То что orleans дает высокоуровневый апи и менеджит акторы, lifecycle, failures, scaling — это достоинство, а не недостаток, который вы почему-то упорно ищите. На выходе работы с аккой ожидаемый результат в большинстве случаев пожалуй такой же как даст orleans из коробки, без необходимости заниматься низкоуровневым кодингом.

Никто не ищет никакие недостатки. Тут просто обсуждаются разные варианты, как можно реализовать модель акторов. Это как с ORM — кто-то выбирает EF, а кому-то и Dapper подходит для решаемых задач.

Можно просто не await-тить таску в ответе от grain и будет тоже самое, что tell в акке

Для этого есть специальный атрибут OneWay, который делает отдельные методы, в которых нам не нужен ответ, fire-and-forget. Правда, в доках эта фича вроде до сих пор не описана.

Это все хорошо, я акку щупал, но так и не понял, как бы сделать масштабирование наименее геморройно. Ну типа кубернетес поднял новый под с пачкой акторов и чтобы их подцепить в общий оркестр, а степень лигаси IoT — дело десятое.

А само по себе так не заводится что ли?

пару лет назад смотрел, надо было каждую ноду в конфиге прописывать и подобные танцы с бубном.

Да, что-то такое вспоминается. Вообще в k8s к каждому поду можно доступиться по имени, т.е. под, зная свое имя, может зарегаться в кластере при старте. По крайней мере я бы это так решал для Proto.Actor.

В akka.cluster каждую не надо, только seed — их обычно штуки 3 всего, и можно указать какие-то well-known IP’s или доменные имена, а еще можно и seed спрятать за load-balanced IP или доменом и собрать из seed нод кластер

Ну и масштабирование так примерно и работает, на машине поднимаешь actor system с seed nodes, дальше оно само

Акка и наименее геморройно это это вещи мало совместимые. Она же даже из коробки сплитбрейн не умеет разруливать, да и актёрский летиткраш не склоняет к простому коду. Наименее геморойно — какой-нибуть месседжбас и стейтлес обработчики, естественно модель акторов тут не очень хорошо с этим сочетается.

Чего, вот их дока на эту тему. Вполне себе разруливание сплитбрейн из коробки

Это, по сути, безальтернативная реализация модели акторов в среде .NET.
Ну, нет. Есть еще, как минимум, такой вариант — dotnet.github.io/orleans.

Спасибо, тут чуть ниже тред на эту тему

Не за что :). Да, вижу и с интересом читаю. У меня почему-то при первой загрузке комментарии не подтянулись. Увидел их после того как добавил свой.

Akka.NET. Это, по сути, безальтернативная реализация модели акторов в среде .NET.

Есть orleans и еще есть actor сервисы в Service fabric(те же виртуальные акторы);

Спасибо, vlingo судя по оф. сайту вообще для JVM (в статье рассматривается .NET), а proto.actor выглядит как альтернатива, но доки явно еще сырые и далеко не полные, например раздел Grains был пустой на момент просмотра

github.com/vlingo-net. Proto.actor мне очень нравится, но не знаю насколько стремительно он развивается, за ним нет большой компании. Знаю несколько компаний, которые используют его в проде.

А можно поинтересоваться, чем именно нравится? АПИ и доменные термины либы, судя по докам, выглядят как микс моделей Orleans + Akka

Айюхенная штука, на самом деле. Довольно простая библиотека по сравнению с тем, что наворотили в Akka. В Proto.Actor используются стандартные проверенные интрументы типа protobuf для сериализации, gRPC для общения, стандартная серализация ThreadPool для работы с моногопоточночтью и асинхронностью, Consul для регистрации акторов и работы с кластером, consistent hashing для поиска акторов. Внутренности лекго понять и можно дорабатывать если чего-то не хватает. Нет привязки к базовым классам внутри акторов, можно актор строить как нравится, pattern matching для обработки сообщения, а не регистрация хендлеров в базовом классе, например. Если интересно поиграться, думаю, понравится. Но я его уже больше года не трогал. И не знаю какие у них планы по его развитию. Поэтому для небольшого проекта я бы его использовал, но в долгую не уверен можно ли его брать в плане развития проекта. Хотя, то, что там есть стабильно.

Рождер недавно в твиттере написал, что ищет новую работу, может там найдется место для Proto.Actor и проект будет развиваться более стремительно, посмотрим.

В Orleans давно не заглядывал, не знаю что там к чему сейчас.

Спасибо, обязательно гляну. Один из минусов Akka, на мой взгляд — это чрезмерная любовь к велосипедам. Хотя все эти велики можно повыдергивать и заменить, но это не бесплатно конечно же. Особенная боль — это сериализация сообщений

Спасибо, про orleans слышал, но у него подход и объектная модель отличаются от akka.net, в первую очередь наличием silo, и отличиях между акторами и grains (из последних нельзя собрать иерархию и у grain отличается жизненный цикл от актора).

Спасибо за статью. Не совсем понятно про какие иерархии идет речь, вроде в Orleans все можно: github.com/...​del with Orleans v1.1.pdf

Спасибо за комментарий, в публикации по вашей ссылке ничего не нашел похожего на ту иерархию, которую можно создать в Akka, с deathwatch или роутером например (возможно потому, что как минимум за роутинг в orleans отвечает среда выполнения)

Sevice Fabric может не подойти, если есть требование хоститься на уже существующем on-premise железе.

Service fabric инсталится куда угодно.
Но если вам не подошли виртуальные акторы, то это тоже не подойдет.
А что за задачи были такие что не подошло взять готовое?
Роутинг и child акторы — впринципе реализуемо на orleans с учетом того, что lifetime менеджит кластер — то все выглядит просто.

Задачи были примерно как в статье описано — нужен был explicit lifetime management иерархии устройств, которые передают данные. в Orleans из коробки нет иерархии, и это стало решающим фактором. Плюс уже был опыт работы с akka.net.
Реализовать можно что угодно и на чем угодно, вопрос только в бюджете заказчика и наличии времени

Подписаться на комментарии