Tartós vezénylések

A Durable Functions az Azure Functions bővítménye. Vezénylő függvénnyel vezényelheti más Durable-függvények végrehajtását egy függvényalkalmazáson belül. Az Orchestrator-függvények a következő jellemzőkkel rendelkeznek:

  • Az Orchestrator függvények eljárási kóddal definiálják a függvény-munkafolyamatokat. Nincs szükség deklaratív sémákra vagy tervezőkre.
  • Az Orchestrator függvények szinkron módon és aszinkron módon is meghívhatnak más tartós függvényeket. Az úgynevezett függvények kimenete megbízhatóan menthető helyi változókba.
  • Az Orchestrator funkciói tartósak és megbízhatóak. A végrehajtási folyamat automatikusan ellenőrzi, ha a függvény "várja" vagy "hozamokat" ad. A helyi állapot soha nem vész el, amikor a folyamat újraindul vagy a virtuális gép újraindul.
  • Az Orchestrator függvények hosszú ideig futhatnak. A vezénylési példány teljes élettartama lehet másodperc, nap, hónap vagy soha nem végződő.

Ez a cikk áttekintést nyújt a vezénylő függvényekről, és arról, hogyan segíthetnek a különböző alkalmazásfejlesztési kihívások megoldásában. Ha még nem ismeri a Durable Functions-alkalmazásokban elérhető függvénytípusokat, először olvassa el a Durable Függvénytípusok című cikket.

Vezénylési identitás

A vezénylés minden példánya rendelkezik példányazonosítóval (más néven példányazonosítóval). Alapértelmezés szerint minden példányazonosító egy automatikusan létrehozott GUID. A példányazonosítók azonban bármilyen felhasználó által létrehozott sztringértékek is lehetnek. Minden vezénylési példányazonosítónak egyedinek kell lennie egy feladatközponton belül.

A példányazonosítókra vonatkozó néhány szabály a következő:

  • A példányazonosítóknak 1 és 100 karakter közöttinek kell lenniük.
  • A példányazonosítók nem kezdődnek a példánnyal @.
  • A példányazonosítók nem tartalmazhatnak /, \vagy #? karaktereket.
  • A példányazonosítók nem tartalmazhatnak vezérlő karaktereket.

Feljegyzés

Általában ajánlott automatikus példányazonosítókat használni, amikor csak lehetséges. A felhasználó által létrehozott példányazonosítók olyan helyzetekre szolgálnak, amikor a vezénylési példány és néhány külső alkalmazásspecifikus entitás, például egy vásárlási megrendelés vagy egy dokumentum között egy-az-egyhez megfeleltetés van.

Emellett a karakterkorlátozási szabályok tényleges érvényesítése az alkalmazás által használt tárolószolgáltatótól függően változhat. A helyes viselkedés és kompatibilitás biztosítása érdekében erősen ajánlott a korábban felsorolt példányazonosító-szabályokat követni.

A vezénylés példányazonosítója a legtöbb példánykezelési művelethez szükséges paraméter. A diagnosztika szempontjából is fontosak, például az alkalmazás Elemzések vezényléskövetési adatainak hibaelhárítási vagy elemzési célból történő kereséséhez. Ezért ajánlott a létrehozott példányazonosítókat külső helyre (például adatbázisba vagy alkalmazásnaplókba) menteni, ahol később könnyen hivatkozhatnak rájuk.

Megbízhatóság

Az Orchestrator-függvények az esemény-forrástervezési minta használatával megbízhatóan fenntartják a végrehajtási állapotukat. A vezénylés aktuális állapotának közvetlen tárolása helyett a Durable Task Framework egy csak hozzáfűző tárolót használ a függvényvezénylés által végrehajtott műveletek teljes sorozatának rögzítéséhez. A csak hozzáfűző tárolók számos előnnyel járnak a teljes futtatókörnyezeti állapot "memóriaképéhez" képest. Az előnyök közé tartozik a nagyobb teljesítmény, a méretezhetőség és a válaszkészség. Emellett végleges konzisztenciát is kaphat a tranzakciós adatokhoz, valamint a teljes auditnaplókhoz és előzményekhez. Az auditnaplók megbízható kompenzáló műveleteket támogatnak.

