Udostępnij za pośrednictwem


Przewodnik rozwiązywania problemów z Durable Functions

Durable Functions to rozszerzenie Azure Functions, które umożliwia tworzenie orkiestracji bezserwerowych przy użyciu zwykłego kodu. Aby uzyskać więcej informacji na temat Durable Functions, zobacz omówienie Durable Functions.

Ten artykuł zawiera przewodnik rozwiązywania typowych scenariuszy w aplikacjach Durable Functions.

Uwaga

Inżynierowie pomocy technicznej firmy Microsoft mogą pomóc w diagnozowaniu problemów z aplikacją. Jeśli nie możesz zdiagnozować problemu przy użyciu tego przewodnika, możesz zgłosić bilet pomocy technicznej, korzystając z bloku Nowy wniosek o pomoc techniczną w sekcji Pomoc techniczna i rozwiązywanie problemów na stronie aplikacji funkcji w Azure Portal.

Zrzut ekranu przedstawiający stronę żądania pomocy technicznej w witrynie Azure Portal.

Porada

Podczas debugowania i diagnozowania problemów zaleca się rozpoczęcie od zapewnienia, że aplikacja korzysta z najnowszej wersji rozszerzenia Durable Functions. W większości przypadków użycie najnowszej wersji ogranicza znane problemy zgłaszane już przez innych użytkowników. Przeczytaj artykuł Uaktualnianie Durable Functions wersji rozszerzenia, aby uzyskać instrukcje dotyczące uaktualniania wersji rozszerzenia.

Karta Diagnozowanie i rozwiązywanie problemów w Azure Portal jest przydatnym zasobem do monitorowania i diagnozowania możliwych problemów związanych z aplikacją. Dostarcza również potencjalne rozwiązania problemów na podstawie diagnozy. Aby uzyskać więcej informacji, zobacz Diagnostyka aplikacji funkcji platformy Azure .

Jeśli powyższe zasoby nie rozwiązały problemu, poniższe sekcje zawierają porady dotyczące konkretnych objawów aplikacji:

Orkiestracja jest zablokowana w Pending stanie

Po uruchomieniu orkiestracji komunikat "start" zostanie zapisany w wewnętrznej kolejce zarządzanej przez rozszerzenie Durable, a stan orkiestracji zostanie ustawiony na "Oczekujące". Po odebraniu i pomyślnym przetworzeniu komunikatu orkiestracji przez dostępne wystąpienie aplikacji stan zmieni się na "Uruchomiono" (lub inny stan inny niż "Oczekujący").

Wykonaj poniższe kroki, aby rozwiązać problemy z wystąpieniami orkiestracji, które pozostają zablokowane na czas nieokreślony w stanie "Oczekujące".

  • Sprawdź ślady platformy Durable Task Framework pod kątem ostrzeżeń lub błędów identyfikatora wystąpienia orkiestracji, których dotyczy ten wpływ. Przykładowe zapytanie można znaleźć w sekcji Błędy śledzenia/Ostrzeżenia.

  • Sprawdź kolejki sterowania usługi Azure Storage przypisane do zablokowanego koordynatora, aby sprawdzić, czy jego komunikat "start" jest nadal dostępny, aby uzyskać więcej informacji na temat kolejek kontroli, zobacz dokumentację kolejki kontroli dostawcy usługi Azure Storage.

  • Zmień wersję konfiguracji platformy aplikacji na "64-bitowy". Czasami aranżacje nie są uruchamiane, ponieważ aplikacja kończy się pamięcią. Przełączanie do 64-bitowego procesu umożliwia aplikacji przydzielanie większej ilości całkowitej pamięci. Dotyczy to tylko planów App Service Podstawowa, Standardowa, Premium i Elastic Premium. Plany bezpłatne lub zużycie nie obsługują procesów 64-bitowych.

Orkiestracja rozpoczyna się po długim opóźnieniu

Zwykle aranżacje zaczynają się w ciągu kilku sekund po ich zaplanowaniu. Istnieją jednak pewne przypadki, w których aranżacje mogą trwać dłużej. Wykonaj poniższe kroki, aby rozwiązać problem, gdy aranżacje potrwają więcej niż kilka sekund, aby rozpocząć wykonywanie.

