Centra zadań w Durable Functions (Azure Functions)

Centrum zadań w Durable Functions jest reprezentacją bieżącego stanu aplikacji w magazynie, w tym wszystkich oczekujących prac. Gdy aplikacja funkcji jest uruchomiona, postęp orkiestracji, działania i funkcji jednostki jest stale przechowywany w centrum zadań. Gwarantuje to, że aplikacja może wznowić przetwarzanie, w którym zostało wyłączone, jeśli wymaga ponownego uruchomienia po tymczasowym zatrzymaniu lub przerwaniu z jakiegoś powodu. Ponadto umożliwia aplikacji funkcji dynamiczne skalowanie procesów roboczych obliczeniowych.

Diagram przedstawiający koncepcję koncepcji aplikacji funkcji i centrum zadań.

Koncepcyjnie centrum zadań przechowuje następujące informacje:

  • Stany wystąpienia wszystkich wystąpień orkiestracji i jednostek.
  • Komunikaty do przetworzenia, w tym
    • wszelkie komunikaty o działaniach reprezentujące działania oczekujące na uruchomienie.
    • wszelkie komunikaty wystąpień oczekujące na dostarczenie do wystąpień.

Różnica między komunikatami aktywności i wystąpienia polega na tym, że komunikaty o aktywności są bezstanowe i mogą być przetwarzane w dowolnym miejscu, podczas gdy komunikaty wystąpień muszą być dostarczane do określonego wystąpienia stanowego (orkiestracji lub jednostki), identyfikowane przez jego identyfikator wystąpienia.

Wewnętrznie każdy dostawca magazynu może używać innej organizacji do reprezentowania stanów i komunikatów wystąpień. Na przykład komunikaty są przechowywane w kolejkach usługi Azure Storage przez dostawcę usługi Azure Storage, ale w tabelach relacyjnych przez dostawcę MSSQL. Te różnice nie mają znaczenia, jeśli chodzi o projekt aplikacji, ale niektóre z nich mogą wpływać na charakterystykę wydajności. Omówimy je w sekcji Reprezentacja w magazynie poniżej.

Elementy robocze

Komunikaty o aktywności i komunikaty wystąpień w centrum zadań reprezentują pracę, którą aplikacja funkcji musi przetworzyć. Gdy aplikacja funkcji jest uruchomiona, stale pobiera elementy robocze z centrum zadań. Każdy element roboczy przetwarza co najmniej jeden komunikat. Rozróżniamy dwa typy elementów roboczych:

  • Elementy robocze działania: uruchom funkcję działania, aby przetworzyć komunikat działania.
  • Element roboczy programu Orchestrator: uruchom funkcję orkiestratora lub jednostki, aby przetworzyć co najmniej jeden komunikat wystąpienia.

Procesy robocze mogą przetwarzać wiele elementów roboczych w tym samym czasie, z zastrzeżeniem skonfigurowanych limitów współbieżności poszczególnych procesów roboczych.

Gdy proces roboczy zakończy element roboczy, zatwierdza efekty z powrotem do centrum zadań. Te efekty różnią się w zależności od typu wykonywanej funkcji:

  • Ukończona funkcja działania tworzy komunikat wystąpienia zawierający wynik skierowany do nadrzędnego wystąpienia orkiestratora.
  • Ukończona funkcja orkiestratora aktualizuje stan orkiestracji i historię i może tworzyć nowe komunikaty.
  • Ukończona funkcja jednostki aktualizuje stan jednostki, a także może tworzyć nowe komunikaty o wystąpieniu.