A Durable Functions transzparens módon használja az esemény-beszerzést. A színfalak mögött a await vezénylő függvény (C#) vagy yield (JavaScript/Python) operátora a vezénylési szál irányítását a Durable Task Framework diszpécserének adja vissza. Java esetén nincs speciális nyelvi kulcsszó. Ehelyett egy feladat meghívása .await() visszahozhatja az irányítást a diszpécsernek egy egyéni Throwablerendszeren keresztül. A diszpécser ezután véglegesíti azokat az új műveleteket, amelyeket a vezénylő függvény ütemezett (például egy vagy több gyermekfüggvény meghívása vagy tartós időzítő ütemezése) a tárolóba. A transzparens véglegesítési művelet úgy frissíti a vezénylési példány végrehajtási előzményeit, hogy az összes új eseményt hozzáfűzi a tárolóhoz, hasonlóan egy csak hozzáfűző naplóhoz. Hasonlóképpen, a véglegesítési művelet üzeneteket hoz létre a tárolóban a tényleges munka ütemezéséhez. Ezen a ponton a vezénylő függvény eltávolítható a memóriából. A Durable Functions alapértelmezés szerint az Azure Storage-t használja futtatókörnyezeti állapottárolóként, de más tárolószolgáltatók is támogatottak.

Ha egy vezénylési függvény több feladatot kap (például válaszüzenet érkezik, vagy egy tartós időzítő lejár), a vezénylő felébreszti és újra végrehajtja a teljes függvényt az elejétől kezdve a helyi állapot újraépítéséhez. A visszajátszás során, ha a kód egy függvényt próbál meghívni (vagy bármilyen más aszinkron műveletet végez), a Durable Task Framework az aktuális vezénylés végrehajtási előzményeit tekinti át. Ha úgy találja, hogy a tevékenységfüggvény már végrehajtotta és eredményt adott, visszajátssza a függvény eredményét, és a vezénylő kód továbbra is fut. A visszajátszás a függvénykód befejezéséig vagy az új aszinkron munka ütemezéséig folytatódik.

Feljegyzés

Ahhoz, hogy a visszajátszási minta megfelelően és megbízhatóan működjön, a vezénylő függvény kódjának determinisztikusnak kell lennie. A nem determinisztikus vezénylőkód futásidejű hibákat vagy más váratlan viselkedést eredményezhet. A vezénylőfüggvények kódkorlátozásairól további információt a vezénylő függvény kódkorlátozásainak dokumentációjában talál.

Feljegyzés

Ha egy vezénylő függvény naplóüzeneteket bocsát ki, a visszajátszási viselkedés ismétlődő naplóüzenetek küldését okozhatja. A naplózási témakörből megtudhatja, hogy miért fordul elő ez a viselkedés, és hogyan lehet megkerülni.

Vezénylési előzmények

A Durable Task Framework esemény-beszerzési viselkedése szorosan összefügg az ön által írt vezénylőfüggvény-kóddal. Tegyük fel, hogy rendelkezik egy tevékenységláncoló vezénylő függvénnyel, például a következő vezénylő függvénnyel:

Feljegyzés

Az Azure Functions Node.js programozási modelljének 4- es verziója általánosan elérhető. Az új v4-modell úgy lett kialakítva, hogy rugalmasabb és intuitívabb felhasználói élményt nyújtson JavaScript- és TypeScript-fejlesztők számára. A migrálási útmutatóban további információt olvashat a v3 és a v4 közötti különbségekről.

A következő kódrészletekben a JavaScript (PM4) a V4 programozási modellt, az új felületet jelöli.

[FunctionName("HelloCities")]
public static async Task<List<string>> Run(
    [OrchestrationTrigger] IDurableOrchestrationContext context)
{
    var outputs = new List<string>();

    outputs.Add(await context.CallActivityAsync<string>("SayHello", "Tokyo"));
    outputs.Add(await context.CallActivityAsync<string>("SayHello", "Seattle"));
    outputs.Add(await context.CallActivityAsync<string>("SayHello", "London"));

    // returns ["Hello Tokyo!", "Hello Seattle!", "Hello London!"]
    return outputs;
}

Amikor egy tevékenységfüggvény ütemezve van, a Durable Task Framework ellenőrzi a függvény végrehajtási állapotát egy tartós tárterület háttérrendszerében (alapértelmezés szerint az Azure Table Storage-ban). Ezt az állapotot nevezzük vezénylési előzményeknek.

Előzménytábla

Általánosságban elmondható, hogy a Durable Task Framework az alábbi feladatokat végzi el minden ellenőrzőponton:

  1. A végrehajtási előzményeket tartós tárolóba menti.
  2. Lekérdezi azokat az üzeneteket, amelyeket a vezénylő meghívni szeretne.
  3. Maga a vezénylő számára is lekérdezi az üzeneteket – például tartós időzítőüzeneteket.

Az ellenőrzőpont befejeződése után a vezénylő függvény szabadon eltávolítható a memóriából, amíg több munka nem történik.

Feljegyzés

Az Azure Storage nem biztosít tranzakciós garanciát az adatok táblatárolóba és üzenetsorokba való mentése között. A hibák kezeléséhez a Durable Functions Azure Storage-szolgáltató végleges konzisztenciamintákat használ. Ezek a minták biztosítják, hogy ne vesszenek el adatok, ha egy ellenőrzőpont közepén összeomlik vagy megszakad a kapcsolat. Az alternatív tárolószolgáltatók, például a Durable Functions MSSQL-tárolószolgáltató erősebb konzisztenciagaranciát biztosíthatnak.

A befejezés után a korábban bemutatott függvény előzményei az Azure Table Storage következő táblázatához hasonlóan néznek ki (illusztrációként rövidítve):

PartitionKey (InstanceId) EventType Időbélyegző Bevitel Név Eredmény Állapot
eaee885b VégrehajtásStarted 2021-05-05T18:45:28.852Z null HelloCities
eaee885b OrchestratorStarted 2021-05-05T18:45:32.362Z
eaee885b Feladatütemezett 2021-05-05T18:45:32.670Z SayHello
eaee885b OrchestratorCompleted 2021-05-05T18:45:32.670Z
eaee885b Feladatkiegészítés 2021-05-05T18:45:34.201Z """Hello Tokió!"""
eaee885b OrchestratorStarted 2021-05-05T18:45:34.232Z
eaee885b Feladatütemezett 2021-05-05T18:45:34.435Z SayHello
eaee885b OrchestratorCompleted 2021-05-05T18:45:34.435Z
eaee885b Feladatkiegészítés 2021-05-05T18:45:34.763Z """Hello Seattle!"""
eaee885b OrchestratorStarted 2021-05-05T18:45:34.857Z
eaee885b Feladatütemezett 2021-05-05T18:45:34.857Z SayHello
eaee885b OrchestratorCompleted 2021-05-05T18:45:34.857Z
eaee885b Feladatkiegészítés 2021-05-05T18:45:34.919Z """Hello London!"""
eaee885b OrchestratorStarted 2021-05-05T18:45:35.032Z
eaee885b OrchestratorCompleted 2021-05-05T18:45:35.044Z
eaee885b Végrehajtás befejezve 2021-05-05T18:45:35.044Z "[""Hello Tokyo!"",""Hello Seattle!"","Hello London!""]" Befejeződött