Orkiestracja nie została ukończona / jest zablokowana w Running stanie

Jeśli orkiestracja pozostaje w stanie "Uruchomiono" przez długi okres czasu, zwykle oznacza to, że oczekuje na długotrwałe zadanie zaplanowane do ukończenia. Może to być na przykład oczekiwanie na ukończenie zadania czasomierza trwałego, zadania działania lub zadania zdarzenia zewnętrznego. Jeśli jednak zauważysz, że zaplanowane zadania zostały ukończone pomyślnie, ale orkiestracja nadal nie postępuje, może wystąpić problem uniemożliwiający kontynuowanie kolejnego zadania. Często nazywamy aranżacje w tym stanie jako "zablokowane aranżacje".

Aby rozwiązać problemy z zablokowanymi aranżacjami, wykonaj następujące czynności:

  • Spróbuj ponownie uruchomić aplikację funkcji. Ten krok może pomóc, jeśli aranżacja zostanie zablokowana z powodu przejściowej usterki lub zakleszczenia w aplikacji lub kodzie rozszerzenia.

  • Sprawdź kolejki kontroli konta usługi Azure Storage, aby sprawdzić, czy kolejki stale rosną. To zapytanie KQL obsługi komunikatów usługi Azure Storage może pomóc zidentyfikować problemy z komunikatami orkiestracji w kolejce. Jeśli problem ma wpływ tylko na jedną kolejkę sterowania, może to wskazywać na problem, który istnieje tylko w konkretnym wystąpieniu aplikacji, w którym przypadku skalowanie w górę lub w dół w celu wyłączenia wystąpienia maszyny wirtualnej w złej kondycji może pomóc.

  • Użyj zapytania usługi Application Insights w sekcji Azure Storage Messaging , aby odfiltrować nazwę tej kolejki jako identyfikator partycji i wyszukać wszelkie problemy związane z tą partycją kolejki sterującej.

  • Zapoznaj się ze wskazówkami w Durable Functions najlepszych rozwiązań i narzędzi diagnostycznych. Niektóre problemy mogą być spowodowane przez znane Durable Functions anty-wzorce.

  • Zapoznaj się z dokumentacją dotyczącą przechowywania wersji Durable Functions. Niektóre problemy mogą być spowodowane przez zmiany powodujące niezgodność wystąpień orkiestracji w locie.

Orkiestracja działa powoli

Duże przetwarzanie danych, błędy wewnętrzne i niewystarczające zasoby obliczeniowe mogą powodować wolniejsze wykonywanie orkiestracji niż zwykle. Aby rozwiązać problemy z aranżacjami, które trwają dłużej niż oczekiwano, wykonaj następujące kroki:

  • Sprawdź ślady platformy Durable Task Framework pod kątem ostrzeżeń lub błędów identyfikatora wystąpienia orkiestracji, których dotyczy ten wpływ. Przykładowe zapytanie można znaleźć w sekcji Błędy śledzenia/Ostrzeżenia.

  • Jeśli aplikacja korzysta z modelu przetwarzania platformy .NET, rozważ włączenie sesji rozszerzonych. Sesje rozszerzone mogą zminimalizować obciążenia historii, co może spowolnić przetwarzanie.

  • Sprawdź wąskie gardła wydajności i skalowalności. Wydajność aplikacji zależy od wielu czynników. Na przykład wysokie użycie procesora CPU lub duże zużycie pamięci może spowodować opóźnienia. Przeczytaj artykuł Wydajność i skalowanie w Durable Functions, aby uzyskać szczegółowe wskazówki.

Przykładowe zapytania

W tej sekcji pokazano, jak rozwiązywać problemy, pisząc niestandardowe zapytania KQL w wystąpieniu usługi aplikacja systemu Azure Insights skonfigurowanym dla aplikacji Azure Functions.

Obsługa komunikatów w usłudze Azure Storage