W przypadku aranżacji każdy element roboczy reprezentuje jeden odcinek wykonania tej orkiestracji. Odcinek rozpoczyna się, gdy do przetworzenia są nowe komunikaty dla orkiestratora. Taki komunikat może wskazywać, że aranżacja powinna się rozpocząć; lub może wskazywać, że działanie, wywołanie jednostki, czasomierz lub suborchestration zostało ukończone; lub może reprezentować zdarzenie zewnętrzne. Komunikat wyzwala element roboczy, który umożliwia orkiestratorowi przetworzenie wyniku i kontynuowanie następnego odcinka. Ten odcinek kończy się po zakończeniu działania orkiestratora lub osiągnie punkt, w którym musi czekać na nowe komunikaty.

Przykład wykonania

Rozważ orkiestrację fan-out-in, która uruchamia dwa działania równolegle i czeka na ukończenie obu z nich:

[FunctionName("Example")]
public static async Task Run([OrchestrationTrigger] IDurableOrchestrationContext context)
{
    Task t1 = context.CallActivityAsync<int>("MyActivity", 1);
    Task t2 = context.CallActivityAsync<int>("MyActivity", 2);
    await Task.WhenAll(t1, t2);
}

Po zainicjowaniu tej aranżacji przez klienta jest on przetwarzany przez aplikację funkcji jako sekwencję elementów roboczych. Każdy ukończony element roboczy aktualizuje stan centrum zadań po jego zatwierdzeniach. Poniżej przedstawiono procedurę:

  1. Klient żąda rozpoczęcia nowej aranżacji z identyfikatorem wystąpienia "123". Po zakończeniu tego żądania centrum zadań zawiera symbol zastępczy stanu aranżacji i komunikat wystąpienia:

    workitems-illustration-step-1

    Etykieta ExecutionStarted jest jednym z wielu typów zdarzeń historii , które identyfikują różne typy komunikatów i zdarzeń uczestniczących w historii orkiestracji.

  2. Proces roboczy wykonuje element roboczy koordynatora w celu przetworzenia komunikatu ExecutionStarted . Wywołuje funkcję orkiestratora, która rozpoczyna wykonywanie kodu orkiestracji. Ten kod planuje dwa działania, a następnie zatrzymuje wykonywanie, gdy oczekuje na wyniki. Po zatwierdzeniu tego elementu roboczego centrum zadań zawiera centrum zadań

    workitems-illustration-step-2

    Stan środowiska uruchomieniowego to teraz Running, dodano dwa nowe TaskScheduled komunikaty, a historia zawiera teraz pięć zdarzeń OrchestratorStarted, , ExecutionStarted, TaskScheduledTaskScheduled, OrchestratorCompleted. Te zdarzenia reprezentują pierwszy odcinek wykonania tej orkiestracji.

  3. Proces roboczy wykonuje element roboczy działania w celu przetworzenia jednego z komunikatów TaskScheduled . Wywołuje funkcję działania z danymi wejściowymi "2". Po zakończeniu działania tworzy TaskCompleted komunikat zawierający wynik. Po zatwierdzeniu tego elementu roboczego centrum zadań zawiera centrum zadań

    workitems-illustration-step-3

  4. Proces roboczy wykonuje element roboczy koordynatora w celu przetworzenia komunikatu TaskCompleted . Jeśli orkiestracja jest nadal buforowana w pamięci, może po prostu wznowić wykonywanie. W przeciwnym razie proces roboczy najpierw odtwarza historię w celu odzyskania bieżącego stanu aranżacji. Następnie kontynuuje orkiestrację, dostarczając wynik działania. Po otrzymaniu tego wyniku orkiestracja nadal czeka na wynik innego działania, więc po raz kolejny przestaje działać. Po zatwierdzeniu tego elementu roboczego centrum zadań zawiera centrum zadań

    workitems-illustration-step-4

    Historia orkiestracji zawiera teraz trzy kolejne zdarzenia OrchestratorStarted, TaskCompleted, OrchestratorCompleted. Te zdarzenia reprezentują drugi odcinek wykonania tej orkiestracji.

  5. Proces roboczy wykonuje element roboczy działania , aby przetworzyć pozostały TaskScheduled komunikat. Wywołuje funkcję działania z danymi wejściowymi "1". Po zatwierdzeniu tego elementu roboczego centrum zadań zawiera centrum zadań

    workitems-illustration-step-5

  6. Proces roboczy wykonuje inny element roboczy koordynatora w celu przetworzenia komunikatu TaskCompleted . Po otrzymaniu tego drugiego wyniku aranżacja zakończy się. Po zatwierdzeniu tego elementu roboczego centrum zadań zawiera centrum zadań

    workitems-illustration-step-6

    Stan środowiska uruchomieniowego to teraz Completed, a historia aranżacji zawiera teraz cztery kolejne zdarzeniaOrchestratorStarted, , TaskCompleted, OrchestratorCompletedExecutionCompleted. Te wydarzenia reprezentują trzeci i ostatni odcinek wykonania tej orkiestracji.