Néhány megjegyzés az oszlopértékekről:

  • PartitionKey: A vezénylés példányazonosítóját tartalmazza.
  • EventType: Az esemény típusát jelöli. Az összes előzményesemény-típus részletes leírását itt találja.
  • Időbélyeg: Az előzményesemény UTC időbélyege.
  • Név: A meghívott függvény neve.
  • Bemenet: A függvény JSON-formátumú bemenete.
  • Eredmény: A függvény kimenete, vagyis a visszatérési értéke.

Figyelmeztetés

Bár hibakeresési eszközként hasznos, ne függjön a táblától. A Durable Functions bővítmény fejlődésével változhat.

Minden alkalommal, amikor egy feladat befejezésére való várakozás után a függvény újraindul, a Durable Task Framework az alapoktól újrafuttatja a vezénylő függvényt. Minden újrafuttatáskor a végrehajtási előzményeket tekinti át annak megállapításához, hogy az aktuális aszinkron tevékenység befejeződött-e. Ha a végrehajtási előzmények azt mutatják, hogy a tevékenység már befejeződött, a keretrendszer visszajátssza a tevékenység kimenetét, és továbblép a következő tevékenységre. Ez a folyamat a teljes végrehajtási előzmények visszajátszásáig folytatódik. Az aktuális végrehajtási előzmények visszajátszása után a helyi változók visszaállítva lesznek a korábbi értékükre.