W przypadku korzystania z domyślnego dostawcy usługi Azure Storage wszystkie zachowania Durable Functions są sterowane przez komunikaty kolejki usługi Azure Storage, a cały stan związany z orkiestracją jest przechowywany w magazynie tabel i magazynie obiektów blob. Po włączeniu śledzenia platformy Durable Task Framework wszystkie interakcje usługi Azure Storage są rejestrowane w usłudze Application Insights, a te dane są niezwykle ważne w przypadku debugowania problemów z wykonywaniem i wydajnością.

Począwszy od wersji 2.3.0 rozszerzenia Durable Functions, można mieć te dzienniki platformy Durable Task Framework opublikowane w wystąpieniu usługi Application Insights, aktualizując konfigurację rejestrowania w pliku host.json. Aby uzyskać informacje i instrukcje dotyczące tego, jak to zrobić, zobacz artykuł dotyczący rejestrowania platformy Durable Task Framework .

Poniższe zapytanie dotyczy inspekcji kompleksowej interakcji usługi Azure Storage dla określonego wystąpienia orkiestracji. Edytuj start i orchestrationInstanceID filtruj według zakresu czasu i identyfikatora wystąpienia.

let start = datetime(XXXX-XX-XXTXX:XX:XX); // edit this 
let orchestrationInstanceID = "XXXXXXX"; //edit this
traces  
| where timestamp > start and timestamp < start + 1h 
| where customDimensions.Category == "DurableTask.AzureStorage" 
| extend taskName = customDimensions["EventName"]
| extend eventType = customDimensions["prop__EventType"] 
| extend extendedSession = customDimensions["prop__IsExtendedSession"]
| extend account = customDimensions["prop__Account"] 
| extend details = customDimensions["prop__Details"] 
| extend instanceId = customDimensions["prop__InstanceId"] 
| extend messageId = customDimensions["prop__MessageId"] 
| extend executionId = customDimensions["prop__ExecutionId"] 
| extend age = customDimensions["prop__Age"] 
| extend latencyMs = customDimensions["prop__LatencyMs"] 
| extend dequeueCount = customDimensions["prop__DequeueCount"] 
| extend partitionId = customDimensions["prop__PartitionId"] 
| extend eventCount = customDimensions["prop__TotalEventCount"] 
| extend taskHub = customDimensions["prop__TaskHub"] 
| extend pid = customDimensions["ProcessId"]
| extend appName = cloud_RoleName
| extend newEvents = customDimensions["prop__NewEvents"]
| where instanceId == orchestrationInstanceID
| sort by timestamp asc
| project timestamp, appName, severityLevel, pid, taskName, eventType, message, details, messageId, partitionId, instanceId, executionId, age, latencyMs, dequeueCount, eventCount, newEvents, taskHub, account, extendedSession, sdkVersion

Błędy śledzenia/ostrzeżenia

Poniższe zapytanie wyszukuje błędy i ostrzeżenia dla danego wystąpienia orkiestracji. Musisz podać wartość dla orchestrationInstanceIDelementu .

let orchestrationInstanceID = "XXXXXX"; // edit this
let start = datetime(XXXX-XX-XXTXX:XX:XX); 
traces  
| where timestamp > start and timestamp < start + 1h
| extend instanceId = iif(isnull(customDimensions["prop__InstanceId"] ) , customDimensions["prop__instanceId"], customDimensions["prop__InstanceId"] ) 
| extend logLevel = customDimensions["LogLevel"]
| extend functionName = customDimensions["prop__functionName"]
| extend status = customDimensions["prop__status"]
| extend details = customDimensions["prop__Details"] 
| extend reason = customDimensions["prop__reason"]
| where severityLevel > 1 // to see all logs of  severity level "Information" or greater.
| where instanceId == orchestrationInstanceID
| sort by timestamp asc 

Kolejka sterowania/ dzienniki identyfikatorów partycji

Następujące zapytanie wyszukuje wszystkie działania skojarzone z kolejką kontrolną instanceId. Musisz podać wartość identyfikatora instanceID w parametrze orchestrationInstanceID i godzinę rozpoczęcia zapytania w .start