Ostatnia historia wykonania tej orkiestracji zawiera następnie 12 zdarzeń OrchestratorStarted, ExecutionCompletedTaskCompletedOrchestratorStartedExecutionStartedOrchestratorCompletedTaskCompletedTaskScheduledTaskScheduledOrchestratorCompletedOrchestratorStarted. OrchestratorCompleted

Uwaga

Pokazany harmonogram nie jest jedynym: istnieje wiele nieco różnych możliwych harmonogramów. Jeśli na przykład drugie działanie zakończy się wcześniej, oba TaskCompleted komunikaty wystąpień mogą być przetwarzane przez pojedynczy element roboczy. W takim przypadku historia wykonywania jest nieco krótsza, ponieważ istnieją tylko dwa odcinki i zawiera następujące 10 zdarzeń: OrchestratorStarted, , ExecutionStarted, OrchestratorStartedTaskScheduledTaskScheduledTaskCompletedTaskCompletedOrchestratorCompletedExecutionCompleted, . OrchestratorCompleted

Zarządzanie centrum zadań

Następnie przyjrzyjmy się bliżej sposobom tworzenia lub usuwania centrów zadań, prawidłowego używania centrów zadań podczas uruchamiania wielu aplikacji funkcji oraz sposobu inspekcji zawartości centrów zadań.

Tworzenie i usuwanie

Puste centrum zadań ze wszystkimi wymaganymi zasobami jest automatycznie tworzone w magazynie po pierwszym uruchomieniu aplikacji funkcji.

Jeśli używasz domyślnego dostawcy usługi Azure Storage, nie jest wymagana dodatkowa konfiguracja. W przeciwnym razie postępuj zgodnie z instrukcjami konfigurowania dostawców magazynu , aby upewnić się, że dostawca magazynu może prawidłowo aprowizować i uzyskiwać dostęp do zasobów magazynu wymaganych dla centrum zadań.

Uwaga

Centrum zadań nie jest automatycznie usuwane po zatrzymaniu ani usunięciu aplikacji funkcji. Musisz usunąć centrum zadań, jego zawartość lub konto magazynu zawierające ręcznie, jeśli nie chcesz już przechowywać tych danych.

Porada

W scenariuszu programowania może być konieczne ponowne uruchomienie z czystego stanu często. Aby to zrobić szybko, wystarczy zmienić skonfigurowaną nazwę centrum zadań. Spowoduje to wymusi utworzenie nowego, pustego centrum zadań po ponownym uruchomieniu aplikacji. Należy pamiętać, że stare dane nie są usuwane w tym przypadku.

Wiele aplikacji funkcji

Jeśli wiele aplikacji funkcji współużytkuje konto magazynu, każda aplikacja funkcji musi być skonfigurowana przy użyciu oddzielnej nazwy centrum zadań. To wymaganie dotyczy również miejsc przejściowych: każde miejsce przejściowe musi być skonfigurowane z unikatową nazwą centrum zadań. Pojedyncze konto magazynu może zawierać wiele centrów zadań. To ograniczenie zwykle dotyczy również innych dostawców magazynu.

