Megjegyzés
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhat bejelentkezni vagy módosítani a címtárat.
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhatja módosítani a címtárat.
A tartós vezénylés egy vezénylő függvénnyel koordinálja más függvények végrehajtását egy megbízható, hosszú ideig futó munkafolyamatban, amely teljes egészében kódban van meghatározva. Az Orchestrator függvények a következő jellemzőkkel rendelkeznek:
- Eljárási kóddal definiálják a munkafolyamatokat. Nincs szükség deklaratív sémákra vagy tervezőkre.
- Más függvényeket szinkron módon és aszinkron módon hívnak meg. Az úgynevezett függvények kimenete menthető helyi változókba.
- Automatikusan ellenőrzési pontot készítenek a végrehajtás előrehaladásáról, amikor a függvény meghív egy
awaitvagyyieldoperátort, így a helyi állapot nem vész el, amikor a folyamat vagy a virtuális gép újraindul. - Támogatják a hosszú ideig futó folyamatokat. A orchestration példány teljes élettartama lehet másodperc, nap vagy hónap, vagy beállíthatja, hogy a példány soha se érjen véget.
Ez a cikk áttekintést nyújt a tartós vezénylésekről, beleértve a vezénylési identitást, az esemény-beszerzést, a végrehajtási előzményeket és az olyan gyakori munkafolyamat-mintákat, mint az alvezénylések, a tartós időzítők és a hibakezelés.
Az Durable Functions-alkalmazásokban elérhető függvénytípusokkal kapcsolatos információkért lásd: Durable Task programozási modell.
Jótanács
Ha a C#-ot a .NET izolált feldolgozómodellel használja, akkor a vezényléseket függvényalapú megközelítéssel (attribútumokkal rendelkező statikus metódusokkal) vagy [Function] megközelítéssel (azoktól TaskOrchestrator<TInput, TOutput>öröklő osztályok) is megírhatja. Az osztályalapú megközelítéshez a Microsoft.DurableTask.Generators forrásgenerátorcsomag szükséges, és erősen gépelt meghívásokat biztosít. További információ: Forrásgenerátorok és osztályalapú szintaxis. A cikkben szereplő C#-kód példák mindkét megközelítést mutatják be.
A Durable Task SDK-k ugyanazokat a vezénylési képességeket biztosítják, mint a Durable Functions, amellyel megbízható, hosszan futó munkafolyamatokat hozhat létre párhuzamos feldolgozással és eseményvezérelt koordinációval. A Durable Functionstől eltérően a Durable Task SDK vezénylések különálló alkalmazásokként futnak, amelyeket a Durable Task Scheduler támogatott.
Orchesztációs identitás
Egy orchestráció minden példánya rendelkezik egy 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 generált globálisan egyedi azonosító (GUID). A példányazonosítók azonban bármilyen felhasználó által létrehozott sztringértékek is lehetnek. Minden orchesztrációs példányazonosítónak egyedinek kell lennie egy feladatközponton belül.
A példányazonosítókra a következő szabályok vonatkoznak:
- A karaktereknek 1 és 100 karakter közöttinek kell lenniük.
- Nem kezdődhetnek
@-vel. - Nem tartalmazhatnak
/,\vagy#?karaktereket. - Nem tartalmazhatnak vezérlőkaraktereket.
Megjegyzés:
Ha lehetséges, használjon automatikus példányazonosítókat. A felhasználó által létrehozott példányazonosítók olyan helyzetekre szolgálnak, amikor a vezénylési példány és egy 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.
Megjegyzés:
A karakterkorlátozási szabályok tényleges érvényesítése az alkalmazás által használt társzolgáltatótól függően változhat. A helyes viselkedés és kompatibilitás biztosítása érdekében kövesse az előző példányazonosító-szabályokat.
A vezénylés példányazonosítója a legtöbb példánykezelési művelethez szükséges paraméter. A példányazonosítók a diagnosztika szempontjából is fontosak. Ezeket például akkor használja, amikor hibaelhárítási vagy elemzési célokra az Application Insights vezényléskövetési adatai között keres . Ezért mentse a létrehozott példányazonosítókat egy külső helyre, amely megkönnyíti a későbbi hivatkozásokat, például egy adatbázis- vagy alkalmazásnaplót.
A vezénylés példányazonosítója a legtöbb példánykezelési művelethez szükséges paraméter. A példányazonosítók a diagnosztika szempontjából is fontosak, ezért mentse a létrehozott példányazonosítókat egy külső helyre, amely megkönnyíti a későbbi hivatkozásokat, például egy adatbázist vagy alkalmazásnaplót.
Reliability
Az Orchestrator-függvények az eseményforrás mintát használják a végrehajtási állapot megbízható fenntartásához. 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örnyezet állapotának kiírásához 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, a teljes auditnaplókhoz és az előzményekhez. Az auditnaplók megbízható kompenzáló műveleteket támogatnak.
A Durable Task Framework transzparens módon használja az esemény-beszerzést. A színfalak mögött a vezénylő függvény egy await operátort használ a C#-ban, és egy yield operátort JavaScriptben és Python. Ezek az operátorok visszavetik a vezénylő szál vezérlését a Durable Task Framework diszpécsernek. Java-ban a .await() hívása egy feladaton átadja az ellenőrzést a diszpécsernek a Throwable egyéni példányán keresztül. A diszpécser ezután véglegesíti azokat az új műveleteket, amelyeket a vezénylő függvény a tárolóba ütemez. Ilyen műveletek például egy vagy több gyermekfüggvény meghívása vagy egy tartós időzítő ütemezése. Az átlátható véglegesítési művelet frissíti a vezénylési példány végrehajtási előzményeit, azáltal hogy az összes új eseményt hozzáfűzi a tárhelyhez, hasonlóan egy csak hozzáfűzést támogató 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 az orchestrator 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 megpróbál meghívni egy függvényt (vagy bármilyen más aszinkron munkát 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ég 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 addig folytatódik, amíg a függvénykód be nem fejeződik, vagy amíg új aszinkron munkát nem ütemez.
Megjegyzé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 nemdeterminisztikus 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 az Orchestrator függvény kódkorlátozásai című témakörben talál.
Megjegyzés:
Ha egy vezénylő függvény naplóüzeneteket bocsát ki, a visszajátszási viselkedés duplikált naplóüzenetek küldéséhez vezethet. Ha szeretné megtudni, hogy miért fordul elő ez a viselkedés, és hogyan lehet megkerülni, tekintse meg a visszajátszásmentes naplózást.
Orkesztrációs előzmények
A Durable Task Framework eseményalapú viselkedése szorosan összefügg az ön által írt orchestrátorfüggvény-kóddal. Tegyük fel, hogy rendelkezik egy tevékenységláncoló orchestrátor függvénnyel, például az alábbi példával.
Izolált munkavállalói modell
[Function("HelloCities")]
public static async Task<List<string>> Run(
[OrchestrationTrigger] TaskOrchestrationContext 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"));
// Return ["Hello Tokyo!", "Hello Seattle!", "Hello London!"].
return outputs;
}
Osztályalapú modell (izolált munkafolyamat)
Az osztályalapú megközelítés egy forrásgenerátort használ, és a Microsoft.DurableTask.Generators NuGet csomagot igényli.
using Microsoft.DurableTask;
[DurableTask]
public class HelloCities : TaskOrchestrator<object?, List<string>>
{
public override async Task<List<string>> RunAsync(
TaskOrchestrationContext context, object? input)
{
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"));
// Return ["Hello Tokyo!", "Hello Seattle!", "Hello London!"].
return outputs;
}
}
Folyamaton belüli modell
[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"));
// Return ["Hello Tokyo!", "Hello Seattle!", "Hello London!"].
return outputs;
}
using Microsoft.DurableTask;
[DurableTask]
public class HelloCities : TaskOrchestrator<object?, List<string>>
{
public override async Task<List<string>> RunAsync(TaskOrchestrationContext context, object? input)
{
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"));
return outputs;
}
}
Amikor egy tevékenységfüggvény ütemezve van, a Durable Task Framework különböző ellenőrzőpontokon menti a függvény végrehajtási állapotát. Minden ellenőrzési ponton a keretrendszer egy tartós háttértárba menti az állapotot. Ezt az állapotot vezénylési előzményeknek nevezzük.
Előzménytábla
A Durable Task Framework általában a következőket végzi el minden ellenőrzőponton:
- A végrehajtási előzményeket tartós tárolóba menti.
- Sorba állítja az üzeneteket azokhoz a funkciókhoz, amelyeket az orchesztáló meghívni szeretne.
- Maga a vezénylő számára is lekérdezi az üzeneteket, például a tartós időzítőüzeneteket.
Ha az ellenőrzőpont elkészült, az orkesztráló függvény eltávolítható a memóriából, amíg nincs több munka számára.
Megjegyzés:
Az Azure Storage nem biztosít tranzakciós garanciát a táblatárolók és az üzenetsorok közötti adatkonzisztenciára az adatok mentésekor. A hibák kezeléséhez a Durable Functions Azure Storage-szolgáltatóvégleges konzisztenciamintákat használ. Ezek a minták segítenek biztosítani, 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 Microsoft SQL Server (MSSQL) tárolószolgáltató erősebb konzisztenciagaranciát biztosíthatnak.
Amikor a korábban bemutatott függvény befejeződik, az előzményei a Table Storage alábbi táblázatában szereplő adatokhoz hasonlóan néznek ki. A bejegyzések lerövidítettek az illusztráció céljából.
| PartitionKey (InstanceId) | Eseménytípus | Időbélyeg | Bemenet | Név | Result | Status |
|---|---|---|---|---|---|---|
| eaee885b | VégrehajtásElindult | 2021-05-05T18:45:28.852Z | null | HelloCities | ||
| eaee885b | OrchestrátorElindult | 2021-05-05T18:45:32.362Z | ||||
| eaee885b | Ütemezett feladat | 2021-05-05T18:45:32.670Z | MonddHelló | |||
| eaee885b | OrkészreállításBefejeződött | 2021-05-05T18:45:32.670Z | ||||
| eaee885b | Feladat befejezve | 2021-05-05T18:45:34.201Z | """Hello Tokió!""" | |||
| eaee885b | OrchestrátorElindult | 2021-05-05T18:45:34.232Z | ||||
| eaee885b | Ütemezett feladat | 2021-05-05T18:45:34.435Z | MonddHelló | |||
| eaee885b | OrkészreállításBefejeződött | 2021-05-05T18:45:34.435Z | ||||
| eaee885b | Feladat befejezve | 2021-05-05T18:45:34.763Z | """Hello Seattle!""" | |||
| eaee885b | OrchestrátorElindult | 2021-05-05T18:45:34.857Z | ||||
| eaee885b | Ütemezett feladat | 2021-05-05T18:45:34.857Z | MonddHelló | |||
| eaee885b | OrkészreállításBefejeződött | 2021-05-05T18:45:34.857Z | ||||
| eaee885b | Feladat befejezve | 2021-05-05T18:45:34.919Z | """Hello London!""" | |||
| eaee885b | OrchestrátorElindult | 2021-05-05T18:45:35.032Z | ||||
| eaee885b | OrkészreállításBefejeződött | 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 |
A táblaoszlopok a következő értékeket tartalmazzák:
- PartitionKey: A vezénylés példányazonosítója.
- EventType: Az esemény típusa. Az összes előzményesemény-típus részletes leírása: Durable Task Framework History Events.
- Időbélyeg: Az előzményesemény koordinált univerzális időbélyege.
- Bemenet: A függvény JSON-formátumú bemenete.
- Név: A meghívott függvény neve.
- Eredmény: A függvény kimenete, pontosabban annak visszatérési értéke.
Figyelmeztetés
Ez a táblázat hibakeresési eszközként hasznos, de formátuma és tartalma megváltozhat a Durable Functions bővítmény fejlődésével.
Minden alkalommal, amikor a függvény a feladat befejezésére való várakozás után folytatódik, 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 addig folytatódik, amíg a teljes végrehajtási előzmény vissza nem játszódik. Az aktuális végrehajtási előzmények visszajátszása után a rendszer visszaállítja a helyi változókat a korábbi értékekre.
Jellemzők és minták
A következő szakaszok a vezénylési függvények funkcióit és mintáit ismertetik.
Részvezénylések a vezénylő függvényekben
Az orchestrator függvények meghívhatnak activity függvényeket, de más orchestrator függvényeket is. Például, egy nagyobb vezénylést hozhat létre 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 lásd: Al-vezénylések a Durable Functions-ben (Azure Functions).
Tartós időzítők
A vezénylések tartós időzítőket ütemezhetnek késések implementálásához vagy időtúllépési kezelés beállításához aszinkron műveletekhez. Használjon tartós időzítőket a vezénylési függvényekben a nyelvi natív sleep API-k helyett.
További információkért és példákért lásd: Timers in Durable Functions (Azure Functions).
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 lásd: Külső események kezelése a Durable Functionsben (Azure Functions)
Hibakezelés
Az Orchestrator függvények használhatják a programozási nyelv hibakezelési funkcióit. Az orkesztációs kód támogatja a meglévő try/catch mintákat.
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.
Megjegyzés:
Ha egy orchestrációs függvény elosztatlan kivétellel rendelkezik, az orchestrációs példány Failed állapotban fejeződik be. Egy vezénylési példány nem próbálható újra, miután meghiúsul.
További információkért és példákért lásd: Hibakezelés a Durable Functions (Azure Functions) dokumentációban.
Kritikus szakaszok (Durable Functions 2.x, jelenleg csak .NET)
Az orchestration példányok egyszálúak, így a versenyfeltételek nem jelentenek problémát az orchestrationen belül. 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 LockAsync.
Az alábbi mintakód egy kritikus szakaszt definiáló vezénylő függvényt mutat be. A LockAsync metódust használja, hogy belépjen a kritikus szakaszba. 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 módszer lekéri a tartós zárakat, és visszaad egy IDisposable objektumot, amely a kritikus szakaszt befejezi, amikor eldobásra kerül. 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 az Entitások koordinációja című témakörben talál.
Megjegyzés:
Kritikus szakaszok érhetők el a Durable Functions 2.0-ban. Jelenleg csak .NET folyamaton belüli 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 .NET izolált feldolgozói vezénylésekhez.
HTTP-végpontokra irányuló hívások (Durable Functions 2.x)
Az Orchestrator-függvények nem végezhetnek I/O-műveleteket az Orchestrator függvénykód-megkötéseiben leírtak szerint. Ennek a korlátozásnak a tipikus megkerülő megoldása az, hogy beburkolja azokat a kódokat, amelyeknek I/O-műveleteket kell végrehajtaniuk egy tevékenységfüggvényben. Azok az orchestruációk, amelyek külső rendszerekkel lépnek interakcióba, gyakran használnak tevékenységfüggvényeket HTTP-hívások végzésére és az eredmények orchestruációhoz való visszajuttatására.
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.
Izolált munkavállalói modell
[Function("CheckSiteAvailable")]
public static async Task CheckSiteAvailable(
[OrchestrationTrigger] TaskOrchestrationContext context)
{
Uri url = context.GetInput<Uri>();
// Make an HTTP GET request to the specified endpoint.
DurableHttpResponse response = await context.CallHttpAsync(
method: HttpMethod.Get,
uri: url,
content: null,
retryOptions: null);
if ((int)response.StatusCode == 400)
{
// Handle error codes.
}
}
Folyamaton belüli modell
[FunctionName("CheckSiteAvailable")]
public static async Task CheckSiteAvailable(
[OrchestrationTrigger] IDurableOrchestrationContext context)
{
Uri url = context.GetInput<Uri>();
// Make an HTTP GET request to the specified endpoint.
DurableHttpResponse response =
await context.CallHttpAsync(HttpMethod.Get, url);
if ((int)response.StatusCode == 400)
{
// Handle error codes.
}
}
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. A külső szolgáltatásokkal való hitelesítést is támogatja felügyelt identitások használatával.
További információkért és részletes példákért tekintse meg a HTTP-funkciókat.
Megjegyzé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óiban érhető el.
Több paraméter átadása tevékenységfüggvényeknek
Nem lehet közvetlenül több paramétert átadni egy tevékenységfüggvénynek. A javaslat objektumok vagy összetett objektumok tömbjének átadására vonatkozik.
Izolált munkavállalói modell
A .NET-ben használjon szerializálható összetett típust, például rekordot több paraméter átadásához.
public record CourseInfo(string Major, int UniversityYear);
[Function("GetCourseRecommendations")]
public static async Task<object> RunOrchestrator(
[OrchestrationTrigger] TaskOrchestrationContext context)
{
int universityYear = context.GetInput<int>();
CourseInfo courseInfo = new("ComputerScience", universityYear);
object courseRecommendations = await context.CallActivityAsync<object>(
"CourseRecommendations", courseInfo);
return courseRecommendations;
}
Folyamaton belüli modell
A .NET-ben szerializálható összetett típussal több paramétert adhat át. A következő minta egy egyszerű osztályt használ:
public class CourseInfo
{
public string Major { get; set; }
public int UniversityYear { get; set; }
}
[FunctionName("GetCourseRecommendations")]
public static async Task<object> RunOrchestrator(
[OrchestrationTrigger] IDurableOrchestrationContext context)
{
var input = new CourseInfo
{
Major = "ComputerScience",
UniversityYear = context.GetInput<int>()
};
object courseRecommendations = await context.CallActivityAsync<object>(
"CourseRecommendations",
input);
return courseRecommendations;
}
A .NET rendszerében a rekordtípusok és a tuple-ök használatával több paramétert lehet átküldeni egyetlen összetett objektumként.
using Microsoft.DurableTask;
public record LocationInfo(string City, string State);
[DurableTask]
public class GetWeatherOrchestration : TaskOrchestrator<object?, string>
{
public override async Task<string> RunAsync(TaskOrchestrationContext context, object? input)
{
var location = new LocationInfo("Seattle", "WA");
string weather = await context.CallActivityAsync<string>("GetWeather", location);
return weather;
}
}