Notatka
Dostęp do tej strony wymaga autoryzacji. Może spróbować zalogować się lub zmienić katalogi.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
Przechowywanie wersji w Durable Functions jest niezbędne, ponieważ funkcje są nieuchronnie dodawane, usuwane i zmieniane w okresie istnienia aplikacji. Durable Functions umożliwia łączenie funkcji w sposób, który nie był wcześniej możliwy, a ten łańcuch wpływa na sposób obsługi przechowywania wersji.
Ten artykuł pomoże Ci:
- Określ, czy zmiana kodu jest zmianą powodującą niezgodność.
- Wybierz odpowiednią strategię ograniczania ryzyka , aby bezpiecznie wdrożyć.
Szybkie porównanie strategii
Jeśli już wiesz, że zmiana powoduje problemy, użyj tej tabeli, aby wybrać strategię łagodzenia skutków.
| Strategia | Najlepsze dla | Szczegóły |
|---|---|---|
| Wersjonowanie orkiestracji (zalecane) | Większość aplikacji z zmianami powodującymi niezgodność. Wbudowana funkcja środowiska wykonawczego współpracuje z dowolnym zapleczem pamięci masowej. | Przejdź do sekcji |
| Wdrożenia równoległe | Aplikacje, które nie mogą używać wersjonowania orkiestracji lub wymagają pełnej izolacji za pośrednictwem oddzielnych centrów zadań lub kont magazynu. | Przejdź do sekcji |
| Zatrzymywanie wszystkich wystąpień w locie | Tworzenie prototypów i rozwój lokalny, w którym utrata aranżacji w locie jest akceptowalna. | Przejdź do sekcji |
Wskazówka
Jeśli szukasz wbudowanej funkcji wersjonowania orkiestracji, która zapewnia automatyczną izolację wersji na poziomie środowiska uruchomieniowego, zobacz Wersjonowanie orkiestracji.
Ważna
Przed wdrożeniem sprawdź, czy zmiana jest zmianą łamiącą zgodność:
- Czy zmieniono nazwę, typ danych wejściowych lub typ danych wyjściowych działania lub funkcji jednostki?
- Czy dodano, usunięto lub zmieniono kolejność wywołań działań, podorkiestracji, czasomierzy lub zdarzeń zewnętrznych w kodzie orkiestratora?
- Czy zmieniłeś nazwę lub usunąłeś funkcję, którą nadal mogą wywoływać działające orkiestracje?
Jeśli odpowiesz tak na którekolwiek z tych, użyj jednej z poniższych strategii łagodzenia, aby uniknąć błędów przy uruchamianiu orkiestracji.
Typy zmian łamiących zgodność
Istnieje kilka przykładów zmian powodujących niezgodność. W tym artykule omówiono najbardziej typowe typy. Głównym motywem wszystkich z nich jest to, że zmiany w kodzie funkcji wpływają zarówno na nowe, jak i istniejące aranżacje funkcji.
Zmiany sygnatury działania lub funkcji jednostki
Zmiana podpisu odnosi się do zmiany nazwy, danych wejściowych lub wyjściowych funkcji. Jeśli wprowadzisz taką zmianę w działaniu lub funkcji jednostki, może to spowodować przerwanie dowolnej funkcji orkiestratora, która jest od niej zależna. To zachowanie jest szczególnie prawdziwe w przypadku języków bezpiecznych pod kątem typów. Jeśli zaktualizujesz funkcję orkiestratora, aby uwzględnić tę zmianę, możesz przerwać istniejące wystąpienia w locie.
Rozważmy na przykład następującą funkcję orkiestratora.
[FunctionName("FooBar")]
public static Task Run([OrchestrationTrigger] IDurableOrchestrationContext context)
{
bool result = await context.CallActivityAsync<bool>("Foo");
await context.CallActivityAsync("Bar", result);
}
Ta funkcja pobiera wynik Foo i przekazuje go do Bar. Załóżmy, że musisz zmienić wartość zwracaną Foo z typu logicznego na tekstowy, aby obsługiwać szerszą gamę wartości wyników. Wynik wygląda następująco:
[FunctionName("FooBar")]
public static Task Run([OrchestrationTrigger] IDurableOrchestrationContext context)
{
string result = await context.CallActivityAsync<string>("Foo");
await context.CallActivityAsync("Bar", result);
}
Ta zmiana działa prawidłowo w przypadku wszystkich nowych wystąpień funkcji orkiestratora, ale może spowodować przerwanie wszystkich wystąpień w locie. Rozważmy na przykład przypadek, w którym wystąpienie orkiestracji wywołuje funkcję o nazwie Foo, pobiera wartość logiczną, a następnie punkty kontrolne. Jeśli zmiana podpisu zostanie wdrożona w tym momencie, wystąpienie punktu kontrolnego zakończy się niepowodzeniem natychmiast po wznowieniu i odtworzeniu wywołania metody Foo. Ten błąd występuje, ponieważ wynik w tabeli historii jest wartością logiczną (Boolean), ale nowy kod próbuje deserializować go do wartości typu String, co powoduje nieprzewidziane działanie lub nawet wyjątek środowiska wykonawczego w przypadku języków z kontrolą typów.
Ten przykład jest jednym z wielu sposobów, na które zmiana podpisu funkcji może przerwać istniejące wystąpienia. Ogólnie rzecz biorąc, jeśli orkiestrator musi zmienić sposób, w jaki wywołuje funkcję, zmiana może być problematyczna.
Zmiany logiki programu Orchestrator
Inna klasa problemów z przechowywaniem wersji wynika z zmiany kodu funkcji orkiestratora w sposób, który zmienia ścieżkę wykonywania dla wystąpień w locie.
Rozważmy następującą funkcję orkiestratora:
[FunctionName("FooBar")]
public static Task Run([OrchestrationTrigger] IDurableOrchestrationContext context)
{
bool result = await context.CallActivityAsync<bool>("Foo");
await context.CallActivityAsync("Bar", result);
}
Teraz załóżmy, że chcesz dodać nowe wywołanie funkcji między dwoma istniejącymi wywołaniami funkcji.
[FunctionName("FooBar")]
public static Task Run([OrchestrationTrigger] IDurableOrchestrationContext context)
{
bool result = await context.CallActivityAsync<bool>("Foo");
if (result)
{
await context.CallActivityAsync("SendNotification");
}
await context.CallActivityAsync("Bar", result);
}
Ta zmiana dodaje nowe wywołanie funkcji do SendNotification między Foo a Bar. Nie istnieją żadne zmiany podpisu. Problem występuje, gdy istniejące wystąpienie zostaje wznowione po wywołaniu do Bar. Podczas odtwarzania, jeśli oryginalne wywołanie metody Foo zwróciło true, to orkiestrator odtwarza wywołanie metody SendNotification, która nie znajduje się w historii wykonania. Środowisko uruchomieniowe wykrywa tę niespójność i zgłasza błąd orkiestracji niedeterministycznej, ponieważ napotkało wywołanie SendNotification, podczas gdy oczekiwano wywołania Bar. Podobny problem może wystąpić podczas dodawania wywołań interfejsu API do innych trwałych operacji, takich jak tworzenie trwałych czasomierzy, oczekiwanie na zdarzenia zewnętrzne lub wywoływanie pod-orchestracji.
Strategie ograniczania ryzyka
Ostrzeżenie
Wdrażanie zmian łamiących kompatybilność bez strategii łagodzenia skutków (podejście "nie rób nic") może spowodować niepowodzenie niedeterministycznych orkiestracji z błędami , utknąć na zawsze w Running statusie lub wyzwolić błędy wykonania na niskim poziomie, które obniżają wydajność. Zawsze stosuj się do jednej z poniższych strategii podczas wdrażania znaczących zmian.
Wersjonowanie orkiestracji (zalecane)
W przeciwieństwie do innych strategii w tej sekcji wersjonowanie orkiestracji jest wbudowaną funkcją środowiska uruchomieniowego, która zapewnia automatyczną izolację wersji. Nie musisz zarządzać oddzielnymi wdrożeniami, centrami zadań ani kontami magazynu. Zamiast tego system wykonawczy śledzi informacje o wersji i zapewnia przetwarzanie instancji orkiestracji przez kompatybilnych procesów roboczych.
Obsługa wersji orkiestracji:
- Każde wystąpienie orkiestracji otrzymuje wersję trwale z nią związaną w momencie tworzenia.
- Funkcje programu Orchestrator mogą odpowiednio sprawdzać ich wersję i wykonywanie gałęzi, zachowując stare i nowe ścieżki kodu w tej samej bazie kodu.
- Pracownicy obsługujący nowsze wersje funkcji orkiestratora mogą kontynuować wykonywanie instancji orkiestracji utworzonych przez starsze wersje.
- Środowisko uruchomieniowe uniemożliwia pracownikom uruchamiającym starsze wersje funkcji orkiestratora wykonywanie orkiestracji nowszych wersji.
Takie podejście wymaga minimalnej konfiguracji (ciąg wersji i opcjonalnej strategii dopasowania) i jest zgodne z dowolnym dostawcą pamięci masowej. Jest to zalecana strategia dla aplikacji, które muszą obsługiwać zmiany powodujące niezgodność przy zachowaniu wdrożeń bez przestojów.
Aby uzyskać szczegółowe wskazówki dotyczące konfiguracji i implementacji, zobacz Orchestration versioning.
Zatrzymywanie wszystkich wystąpień w locie
Inną opcją jest zatrzymanie wszystkich wystąpień w locie. Jeśli używasz domyślnego dostawcy Azure Storage dla Durable Functions, zatrzymaj wszystkie wystąpienia, usuwając zawartość wewnętrznej kolejki control-queue i workitem-queue. Możesz też zatrzymać aplikację, usunąć te kolejki i ponownie włączyć aplikację. Kolejki są tworzone automatycznie po ponownym uruchomieniu aplikacji. Poprzednie wystąpienia orkiestracji mogą pozostawać w stanie "Uruchomiono" na czas nieokreślony, ale nie zaśmiecają dzienników komunikatami o błędach ani nie powodują żadnych szkód w aplikacji. Takie podejście jest idealne do szybkiego tworzenia prototypów, w tym programowania lokalnego.
Ostrzeżenie
Takie podejście wymaga bezpośredniego dostępu do podstawowych zasobów magazynu i nie jest odpowiednie dla wszystkich dostawców magazynu obsługiwanych przez Durable Functions.
Wdrożenia równoległe
Najpewniejszym sposobem zapewnienia bezpiecznego wdrażania sprzecznych zmian jest wdrożenie ich równolegle z wcześniejszymi wersjami. Możesz użyć jednej z następujących technik:
- Inne konto magazynowe: wdróż wszystkie aktualizacje jako nową aplikację funkcji z innym kontem magazynowym. W pełni izoluje stan nowej wersji od stanu starej wersji.
- Inne centrum zadań: wdróż nową kopię aplikacji funkcji, używając tego samego konta magazynu, ale z nową nazwą centrum zadań. Podejście to tworzy nowe składniki przechowywania dla nowej wersji, podczas gdy stara wersja nadal używa istniejących artefaktów.
W przypadku wdrożeń równoległych w Azure można użyć slotów wdrożeniowych aby uruchamiać obie wersje jednocześnie, z jedną jako aktywny slot produkcyjny. Gdy wszystko będzie gotowe do udostępnienia nowej logiki orkiestracji, przełącz nową wersję na slot produkcyjny.
Uwaga / Notatka
Te wskazówki korzystają z terminów specyficznych dla Azure Storage, ale dotyczą ogólnie wszystkich obsługiwanych dostawców magazynu Durable Functions.
Uwaga / Notatka
Zamiany miejsc wdrożenia działają najlepiej z wyzwalaczami HTTP i webhook. W przypadku wyzwalaczy innych niż HTTP, takich jak kolejki lub usługa Event Hubs, definicja wyzwalacza powinna pochodzić z ustawienia aplikacji , które jest aktualizowane w ramach operacji zamiany.