Na poniższym diagramie przedstawiono jedno centrum zadań na aplikację funkcji na udostępnione i dedykowane konta usługi Azure Storage.

Diagram przedstawiający udostępnione i dedykowane konta magazynu.

Uwaga

Wyjątkiem od reguły udostępniania centrum zadań jest skonfigurowanie aplikacji na potrzeby regionalnego odzyskiwania po awarii. Aby uzyskać więcej informacji, zobacz artykuł dotyczący odzyskiwania po awarii i dystrybucji geograficznej .

Inspekcja zawartości

Istnieje kilka typowych sposobów sprawdzania zawartości centrum zadań:

  1. W aplikacji funkcji obiekt klienta udostępnia metody wykonywania zapytań dotyczących magazynu wystąpień. Aby dowiedzieć się więcej o obsługiwanych typach zapytań, zobacz artykuł Zarządzanie wystąpieniami .
  2. Podobnie interfejs API HTTP oferuje żądania REST w celu wykonywania zapytań dotyczących stanu aranżacji i jednostek. Aby uzyskać więcej informacji, zobacz dokumentację interfejsu API HTTP .
  3. Narzędzie Durable Functions Monitor może sprawdzać centra zadań i oferuje różne opcje wyświetlania wizualnego.

W przypadku niektórych dostawców magazynu można również sprawdzić centrum zadań, przechodząc bezpośrednio do bazowego magazynu:

  • W przypadku korzystania z dostawcy usługi Azure Storage stany wystąpienia są przechowywane w tabeli wystąpień i tabeli historii, które można sprawdzić przy użyciu narzędzi, takich jak Eksplorator usługi Azure Storage.
  • Jeśli używasz dostawcy magazynu MSSQL, zapytania SQL i narzędzia mogą służyć do sprawdzania zawartości centrum zadań wewnątrz bazy danych.

Reprezentacja w magazynie

Każdy dostawca magazynu używa innej organizacji wewnętrznej do reprezentowania centrów zadań w magazynie. Zrozumienie tej organizacji, choć nie jest wymagane, może być przydatne podczas rozwiązywania problemów z aplikacją funkcji lub podczas próby zapewnienia wydajności, skalowalności lub celów kosztów. W związku z tym krótko wyjaśniamy, w jaki sposób dane są zorganizowane w magazynie dla każdego dostawcy magazynu. Aby uzyskać więcej informacji na temat różnych opcji dostawcy magazynu i ich porównywania, zobacz dostawcy magazynu Durable Functions.

Dostawca usługi Azure Storage

Dostawca usługi Azure Storage reprezentuje centrum zadań w magazynie przy użyciu następujących składników:

  • Dwie tabele platformy Azure przechowują stany wystąpienia.
  • Jedna kolejka platformy Azure przechowuje komunikaty o aktywności.
  • Co najmniej jedna kolejka platformy Azure przechowuje komunikaty wystąpień. Każda z tych tak nazywanych kolejek sterowania reprezentuje partycję , która jest przypisana podzestaw wszystkich komunikatów wystąpień na podstawie skrótu identyfikatora wystąpienia.
  • Kilka dodatkowych kontenerów obiektów blob używanych do dzierżawy obiektów blob i/lub dużych komunikatów.

Na przykład centrum zadań o nazwie xyz with PartitionCount = 4 zawiera następujące kolejki i tabele:

Diagram przedstawiający organizację magazynu dostawcy usługi Azure Storage dla 4 kolejek kontrolnych.

Następnie opiszemy te składniki i rolę, jaką pełnią bardziej szczegółowo.

Aby uzyskać więcej informacji o tym, jak centra zadań są reprezentowane przez dostawcę usługi Azure Storage, zobacz dokumentację dostawcy usługi Azure Storage .

Dostawca magazynu netherite