Jellemzők és minták

A következő szakaszok a vezénylő függvények funkcióit és mintáit ismertetik.

Alvezénylések

Az Orchestrator függvények meghívhatnak tevékenységfüggvényeket, de más vezénylő függvényeket is. Létrehozhat például egy nagyobb vezénylést a vezénylő függvények könyvtárából. Egy vezénylőfüggvény több példányát is futtathatja párhuzamosan.

További információkért és példákért tekintse meg az Al-vezénylések című cikket.

Tartós időzítők

A vezénylések ütemezhetnek tartós időzítőket a késések implementálásához vagy időtúllépési kezelés beállításához az aszinkron műveletekhez. Használjon tartós időzítőket a vezénylő függvényekben a nyelvi natív "alvó" API-k helyett.

További információkért és példákért tekintse meg a Durable időzítőkről szóló cikket.

Külső események

Az Orchestrator-függvények megvárhatják, amíg a külső események frissítik a vezénylési példányt. Ez a Durable Functions funkció gyakran hasznos emberi interakciók vagy más külső visszahívások kezeléséhez.

További információkért és példákért tekintse meg a Külső események című cikket.

Hibakezelés

Az Orchestrator függvények használhatják a programozási nyelv hibakezelési funkcióit. A vezénylési kód támogatja a meglévő mintákat try/catch .

Az Orchestrator-függvények újrapróbálkozési szabályzatokat is hozzáadhatnak az általuk hívott tevékenységhez vagy al-vezénylő függvényekhez. Ha egy tevékenység vagy alvezénylő függvény kivétellel meghiúsul, a megadott újrapróbálkozási szabályzat automatikusan késleltetheti és újrapróbálkozza a végrehajtást egy megadott számú alkalommal.

Feljegyzés

Ha egy vezénylési függvény nem kezelt kivételt tapasztal, a vezénylési példány állapotban Failed fejeződik be. A vezénylési példányokat nem lehet újrapróbálkozásra, ha az sikertelen volt.

További információkért és példákért tekintse meg a hibakezelési cikket.

Kritikus szakaszok (Durable Functions 2.x, jelenleg csak .NET)

A vezénylési példányok egyszálasak, így nem szükséges a vezénylésen belüli versenyfeltételek miatt aggódni. A versenyfeltételek azonban akkor lehetségesek, ha a vezénylések külső rendszerekkel kommunikálnak. A külső rendszerekkel való interakció során a versenyhelyzetek mérséklése érdekében a vezénylő függvények a .NET-ben egy metódussal definiálhatják a kritikus szakaszokat.LockAsync

Az alábbi mintakód egy kritikus szakaszt definiáló vezénylő függvényt mutat be. A metódussal belép a kritikus szakaszba LockAsync . Ehhez a módszerhez egy vagy több hivatkozást kell átadni egy tartós entitásnak, amely tartósan kezeli a zárolási állapotot. A vezénylésnek csak egyetlen példánya tudja egyszerre végrehajtani a kódot a kritikus szakaszban.

[FunctionName("Synchronize")]
public static async Task Synchronize(
    [OrchestrationTrigger] IDurableOrchestrationContext context)
{
    var lockId = new EntityId("LockEntity", "MyLockIdentifier");
    using (await context.LockAsync(lockId))
    {
        // critical section - only one orchestration can enter at a time
    }
}

