Протягом останнього тижня я занурився у розробку програмного забезпечення, досліджуючи концепцію віртуальних акторів. Я зрештою розглянув два різні фреймворки: Dapr і Orleans.
Обидва проєкти дуже лаконічні з безліччю цікавих сценаріїв використання. Обидва використовують ідею «віртуальних» акторів. Віртуальний актор — це одиниця стану та логіки, яка:
- Його можна унікально ідентифікувати за ID
- Він однониток
- Може бути в пам'яті або постійним — його життєвий цикл керується фреймворком
Мені дуже подобається ідея віртуальних акторів, і я вважаю їх дуже корисними у дослідженні створення масштабованих і надійних інструментів для виконання складних робочих процесів. Якщо кожне завдання є однопотоковим віртуальним учасником, проблема умов раси зникає.
Оскільки Orleans і Dapr — обидва проєкти Microsoft, я уявляю собі день у стилі Western Story протистояння в кафетерії Microsoft.
Орлеані
Я почав з Orleans, бо він вже деякий час у мене на радарі після перегляду відео на YouTube. Все почалося дуже погано, бо я думав, що буду використовувати 4.x версію всіх їхніх пакетів NuGet. Однак жодна з їхніх документацій не працює з пакетом 4.x. Я врешті-решт використав версію 3.6.2.
Зерна / Стан / Таймери
Створити зерно, яке відстежує власний стан і виконує дії, дуже просто. Я навіть зміг виконати документацію щодо збереження зерен і створити власну реалізацію IGrainStorage у CosmosDB (SQL API).
Нагадування
Нагадування також легко встановити. Поки не спробував налаштувати для них реальну стійкість. На цьому етапі мого дослідження я намагаюся тримати все в порядку і зберігати все в ComsosDB. На жаль, я взагалі не можу змусити пакет нагадувань Orleans працювати. Врешті-решт мені довелося перейти на пакет AzureStorage. Тепер мої дані наполовину знаходяться в обліковому записі SQL API, а наполовину — в обліковому записі таблиці API.
Потоки
Ось тут у мене не вийшло. В Орлеані потоки ідентифікуються за допомогою GUID та опціонального простору назв. Я впевнений, що є вагома причина, чому потоки мають ідентифікуватися за допомогою GUID, але це непрактично.
Я дуже розчарований через потоки, бо міг легко їх створити, але як тільки я зупиняюся, перезапускаю проєкт і запускаю нову подію, все вилітає.
Далі йде дуже цінна інформація, адже мені знадобилося 8 годин, щоб розібратися з кодом Орлеана і розібратися:
Коли grain є підписником потоку, grain повинен викликати ResumeAsync на дескрипторі підписки у своєму методі OnActivateAsync, інакше ви зазнаєте аварію через невизнану помилку.
У мене також була проблема з дублюванням однієї й тієї ж підписки, тому я використав код, щоб видалити всі підписки на зерна, а потім відтворив її заново:
Інші орлеанські готчі / поради
Streams добре працює з Azure Event Hubs (через AddEventHubStreams).
Не використовуйте / або інші спеціальні символи в назві Grain у CosmosDB SQL API!
Орлеанське завершення
Мені подобається Орлеан, і я вважаю, що він має потенціал. Однак у нього дуже крута крива навчання. Через мою тривалу боротьбу зі стрімінгом у мене немає часу вивчати, як працюють кластери/розгортання.
Dapr
Я знайшов Dapr, шукаючи альтернативи Орлеану. Трохи дивно, що це також проєкт, спонсорований Microsoft. Можливо, вони тут, щоб застосувати підхід виживання найсильніших. Якщо так, думаю, Dapr буде вижившим.
По-перше, дизайн Dapr на основі REST/gRPC дозволяє реалізовувати акторів на будь-якій мові програмування. Мені також здалося тривіальним запускати все (учасники, статуси, таймери, нагадування, події) в одному Redis-інстансі. До того ж, мені знадобилося лише близько третини часу, щоб почати користуватися Dapr. Такий швидкий час запуску зумовлений відмінною документацією Dapr.
Актори / Таймери / Нагадування
Я щойно сказав, що документація Dapr чудова? Ну, це всюди, крім прикладів JavaScript. Я більшість часу проводжу на Dapr, намагаючись зрозуміти, як викликати методи для акторів. Код для зразка Dapr Javascript виглядає так:
Це явно застаріло. Мені довелося витратити багато часу, щоб провести ці три рядки через тестове/дослідження зразків коду Dapr
Приклади коду для отримання стану мають схожі проблеми, тому я створив для них проблему на GitHub.
Окрім цих дрібних проблем, підлаштувати акторів — це легко.
Встановлювати таймери та нагадування для мого заклинання також дуже просто.
Стан
Мені вдалося дуже легко налаштувати Dapr для збереження з Postgres.
Одне, що я помітив — можуть виникати проблеми з масштабованістю зберігання нагадувань. Dapr зберігає всі сповіщення для певного типу учасника в одному масиві JSON. Що відбувається, якщо у когось багато нагадувань?
Інші Dapr Gotcha / Поради
Одне, що я помітив під час перегляду коду JavaScript SDK — у коді майже немає коментарів. Через це майже неможливо щось з'ясувати. Наприклад, у методі addOrUpdateState менеджера стану існує третій параметр під назвою updateValueFactory. Якщо в коді немає коментарів, майже неможливо зрозуміти, для чого потрібна зворотна відповідь.
Я також не впевнений, наскільки мені подобається команда "dapr init", яка намагається налаштувати та запустити контейнер Redis для мене. А що, якщо у мене вже є контейнер Redis? А якщо я захочу використати postgres замість цього? Я не можу знайти документацію, яка пояснює, як змінити функцію DAPR init.
Примітка для тих, хто має труднощі з використанням pubsub. Ви повинні використовувати «dapr run» для роботи як видавця, так і підписника:
Для акторів і pubsub важливо використовувати параметр --app-port, щоб dapr знав, на якому порту працює ваш сервіс. pubsub події та акторні виклики надсилаються на ваш сервіс із сайдкару Dapr через http-виклики, тому він має знати, куди їх надсилати:
Я протестував невеликий власний «кластер» Dapr, запустивши свій Pubsub Subscriber на двох різних машинах у домашній мережі. Це просто спрацювало!
Висновок Dapr
Якщо хочете дізнатися більше ідей про розподілені додатки або віртуальні актори, рекомендую почати з Dapr. Orleans був першопрохідцем, а Dapr — перезапуск, який підняв події на новий рівень.
Оригінальне посилання:Вхід за гіперпосиланням видно.
|