Netherite partycjonuje cały stan centrum zadań na określoną liczbę partycji. W magazynie używane są następujące zasoby:

  • Jeden kontener obiektów blob usługi Azure Storage zawierający wszystkie obiekty blob pogrupowane według partycji.
  • Jedna tabela platformy Azure zawierająca opublikowane metryki dotyczące partycji.
  • Azure Event Hubs przestrzeni nazw do dostarczania komunikatów między partycjami.

Na przykład centrum zadań o nazwie mytaskhub with PartitionCount = 32 jest reprezentowane w magazynie w następujący sposób:

Diagram przedstawiający organizację magazynu Netherite dla 32 partycji.

Uwaga

Cały stan centrum zadań jest przechowywany wewnątrz kontenera x-storage obiektów blob. Tabela DurableTaskPartitions i przestrzeń nazw usługi EventHubs zawierają nadmiarowe dane: jeśli ich zawartość zostanie utracona, można je automatycznie odzyskać. W związku z tym nie jest konieczne skonfigurowanie Azure Event Hubs przestrzeni nazw w celu zachowania komunikatów po domyślnym czasie wygaśnięcia.

Netherite używa mechanizmu określania źródła zdarzeń na podstawie dziennika i punktów kontrolnych do reprezentowania bieżącego stanu partycji. Są używane zarówno blokowe obiekty blob, jak i stronicowe obiekty blob. Nie można odczytać tego formatu bezpośrednio z magazynu, więc aplikacja funkcji musi być uruchomiona podczas wykonywania zapytań względem magazynu wystąpień.

Aby uzyskać więcej informacji na temat centrów zadań dostawcy magazynu Netherite, zobacz Task Hub information for the Netherite storage provider (Centrum zadań dla dostawcy magazynu Netherite).

Dostawca magazynu MSSQL

Wszystkie dane centrum zadań są przechowywane w pojedynczej relacyjnej bazie danych przy użyciu kilku tabel:

  • Tabele dt.Instances i dt.History przechowują stany wystąpień.
  • Tabela dt.NewEvents przechowuje komunikaty wystąpień.
  • Tabela dt.NewTasks przechowuje komunikaty o aktywności.

Diagram przedstawiający organizację magazynu MSSQL.

Aby umożliwić współistnienie wielu koncentratorów zadań niezależnie w tej samej bazie danych, każda tabela zawiera kolumnę TaskHub jako część klucza podstawowego. W przeciwieństwie do pozostałych dwóch dostawców dostawca MSSQL nie ma pojęcia partycji.

Aby uzyskać więcej informacji na temat centrów zadań dostawcy magazynu MSSQL, zobacz Informacje o centrum zadań dostawcy magazynu Microsoft SQL (MSSQL).

Nazwy centrum zadań

Centra zadań są identyfikowane przez nazwę, która musi być zgodna z następującymi regułami:

  • Zawiera tylko znaki alfanumeryczne
  • Rozpoczyna się od litery
  • Ma minimalną długość 3 znaków, maksymalną długość 45 znaków

Nazwa centrum zadań jest zadeklarowana w pliku host.json , jak pokazano w poniższym przykładzie:

host.json (Functions 2.0)

{
  "version": "2.0",
  "extensions": {
    "durableTask": {
      "hubName": "MyTaskHub"
    }
  }
}

host.json (Functions 1.x)

{
  "durableTask": {
    "hubName": "MyTaskHub"
  }
}

Centra zadań można również skonfigurować przy użyciu ustawień aplikacji, jak pokazano w poniższym host.json przykładowym pliku:

host.json (Functions 1.0)

{
  "durableTask": {
    "hubName": "%MyTaskHub%"
  }
}

host.json (Functions 2.0)

{
  "version": "2.0",
  "extensions": {
    "durableTask": {
      "hubName": "%MyTaskHub%"
    }
  }
}

Nazwa centrum zadań zostanie ustawiona na wartość MyTaskHub ustawienia aplikacji. Poniżej local.settings.json przedstawiono sposób definiowania MyTaskHub ustawienia jako samplehubname:

{
  "IsEncrypted": false,
  "Values": {
    "MyTaskHub" : "samplehubname"
  }
}

Uwaga

W przypadku korzystania z miejsc wdrożenia najlepszym rozwiązaniem jest skonfigurowanie nazwy centrum zadań przy użyciu ustawień aplikacji. Jeśli chcesz upewnić się, że określone miejsce zawsze używa określonego centrum zadań, użyj ustawień aplikacji "slot-sticky".

Oprócz pliku host.json nazwy centrum zadań można również skonfigurować w metadanych powiązania klienta orkiestracji . Jest to przydatne, jeśli musisz uzyskać dostęp do aranżacji lub jednostek, które działają w oddzielnej aplikacji funkcji. Poniższy kod pokazuje, jak napisać funkcję, która używa powiązania klienta orkiestracji do pracy z centrum zadań skonfigurowanego jako ustawienie aplikacji:

[FunctionName("HttpStart")]
public static async Task<HttpResponseMessage> Run(
    [HttpTrigger(AuthorizationLevel.Function, methods: "post", Route = "orchestrators/{functionName}")] HttpRequestMessage req,
    [DurableClient(TaskHub = "%MyTaskHub%")] IDurableOrchestrationClient starter,
    string functionName,
    ILogger log)
{
    // Function input comes from the request content.
    object eventData = await req.Content.ReadAsAsync<object>();
    string instanceId = await starter.StartNewAsync(functionName, eventData);

    log.LogInformation($"Started orchestration with ID = '{instanceId}'.");

    return starter.CreateCheckStatusResponse(req, instanceId);
}

Uwaga

Poprzedni przykład dotyczy Durable Functions 2.x. W przypadku Durable Functions 1.x należy użyć DurableOrchestrationContext polecenia zamiast IDurableOrchestrationContext. Aby uzyskać więcej informacji na temat różnic między wersjami, zobacz artykuł dotyczący wersji Durable Functions.

Uwaga

Konfigurowanie nazw centrów zadań w metadanych powiązania klienta jest konieczne tylko wtedy, gdy używasz jednej aplikacji funkcji do uzyskiwania dostępu do aranżacji i jednostek w innej aplikacji funkcji. Jeśli funkcje klienta są zdefiniowane w tej samej aplikacji funkcji co aranżacje i jednostki, należy unikać określania nazw centrum zadań w metadanych powiązania. Domyślnie wszystkie powiązania klienta pobierają metadane centrum zadań z ustawień host.json .

Nazwy centrum zadań muszą zaczynać się literą i składać się tylko z liter i cyfr. Jeśli nie zostanie określona, zostanie użyta domyślna nazwa centrum zadań, jak pokazano w poniższej tabeli:

Wersja rozszerzenia durable Domyślna nazwa centrum zadań
2.x Po wdrożeniu na platformie Azure nazwa centrum zadań pochodzi od nazwy aplikacji funkcji. W przypadku uruchamiania poza platformą Azure domyślna nazwa centrum zadań to TestHubName.
1.x Domyślna nazwa centrum zadań dla wszystkich środowisk to DurableFunctionsHub.

Aby uzyskać więcej informacji na temat różnic między wersjami rozszerzeń, zobacz artykuł Durable Functions versions (Wersje Durable Functions).

Uwaga

Nazwa odróżnia jedno centrum zadań od drugiego w przypadku wielu centrów zadań na udostępnionym koncie magazynu. Jeśli masz wiele aplikacji funkcji współużytkowanych konto magazynu, musisz jawnie skonfigurować różne nazwy dla każdego centrum zadań w plikach host.json . W przeciwnym razie wiele aplikacji funkcji będzie konkurować ze sobą w przypadku komunikatów, co może spowodować niezdefiniowane zachowanie, w tym nieoczekiwanie "zablokowane" w Pending stanie lub Running .

Następne kroki