A LockAsync tartós zár(ok) beszerzése és a IDisposable kritikus szakasz végének visszaadása a megsemmisítéskor. Ez az IDisposable eredmény blokkokkal using együtt használható a kritikus szakasz szintaktikai ábrázolásának lekéréséhez. Amikor egy vezénylő függvény kritikus szakaszba lép, csak egy példány tudja végrehajtani ezt a kódblokkot. A kritikus szakaszba belépni próbáló egyéb példányok mindaddig le lesznek tiltva, amíg az előző példány ki nem lép a kritikus szakaszból.

A kritikus szakasz funkció a tartós entitások módosításainak összehangolásához is hasznos. A kritikus szakaszokról további információt a Durable entitások "Entitáskoordináció" című témakörében talál.

Feljegyzés

Kritikus szakaszok érhetők el a Durable Functions 2.0-ban. Jelenleg csak a .NET in-proc vezénylések implementálják ezt a funkciót. Az entitások és a kritikus szakaszok még nem érhetők el a Durable Functionsben a dotnet-izolált feldolgozó számára.

HTTP-végpontok meghívása (Durable Functions 2.x)

A vezénylő függvények nem végezhetnek I/O-t a vezénylő függvénykódokra vonatkozó korlátozásokban leírtak szerint. Ennek a korlátozásnak a tipikus megkerülő megoldása az, hogy becsomagolja azokat a kódot, amelyeknek I/O-t kell elvégeznie egy tevékenységfüggvényben. A külső rendszerekkel interakcióba lépő vezénylések gyakran használnak tevékenységfüggvényeket HTTP-hívások indításához és az eredménynek a vezényléshez való visszaadásához.

A gyakori minta egyszerűsítése érdekében a vezénylő függvények a metódus használatával közvetlenül meghívhatják a CallHttpAsync HTTP API-kat.

[FunctionName("CheckSiteAvailable")]
public static async Task CheckSiteAvailable(
    [OrchestrationTrigger] IDurableOrchestrationContext context)
{
    Uri url = context.GetInput<Uri>();

    // Makes an HTTP GET request to the specified endpoint
    DurableHttpResponse response = 
        await context.CallHttpAsync(HttpMethod.Get, url);

    if ((int)response.StatusCode == 400)
    {
        // handling of error codes goes here
    }
}

Az alapszintű kérés- és válaszminták támogatása mellett a módszer támogatja a gyakori aszinkron HTTP 202 lekérdezési minták automatikus kezelését, valamint támogatja a külső szolgáltatásokkal való hitelesítést felügyelt identitásokkal.

További információkért és részletes példákért tekintse meg a HTTP-funkciókról szóló cikket.

Feljegyzés

A HTTP-végpontok közvetlenül a vezénylő függvényekből való meghívása a Durable Functions 2.0-s és újabb verziókban érhető el.

Több paraméter átadása

Nem lehet közvetlenül több paramétert átadni egy tevékenységfüggvénynek. A javaslat az objektumok vagy összetett objektumok tömbjének átadása.

A .NET-ben ValueTuple-objektumokat is használhat. Az alábbi minta a C# 7-hez hozzáadott ValueTuple új funkcióit használja:

[FunctionName("GetCourseRecommendations")]
public static async Task<object> RunOrchestrator(
    [OrchestrationTrigger] IDurableOrchestrationContext context)
{
    string major = "ComputerScience";
    int universityYear = context.GetInput<int>();

    object courseRecommendations = await context.CallActivityAsync<object>(
        "CourseRecommendations",
        (major, universityYear));
    return courseRecommendations;
}

[FunctionName("CourseRecommendations")]
public static async Task<object> Mapper([ActivityTrigger] IDurableActivityContext inputs)
{
    // parse input for student's major and year in university
    (string Major, int UniversityYear) studentInfo = inputs.GetInput<(string, int)>();

    // retrieve and return course recommendations by major and university year
    return new
    {
        major = studentInfo.Major,
        universityYear = studentInfo.UniversityYear,
        recommendedCourses = new []
        {
            "Introduction to .NET Programming",
            "Introduction to Linux",
            "Becoming an Entrepreneur"
        }
    };
}

Következő lépések