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.
Állapotalapú alkalmazások létrehozása a Durable Functions segítségével. Ez a Azure Functions kiterjesztése. A orchestrator függvény segítségével koordinálhatja a függvényalkalmazás többi Durable Functionját. Az állapottartó, megbízható vezénylő (orchestrátor) függvényeket úgy alakították ki, hogy hosszú ideig futtathatók legyenek.
Állapotalapú, hibatűrő munkafolyamatokat hozhat létre a Durable Task SDK-kkal .NET, Python és Java. Vezénylő használatával koordinálhatja a tevékenységeket és az alvezényléseket. A rendszervezérlők állapotalapúak, megbízhatók, és úgy készültek, hogy hosszú ideig tartósan működjenek.
Vezénylői kódkorlátozások
Az Orchestrator-függvények az eseményforrás használatát alkalmazzák a megbízható végrehajtás és a helyi változó állapot fenntartása érdekében. A vezénylőkód visszajátszási viselkedése kényszereket hoz létre a vezénylő függvényben írható kód típusára. A vezénylőfüggvényeknek például determinisztikusnak kell lenniük: a vezénylő függvények többször is lejátszhatók, és minden alkalommal ugyanazt az eredményt kell eredményezniük.
Az orchestratiók eseményforrás használatával biztosítják a megbízható végrehajtást és a helyi változó állapot fenntartását. A vezénylőkód visszajátszási viselkedése korlátozásokat hoz létre a vezénylőbe írható kód típusára. A vezénylőknek például determinisztikusnak kell lenniük: a vezénylők többször is lejátszanak, és minden alkalommal ugyanazt az eredményt kell eredményezniük.
Determinisztikus API-k használata
Az alábbiakban néhány egyszerű útmutatást talál a kód determinisztikusságának biztosításához.
Api-kat hívhat meg a célnyelvekből a vezénylő függvényekben, de csak determinisztikus API-kat használjon. A determinisztikus API mindig ugyanazt az értéket adja vissza ugyanahhoz a bemenethez, függetlenül attól, hogy mikor vagy milyen gyakran hívják.
Az alábbi szakaszok útmutatást nyújtanak az API-król és azokról a mintákról, amelyek nem determinisztikusak . Ezek a korlátozások csak a vezénylő függvényekre vonatkoznak. Más függvénytípusok nem rendelkeznek ilyen korlátozásokkal.
Az alábbiakban néhány egyszerű útmutatást talál a kód determinisztikusságának biztosításához.
API-kat hívhat meg vezénylőkben a célnyelvekből, de csak determinisztikus API-kat használjon. A determinisztikus API mindig ugyanazt az értéket adja vissza ugyanahhoz a bemenethez, függetlenül attól, hogy mikor vagy milyen gyakran hívják.
Az alábbi szakaszok útmutatást nyújtanak az API-król és azokról a mintákról, amelyek nem determinisztikusak . Ezek a korlátozások csak a vezénylőkre vonatkoznak. A tevékenységek nem rendelkeznek ilyen korlátozásokkal.
Megjegyzés:
Ez a cikk a vezénylői kód általános korlátozásait ismerteti, de nem átfogó. Összpontosítson arra, hogy egy API determinisztikus-e. Ezzel a gondolkodásmóddal általában a listára való hivatkozás nélkül is megállapíthatja, hogy mely API-k használhatók biztonságosan.
Dátumok és időpontok
Az időalapú API-k nem determinisztikusak, és soha nem használhatók vezénylési funkciókban. Minden orchestrátor függvény visszajátszás más értéket ad. Ehelyett használja a Durable Functions egyenértékű API-t az aktuális dátum vagy idő lekéréséhez, amely a visszajátszások során konzisztens marad.
Ne használjon DateTime.Now, DateTime.UtcNowvagy azzal egyenértékű API-kat az aktuális idő lekéréséhez. Az olyan osztályokat, mint Stopwatch, is el kell kerülni. A .NET folyamaton belüli vezénylési függvényekhez használja a IDurableOrchestrationContext.CurrentUtcDateTime tulajdonságot az aktuális idő lekéréséhez. Az elkülönített .NET vezénylőfüggvények esetén használja a TaskOrchestrationContext.CurrentDateTimeUtc tulajdonságot az aktuális idő lekérésére.
DateTime startTime = context.CurrentUtcDateTime;
// do some work
TimeSpan totalTime = context.CurrentUtcDateTime.Subtract(startTime);
Az időalapú API-k nem determinisztikusak, és nem használhatók vezénylőkben. Minden orchestrátor újrajátszása más értéket eredményez. Ehelyett használja a Durable Task SDK egyenértékű API-t az aktuális dátum vagy idő lekéréséhez, amely a visszajátszások között konzisztens marad.
Ne használjon DateTime.Now, DateTime.UtcNowvagy azzal egyenértékű API-kat az aktuális idő lekéréséhez. Az olyan osztályokat, mint Stopwatch, is el kell kerülni. Használja a TaskOrchestrationContext.CurrentUtcDateTime tulajdonságot az aktuális idő lekéréséhez.
using Microsoft.DurableTask;
public class TimerExample : TaskOrchestrator<object?, TimeSpan>
{
public override async Task<TimeSpan> RunAsync(TaskOrchestrationContext context, object? input)
{
// Use context.CurrentUtcDateTime instead of DateTime.Now or DateTime.UtcNow
DateTime startTime = context.CurrentUtcDateTime;
// do some work
await context.CallActivityAsync("DoWork", null);
TimeSpan totalTime = context.CurrentUtcDateTime.Subtract(startTime);
return totalTime;
}
}
GUID-k és UUID-k
A véletlenszerű GUID-t vagy UUID-t visszaadó API-k nemdeterminisztikusak, mert a létrehozott érték minden visszajátszásnál eltérő. A nyelvtől függően elérhető lehet egy beépített API a determinisztikus GUID-k vagy UUID-k létrehozásához. Ellenkező esetben egy tevékenységfüggvényt használva véletlenszerűen generált GUID-t vagy UUID-t lehet létrehozni.
Az olyan API-k, mint Guid.NewGuid(), helyett használja a környezeti objektum NewGuid() API-ját egy véletlenszerű GUID létrehozásához, amely biztonságos a vezénylő visszajátszásához.
Guid randomGuid = context.NewGuid();
Megjegyzés:
A GUID-ok, amelyeket az orchestration környezet API-kkal hoztak létre, 5-ös típusú UUID-k.
A véletlenszerű GUID-t vagy UUID-t visszaadó API-k nemdeterminisztikusak, mert a létrehozott érték minden visszajátszásnál eltérő. A nyelvtől függően elérhető lehet egy beépített API a determinisztikus GUID-k vagy UUID-k létrehozásához. Ellenkező esetben egy tevékenység használatával véletlenszerűen generált GUID-t vagy UUID-t ad vissza.
Az olyan API-k, mint Guid.NewGuid(), helyett használja a környezeti objektum NewGuid() API-ját egy véletlenszerű GUID létrehozásához, amely biztonságos a vezénylő visszajátszásához.
using Microsoft.DurableTask;
public class GuidExample : TaskOrchestrator<object?, Guid>
{
public override async Task<Guid> RunAsync(TaskOrchestrationContext context, object? input)
{
// Use context.NewGuid() instead of Guid.NewGuid()
Guid randomGuid = context.NewGuid();
return randomGuid;
}
}
Megjegyzés:
A GUID-ok, amelyeket az orchestration környezet API-kkal hoztak létre, 5-ös típusú UUID-k.
Véletlenszerű számok
Tevékenységfüggvény használatával véletlenszerű számokat ad vissza egy vezénylő függvénynek. A tevékenységfüggvények visszatérési értékei mindig biztonságosan visszajátszhatók, mert el vannak mentve az orchestrációs előzményekbe.
Alternatív megoldásként használhat véletlenszerű számgenerátort rögzített magértékkel közvetlenül egy vezénylőfüggvényben. Ez a módszer mindaddig biztonságos, amíg az egyes vezénylési visszajátszásokhoz ugyanazt a számsorozatot hozza létre.
Egy tevékenység használatával véletlenszerű számokat ad vissza egy vezénylőnek. A tevékenységek visszatérési értékei mindig biztonságosak a visszajátszáshoz, mert elmentésre kerülnek az orchestrációs előzményekbe.
Alternatív megoldásként közvetlenül egy orchestration rendszerben használhat véletlenszám-generátort rögzített magértékkel. Ez a módszer mindaddig biztonságos, amíg az egyes vezénylési visszajátszásokhoz ugyanazt a számsorozatot hozza létre.
Kötések
Ne használjon kötéseket orkestrációs függvényekben, beleértve az orkestrációs ügyfél - és a entitásügyfél-kötéseket is. Bemeneti és kimeneti kötéseket csak ügyfél- vagy tevékenységfüggvényekben használhat. Az Orchestrator függvények többször is lejátszhatók, ami nemdeterminista és duplikált I/O-t okoz külső rendszerekkel.
Az vezénylők nem végezhetnek közvetlen I/O-műveleteket külső rendszerekkel. Az input/output műveletek áthelyezése tevékenységekre. A vezénylők többször is újrajátszhatók, ami nem determinisztikus és duplikált I/O-t okozhat külső rendszerekkel.
Statikus változók
A statikus változók idővel változhatnak, így nem biztonságosak a vezénylő függvények számára. Kerülje a statikus változók használatát a vezénylő függvényekben, mert az értékek idővel változhatnak, ami nem meghatározott futásidejű viselkedést eredményez. Ehelyett használjon állandókat, vagy korlátozza a statikus változók használatát a tevékenységfüggvényekre.
A statikus változók idővel változhatnak, így nem biztonságosak a vezénylők számára. Kerülje a statikus változók használatát a vezénylőkben, mert az értékek idővel változhatnak, ami nemdeterminista futtatókörnyezeti viselkedést eredményez. Ehelyett használjon állandókat, vagy korlátozza a statikus változók használatát tevékenységekre.
Megjegyzés:
A Azure Functions statikus változóinak használata a vezénylő függvényeken kívül is problémás lehet, mivel nincs garancia arra, hogy a statikus állapot több függvény végrehajtása során is megmarad. Kerülje a statikus változókat, kivéve bizonyos használati eseteket, például a memóriabeli gyorsítótárazást a tevékenységben vagy entitásfüggvényekben.
Környezeti változók
A vezénylő függvények környezeti változói idővel változhatnak, ami nemdeterminista futtatókörnyezeti viselkedést eredményez. Ha egy vezénylőfüggvénynek környezeti változóban meghatározott konfigurációra van szüksége, a konfigurációs értéket bemenetként vagy tevékenységfüggvény visszatérési értékeként kell átadnia a vezénylő függvénynek.
A vezénylők környezeti változói idővel változhatnak, ami nemdeterminista futtatókörnyezeti viselkedést eredményez. Ha egy vezénylőnek környezeti változóban meghatározott konfigurációra van szüksége, a konfigurációs értéket bemenetként vagy egy tevékenység visszatérési értékeként kell átadnia a vezénylőnek.
Hálózat és HTTP
Használj tevékenységfüggvényeket kimenő hálózati hívások indításához. Ha HTTP-hívást kell kezdeményeznie a vezénylő függvényből, használhatja a tartós HTTP API-kat is.
Tevékenységek használata kimenő hálózati hívások indításához. Az vezénylőknek soha nem szabad közvetlen HTTP-hívásokat vagy más hálózati kéréseket kezdeményeznie, mert ezek a műveletek nem meghatározottak.
Szálblokkoló API-k
A sleep api-k blokkolása teljesítménybeli és méretezési problémákat okozhat a vezénylő függvények esetében, és szükségtelen végrehajtási időköltségeket eredményezhet a Azure Functions Használati tervben. Használjon alternatív megoldásokat, ha elérhetők. Tartós időzítőkkel például olyan késéseket hozhat létre, amelyek biztonságosak az újrajátszáshoz, és nem számítanak bele a vezénylés végrehajtási idejébe.
Az olyan API-k blokkolása, mint az "alvás" teljesítménybeli és méretezési problémákat okozhat a vezénylők számára, ezért kerülni kell. Megbízható időzítőket használjon olyan késleltetések létrehozásához, amelyek biztonságosan használhatók az újrajátszáshoz.
Használja context.CreateTimer() helyett Task.Delay() vagy Thread.Sleep().
// Don't use Task.Delay() or Thread.Sleep()
// Use context.CreateTimer() instead
await context.CreateTimer(context.CurrentUtcDateTime.AddMinutes(5), CancellationToken.None);
Async API-k
Az orchestrator-kódnak soha nem szabad aszinkron műveletet elindítania, kivéve a vezénylési eseményindító környezeti objektuma által meghatározott műveleteket. Soha ne használjon például Task.Run, Task.Delay és HttpClient.SendAsync .NET vagy setTimeout és setInterval JavaScriptben. A vezénylő függvények csak tartós SDK API-k használatával ütemezhetnek aszinkron munkát, például ütemezési tevékenységfüggvényeket. Minden más típusú aszinkron meghívást a tevékenységfüggvényeken belül kell végrehajtani.
Az orchestrator-kódnak soha nem szabad aszinkron műveletet elindítania, kivéve a vezénylési környezet objektuma által meghatározott műveleteket. Például soha ne használja a Task.Run, Task.Delay és HttpClient.SendAsync elemeket a .NET-ben. A vezénylőknek csak aszinkron munkát kell ütemezni a Durable Task SDK API-kkal, például az ütemezési tevékenységekkel. Minden más típusú aszinkron meghívást a tevékenységeken belül kell végrehajtani.
Aszinkron JavaScript-függvények
Deklarálja a JavaScript-vezénylő függvényeket szinkron generátorfüggvényekként. Ne deklarálja a JavaScript-vezénylő függvényeket, async mert a Node.js futtatókörnyezet nem garantálja a függvények determinisztikus viselkedését async .
Python coroutines
Ne deklarálja a Python vezérlő függvényeket korutinokként. Ne használja a async kulcsszót, mert a korutin szemantikája nem igazodik a Durable Functions visszajátszási modellhez. Deklarálja a Python orchestrator függvényeket generátorként, és használja a yield a await helyett a context API-val.
Nem deklarálhat Python orchestrátorokat korutinokként. Más szóval soha ne deklaráljon Python vezénylőket a async kulcsszóval, mert a coroutine szemantikája nem igazodik a Durable Task visszajátszási modelljéhez. A Python vezénylőket mindig generátorként kell deklarálnia, ami azt jelenti, hogy yield kell használnia await helyett a környezeti API-k meghívásakor.
from durabletask import task
# CORRECT - use yield (generator function)
def my_orchestrator(ctx: task.OrchestrationContext, input: str):
result = yield ctx.call_activity(my_activity, input=input)
return result
# WRONG - don't use async/await
async def bad_orchestrator(ctx: task.OrchestrationContext, input: str):
result = await ctx.call_activity(my_activity, input=input) # This won't work!
return result
.NET szálkezelés API-k
A Durable Task Framework egyetlen szálon futtat vezénylési kódot, és nem tud más szálakkal kommunikálni. Az aszinkron folytatások futtatása egy feldolgozókészlet-szálon a vezénylés végrehajtásában nem meghatározott végrehajtást vagy holtpontot eredményezhet. Ezért a vezénylő függvények szinte soha nem használhatnak szálkezelő API-kat. Például soha ne használjon ConfigureAwait(continueOnCapturedContext: false) vezénylőfüggvényben annak biztosítására, hogy a feladat folytatásai a vezénylő függvény eredeti SynchronizationContext helyén fussanak.
Megjegyzés:
A Durable Task Framework megpróbálja észlelni a nem-vezénylő szálak véletlen használatát a vezénylő függvényekben. Ha jogsértést talál, a keretrendszer egy NonDeterministicOrchestrationException kivételt eredményez. Ez az észlelési viselkedés azonban nem fog minden szabálysértést észlelni, és nem szabad attól függenie.
A Durable Task Framework egyetlen szálon futtat vezénylési kódot, és nem tud más szálakkal kommunikálni. Az aszinkron folytatások futtatása egy feldolgozókészlet-szálon a vezénylés végrehajtásában nem meghatározott végrehajtást vagy holtpontot eredményezhet. Ezért a vezénylőknek szinte soha nem szabad menetes API-kat használniuk. Például soha ne használjon ConfigureAwait(continueOnCapturedContext: false) egy orchestrátorban annak érdekében, hogy a feladatok folytatásai az eredeti orchestrátoron SynchronizationContext fussanak.
Megjegyzés:
A Durable Task Framework megpróbálja észlelni a vezénylőkben a nemvezénylő szálak véletlen használatát. Ha jogsértést talál, a keretrendszer egy NonDeterministicOrchestrationException kivételt eredményez. Ez az észlelési viselkedés azonban nem fog minden szabálysértést észlelni, és nem szabad attól függenie.
Verziókezelés
A tartós vezénylés napokig, hónapokig, évekig vagy akár örök vezénylésként is futtatható. A futtatási vezényléseket befolyásoló kódmódosítások megszakíthatják a visszajátszási viselkedést, ezért gondosan tervezze meg az alkalmazást, mielőtt frissítené. További információ: Verziószámozás.
A tartós orkesztáció napokig, hónapokig, évekig vagy akár határozatlan ideig is futtatható. A futtatási vezényléseket befolyásoló kódmódosítások megszakíthatják a visszajátszási viselkedést, ezért gondosan tervezze meg az alkalmazást, mielőtt frissítené. A gyakori verziószámozási stratégiák közé tartozik az egymás melletti üzembe helyezés és a verzióspecifikus feladatközpontok neveinek használata.
Tartós feladatok
Megjegyzés:
Ez a szakasz a Durable Task Framework belső implementációjának részleteit ismerteti. A Durable Functions használatához nem kell tudnia ezeket az információkat, de segít elmagyarázni a visszajátszási viselkedést.
A vezénylő függvényekben biztonságosan várakozó feladatokat tartós feladatoknak is nevezik. A Durable Task Framework létrehozza és kezeli ezeket a feladatokat. Ilyenek például a CallActivityAsync, WaitForExternalEvent és CreateTimer által visszaadott feladatok .NET vezénylési függvényekben.
A .NET TaskCompletionSource objektumainak listája belsőleg kezeli ezeket a tartós feladatokat. A visszajátszás során a vezénylőkód létrehozza ezeket a feladatokat. A diszpécser végrehajtja őket, miközben felsorolja a kapcsolódó előzményeseményeket.
A futtatókörnyezet szinkron módon hajtja végre a feladatokat egyetlen szálon, amíg vissza nem játssza az előzményeket. Ha egy tartós feladat nem fejeződik be az előzmények visszajátszásának végéig, a futtatókörnyezet végrehajtja a megfelelő műveleteket. A futtatókörnyezet például meghívhat egy tevékenységfüggvényt meghívó üzenetet.
Ez a futtatási viselkedés megmagyarázza, hogy a vezénylő függvény miért nem használhatja a await vagy yield egy nem-tartós feladatban. A diszpécserszál nem tudja megvárni a feladat befejezését, és a feladat visszahívásai ronthatják a vezénylő függvény nyomkövetési állapotát. A futtatókörnyezet olyan ellenőrzéseket tartalmaz, amelyek segítenek észlelni ezeket a szabálysértéseket.
A Durable Task Framework vezénylői funkcióinak végrehajtásáról a Durable Task source code on GitHub című témakörben talál további információt. Lásd: TaskOrchestrationExecutor.cs és TaskOrchestrationContext.cs.
A vezénylőkben biztonságosan várakozó feladatokat tartós feladatoknak is nevezik. A Durable Task Framework létrehozza és kezeli ezeket a feladatokat. Ilyenek például a CallActivityAsync, WaitForExternalEvent és CreateTimer által visszaadott feladatok .NET vezénylőkben.
A .NET TaskCompletionSource objektumainak listája belsőleg kezeli ezeket a tartós feladatokat. A visszajátszás során a vezénylőkód létrehozza ezeket a feladatokat. A diszpécser végrehajtja őket, miközben felsorolja a kapcsolódó előzményeseményeket.
A futtatókörnyezet szinkron módon hajtja végre a feladatokat egyetlen szálon, amíg vissza nem játssza az előzményeket. Ha egy tartós feladat nem fejeződik be az előzmények visszajátszásának végéig, a futtatókörnyezet végrehajtja a megfelelő műveleteket. A futtatókörnyezet például üzenetet jeleníthet meg egy tevékenység meghívásához.
Ez a futásidejű viselkedés megmagyarázza, hogy a vezénylő miért nem tudja használni a await vagy yield címkéket nem tartós feladatoknál. A ütemező szál nem tudja megvárni a feladat befejezését, és a feladatból érkező visszahívások ronthatják az orchestrátor nyomkövetési állapotát. A futtatókörnyezet olyan ellenőrzéseket tartalmaz, amelyek segítenek észlelni ezeket a szabálysértéseket.
Ha többet szeretne megtudni arról, hogy a Durable Task Framework hogyan hajtja végre a vezénylőket, tekintse meg a Durable Task forráskódját a GitHubon. Lásd: TaskOrchestrationExecutor.cs és TaskOrchestrationContext.cs.