let orchestrationInstanceID = "XXXXXX"; // edit this
let start = datetime(XXXX-XX-XXTXX:XX:XX); // edit this
traces  // determine control queue for this orchestrator
| where timestamp > start and timestamp < start + 1h 
| extend instanceId = customDimensions["prop__TargetInstanceId"] 
| extend partitionId = tostring(customDimensions["prop__PartitionId"])
| where partitionId contains "control" 
| where instanceId == orchestrationInstanceID
| join kind = rightsemi(
traces  
| where timestamp > start and timestamp < start + 1h 
| where customDimensions.Category == "DurableTask.AzureStorage" 
| extend taskName = customDimensions["EventName"]
| extend eventType = customDimensions["prop__EventType"] 
| extend extendedSession = customDimensions["prop__IsExtendedSession"]
| extend account = customDimensions["prop__Account"] 
| extend details = customDimensions["prop__Details"] 
| extend instanceId = customDimensions["prop__InstanceId"] 
| extend messageId = customDimensions["prop__MessageId"] 
| extend executionId = customDimensions["prop__ExecutionId"] 
| extend age = customDimensions["prop__Age"] 
| extend latencyMs = customDimensions["prop__LatencyMs"] 
| extend dequeueCount = customDimensions["prop__DequeueCount"] 
| extend partitionId = tostring(customDimensions["prop__PartitionId"])
| extend eventCount = customDimensions["prop__TotalEventCount"] 
| extend taskHub = customDimensions["prop__TaskHub"] 
| extend pid = customDimensions["ProcessId"]
| extend appName = cloud_RoleName
| extend newEvents = customDimensions["prop__NewEvents"]
) on partitionId
| sort by timestamp asc
| project timestamp, appName, severityLevel, pid, taskName, eventType, message, details, messageId, partitionId, instanceId, executionId, age, latencyMs, dequeueCount, eventCount, newEvents, taskHub, account, extendedSession, sdkVersion

Dokumentacja kolumn usługi Application Insights

Poniżej znajduje się lista kolumn przewidywanych przez powyższe zapytania i ich odpowiednie opisy.

Kolumna Opis
Pid Identyfikator procesu wystąpienia aplikacji funkcji. Jest to przydatne do określenia, czy proces został poddany recyklingu podczas wykonywania aranżacji.
Nazwa_zadania Nazwa rejestrowanego zdarzenia.
eventType Typ komunikatu, który zwykle reprezentuje pracę wykonywaną przez koordynatora. Pełna lista możliwych wartości i ich opisów znajduje się tutaj
extendedSession Wartość logiczna wskazująca, czy sesje rozszerzone są włączone.
account Konto magazynu używane przez aplikację.
szczegóły Dodatkowe informacje o konkretnym zdarzeniu, jeśli są dostępne.
instanceId Identyfikator danego wystąpienia orkiestracji lub jednostki.
Messageid Unikatowy identyfikator usługi Azure Storage dla danego komunikatu w kolejce. Ta wartość najczęściej pojawia się w zdarzeniach śledzenia ReceivedMessage, ProcessingMessage i DeletingMessage. Pamiętaj, że nie jest obecny w zdarzeniach SendMessage, ponieważ identyfikator komunikatu jest generowany przez usługę Azure Storage po wysłaniu komunikatu.
Executionid Identyfikator wykonania orkiestratora, który zmienia się za każdym razem, gdy continue-as-new jest wywoływany.
wiek Liczba milisekund od momentu kolejkowania komunikatu. Duża liczba często wskazuje na problemy z wydajnością. Wyjątkiem jest typ komunikatu TimerFired, który może mieć dużą wartość wiekową w zależności od czasu trwania czasomierza.
opóźnienieMs Liczba milisekund wykonanych przez operację magazynu.
dequeueCount Liczba przypadków, gdy komunikat został usunięty z kolejki. W normalnych okolicznościach ta wartość jest zawsze 1. Jeśli jest to więcej niż jeden, może wystąpić problem.
Partitionid Nazwa kolejki skojarzonej z tym dziennikiem.
totalEventCount Liczba zdarzeń historii zaangażowanych w bieżącą akcję.
taskHub Nazwa centrum zadań.
newEvents Rozdzielona przecinkami lista zdarzeń historii zapisywanych w tabeli Historia w magazynie.