Отправка запроса в ASP.Net Core Web API, работающий на определенном узле в кластере Service Fabric

Я работаю над приложением Service Fabric, в котором я запускаю свое приложение, которое содержит несколько основных веб-API ASP.NET. Теперь, когда я запускаю свое приложение в своем локальном кластере сервисной фабрики, который настроен на 5 узлов, приложение работает успешно, и я могу отправлять запросы по почте в открытые веб-API. На самом деле я хочу поразить код, работающий на одном и том же узле кластера, с различными запросами на публикацию к открытым API на этом конкретном узле.

Для дальнейшего объяснения, например, существует API, представленный на узле '0', который принимает запрос на публикацию и выполняет задание, а также есть API, который прерывает запущенное задание. Теперь, когда я запрашиваю выполнение задания, оно начинает выполняться на узле "0", но когда я пытаюсь прервать задание, кластер сервисной фабрики перенаправляет запрос на другой узел, например, скажем, на узел "1". В результате я не смог прервать работающее задание, потому что на узле '1' нет доступного запущенного задания. Я не знаю, как справиться с этой ситуацией.

Для состояний я использую службу без сохранения состояния типа ASP.Net Core Web API и запускаю приложение на 5 узлах моего локального кластера сервисной фабрики.

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

2 ответа

Решение

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

Вы должны использовать свой API для планирования работы в фоновом режиме (Process\Worker) и вернуть пользователю токен или идентификатор операции. Пользователь будет использовать этот токен для запроса статуса или отмены задания.

Первый шаг: когда вы вызываете свой API в первый раз, вы можете сгенерировать GUID(или вставить в БД) и поместить это сообщение в очередь (т. Е. Служебную шину), а затем вернуть GUID вызывающей стороне.

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

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

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

Третий шаг, отмена: процесс отмены прост, и есть много подходов:

  • Используя аналогичный подход и поставить в очередь сообщение об отмене
    • Ваш сервис будет прослушивать отмену в отдельном потоке и отменять запущенное задание (если выполняется).
    • Лучше использовать другую очередь для отправки сообщений об отмене
    • Если запущено несколько экземпляров прослушивателя, вы можете рассмотреть тему вместо очереди.
  • Использование ключа кэша для хранения статуса задания и проверки на каждой итерации, запрашивается ли отмена.
  • Таблица со статусом задания, где вы проверяете каждую итерацию, как если бы вы использовали ключ кеша.
  • Создание удаленной конечной точки для прямого вызова службы и запуска токена отмены.

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

Вам понадобится немного памяти, чтобы сделать это.

Создать таблицу (например, JobQueue). Перед началом обработки задания вы сохраняете в базе данных, сохраняете статус (например, " Выполняется", это может быть перечисление), а затем возвращаете идентификатор вызывающей стороне. Как только вам нужно прервать / отменить задание, вы вызываете метод abort из API, отправляя идентификатор, который хотите прервать. В методе прерывания вы просто обновляете состояние задания до " Прервать". Внутри первого метода (который запускает задание) вам нужно будет некоторое время проверять эту таблицу, если она прерывается, то вы останавливаете задание (и обновляете статус до Aborted). Или вы можете просто удалить из базы данных, как только работа была прервана или завершена.

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

Другие вопросы по тегам