A Durable Functions diagnosztikája az Azure-ban
A Durable Functions problémáinak diagnosztizálása többféleképpen is lehetséges. Ezek némelyike megegyezik a hagyományos függvényekre vonatkozó módszerekkel, mások pedig csak a Durable Functions függvényeihez használhatók.
Application Insights
Az Application Insights a diagnosztikai és monitorozási műveletek ajánlott módja az Azure Functionsben. Ugyanez vonatkozik a Durable Functionsre is. Az Application Insights függvényalkalmazásban való használatának áttekintését az Azure Functions monitorozása című témakörben tekintheti meg.
Az Azure Functions Durable Extension olyan nyomkövetési eseményeket is bocsát ki, amelyek lehetővé teszik a vezénylések végpontok közötti végrehajtásának nyomon követését. Ezek a nyomon követési események az Application Insights Analytics eszközzel találhatók és kérdezhetők le az Azure Portalon.
Adatok nyomon követése
A vezénylési példány minden életciklus-eseménye követési eseményt ír az Application Insights nyomkövetési gyűjteményéhez. Ez az esemény több mezővel rendelkező customDimensions hasznos adatokat tartalmaz. A mezőnevek mindegyike elő van állítva a következővel prop__
: .
- hubName: Annak a feladatközpontnak a neve, amelyben a vezénylések futnak.
- appName: A függvényalkalmazás neve. Ez a mező akkor hasznos, ha több függvényalkalmazás is ugyanazt az Application Insights-példányt használja.
- slotName: Az az üzembehelyezési pont , amelyen az aktuális függvényalkalmazás fut. Ez a mező akkor hasznos, ha üzembehelyezési pontok használatával verziószámozza a vezényléseket.
- functionName: A vezénylő vagy tevékenységfüggvény neve.
- functionType: A függvény típusa, például Orchestrator vagy Activity.
- instanceId: A vezénylési példány egyedi azonosítója.
- állapot: A példány életciklus-végrehajtási állapota. Az érvényes értékek a következők:
- Ütemezett: A függvény végrehajtásra lett ütemezve, de még nem indult el.
- Elindítva: A függvény elindult, de még nem várt vagy fejeződött be.
- Várva: A vezénylő tervezett néhány munkát, és várja, hogy befejeződjön.
- Figyelés: A vezénylő egy külső eseményértesítést figyel.
- Befejeződött: A függvény sikeresen befejeződött.
- Sikertelen: A függvény hiba miatt meghiúsult.
- ok: A nyomkövetési eseményhez társított további adatok. Ha például egy példány egy külső eseményértesítésre vár, ez a mező annak az eseménynek a nevét jelzi, amelyre vár. Ha egy függvény sikertelen volt, ez a mező tartalmazza a hiba részleteit.
- isReplay: Logikai érték, amely azt jelzi, hogy a nyomkövetési esemény az újrajátszott végrehajtáshoz tartozik-e.
- extensionVersion: A Durable Task bővítmény verziója. A verzióinformációk különösen fontos adatok a bővítmény lehetséges hibáinak jelentésekor. A hosszan futó példányok több verziót is jelenthetnek, ha egy frissítés fut.
- sequenceNumber: Egy esemény végrehajtási sorszáma. Az időbélyeggel kombinálva a végrehajtási idő alapján rendezheti az eseményeket. Vegye figyelembe, hogy ez a szám nullára lesz visszaállítva, ha a gazdagép újraindul a példány futása közben, ezért fontos, hogy mindig időbélyeg szerint rendezze először, majd a sequenceNumber függvényt.
Az Application Insightsnak küldött nyomkövetési adatok részletessége konfigurálható a logger
fájl (Functions 1.x) vagy logging
(Functions 2.0) szakaszában host.json
.
Functions 1.0
{
"logger": {
"categoryFilter": {
"categoryLevels": {
"Host.Triggers.DurableTask": "Information"
}
}
}
}
Functions 2.0
{
"logging": {
"logLevel": {
"Host.Triggers.DurableTask": "Information",
},
}
}
Alapértelmezés szerint minden nem visszajátszáskövetési esemény ki lesz bocsátva. Az adatok mennyisége csökkenthető úgy, hogy beállítja Host.Triggers.DurableTask
vagy "Warning"
"Error"
ebben az esetben a nyomon követési események csak kivételes helyzetekben lesznek kibocsátva. A részletes vezénylési újrajátszási események kibocsátásához állítsa be a logReplayEvents
true
beállítást a host.json konfigurációs fájlban.
Feljegyzés
Alapértelmezés szerint az Azure Functions-futtatókörnyezet mintavételezi az Application Insights telemetriát, hogy elkerülje az adatok túl gyakran történő kibocsájtását. Ez azt okozhatja, hogy a nyomon követési adatok elvesznek, ha rövid időn belül számos életciklus-esemény történik. Az Azure Functions Monitorozási cikk bemutatja, hogyan konfigurálhatja ezt a viselkedést.
A vezénylő, tevékenység és entitásfüggvények bemeneteit és kimeneteit alapértelmezés szerint nem naplózza a rendszer. Ez az alapértelmezett viselkedés azért ajánlott, mert a bemenetek és kimenetek naplózása növelheti az Application Insights költségeit. A függvénybemenet és a kimeneti hasznos adatok bizalmas információkat is tartalmazhatnak. Ehelyett alapértelmezés szerint a függvénybemenetek és -kimenetek bájtjainak száma lesz naplózva a tényleges hasznos adatok helyett. Ha azt szeretné, hogy a Durable Functions bővítmény naplózza a teljes bemeneti és kimeneti hasznos adatokat, állítsa be a traceInputsAndOutputs
tulajdonságot true
a host.json konfigurációs fájlba.
Egypéldányos lekérdezés
Az alábbi lekérdezés a Hello Sequence függvény vezénylésének egyetlen példányára vonatkozó előzménykövetési adatokat mutatja be. A Kusto lekérdezésnyelv íródott. Kiszűri a visszajátszás végrehajtását, így csak a logikai végrehajtási útvonal jelenik meg. Az események rendezhetők az alábbi lekérdezés szerint timestamp
és sequenceNumber
módon:
let targetInstanceId = "ddd1aaa685034059b545eb004b15d4eb";
let start = datetime(2018-03-25T09:20:00);
traces
| where timestamp > start and timestamp < start + 30m
| where customDimensions.Category == "Host.Triggers.DurableTask"
| extend functionName = customDimensions["prop__functionName"]
| extend instanceId = customDimensions["prop__instanceId"]
| extend state = customDimensions["prop__state"]
| extend isReplay = tobool(tolower(customDimensions["prop__isReplay"]))
| extend sequenceNumber = tolong(customDimensions["prop__sequenceNumber"])
| where isReplay != true
| where instanceId == targetInstanceId
| sort by timestamp asc, sequenceNumber asc
| project timestamp, functionName, state, instanceId, sequenceNumber, appName = cloud_RoleName
Az eredmény azoknak a nyomon követési eseményeknek a listája, amelyek a vezénylés végrehajtási útvonalát jelenítik meg, beleértve a végrehajtási idő által növekvő sorrendben rendezett tevékenységfüggvényeket is.
Példányösszegző lekérdezés
Az alábbi lekérdezés megjeleníti a megadott időtartományban futtatott vezénylési példányok állapotát.
let start = datetime(2017-09-30T04:30:00);
traces
| where timestamp > start and timestamp < start + 1h
| where customDimensions.Category == "Host.Triggers.DurableTask"
| extend functionName = tostring(customDimensions["prop__functionName"])
| extend instanceId = tostring(customDimensions["prop__instanceId"])
| extend state = tostring(customDimensions["prop__state"])
| extend isReplay = tobool(tolower(customDimensions["prop__isReplay"]))
| extend output = tostring(customDimensions["prop__output"])
| where isReplay != true
| summarize arg_max(timestamp, *) by instanceId
| project timestamp, instanceId, functionName, state, output, appName = cloud_RoleName
| order by timestamp asc
Az eredmény a példányazonosítók listája és az aktuális futtatókörnyezeti állapotuk.
Tartós feladat-keretrendszer naplózása
A Durable bővítménynaplók hasznosak a vezénylési logika viselkedésének megértéséhez. Ezek a naplók azonban nem mindig tartalmaznak elegendő információt a keretrendszerszintű teljesítmény- és megbízhatósági problémák hibakereséséhez. A Durable bővítmény 2.3.0-s verziójától kezdve a mögöttes Durable Task Framework (DTFx) által kibocsátott naplók is elérhetők a gyűjteményhez.
A DTFx által kibocsátott naplók megtekintésekor fontos tisztában lenni azzal, hogy a DTFx motor két összetevőből áll: az alapvető diszpécsermotorból (DurableTask.Core
) és a számos támogatott tárolószolgáltató közül (a Durable Functions alapértelmezés szerint használja DurableTask.AzureStorage
, de más lehetőségek is rendelkezésre állnak).
- DurableTask.Core: Alapvető vezénylési végrehajtás és alacsony szintű ütemezési naplók és telemetriai adatok.
- DurableTask.AzureStorage: Az Azure Storage-állapotszolgáltatóra jellemző háttérnaplók. Ezek a naplók részletes interakciókat tartalmaznak a belső üzenetsorokkal, blobokkal és tárolótáblákkal a belső vezénylési állapot tárolásához és lekéréséhez.
- DurableTask.Netherite: Ha engedélyezve van, a Netherite-tárolószolgáltatóra vonatkozó háttérnaplók.
- DurableTask.SqlServer: Ha engedélyezve van, a Microsoft SQL (MSSQL) tárolószolgáltatójának háttérnaplói.
Ezeket a naplókat a függvényalkalmazás host.json fájljának szakaszának frissítésével logging/logLevel
engedélyezheti. Az alábbi példa bemutatja, hogyan engedélyezheti a figyelmeztetési és hibanaplókat mind a kettőbőlDurableTask.Core
:DurableTask.AzureStorage
{
"version": "2.0",
"logging": {
"logLevel": {
"DurableTask.AzureStorage": "Warning",
"DurableTask.Core": "Warning"
}
}
}
Ha engedélyezve van az Application Insights, a rendszer automatikusan hozzáadja ezeket a naplókat a trace
gyűjteményhez. Ugyanúgy kereshet bennük, mint más naplókban trace
a Kusto-lekérdezések használatával.
Feljegyzés
Éles alkalmazások esetén ajánlott engedélyezni DurableTask.Core
, és a megfelelő tárolószolgáltató (például DurableTask.AzureStorage
) naplóit a "Warning"
szűrő használatával. A nagyobb részletességű szűrők, például "Information"
nagyon hasznosak a teljesítményproblémák hibakereséséhez. Ezek a naplóesemények azonban nagy mennyiségűek lehetnek, és jelentősen növelhetik az Application Insights adattárolási költségeit.
Az alábbi Kusto-lekérdezés bemutatja, hogyan kérdezhet le DTFx-naplókat. A lekérdezés legfontosabb része az, where customerDimensions.Category startswith "DurableTask"
hogy szűri az eredményeket a naplókba és DurableTask.AzureStorage
a DurableTask.Core
kategóriákba.
traces
| where customDimensions.Category startswith "DurableTask"
| project
timestamp,
severityLevel,
Category = customDimensions.Category,
EventId = customDimensions.EventId,
message,
customDimensions
| order by timestamp asc
Az eredmény a Durable Task Framework naplószolgáltatói által írt naplók halmaza.
A naplóeseményekről további információt a Durable Task Framework strukturált naplózási dokumentációjában talál a GitHubon.
Alkalmazásnaplózás
Fontos szem előtt tartani a vezénylő visszajátszási viselkedését, amikor naplókat ír közvetlenül egy vezénylő függvényből. Vegyük például a következő vezénylő függvényt:
[FunctionName("FunctionChain")]
public static async Task Run(
[OrchestrationTrigger] IDurableOrchestrationContext context,
ILogger log)
{
log.LogInformation("Calling F1.");
await context.CallActivityAsync("F1");
log.LogInformation("Calling F2.");
await context.CallActivityAsync("F2");
log.LogInformation("Calling F3");
await context.CallActivityAsync("F3");
log.LogInformation("Done!");
}
Az eredményként kapott naplóadatok a következő példakimenethez hasonlóan fognak kinézni:
Calling F1.
Calling F1.
Calling F2.
Calling F1.
Calling F2.
Calling F3.
Calling F1.
Calling F2.
Calling F3.
Done!
Feljegyzés
Ne feledje, hogy bár a naplók F1, F2 és F3 hívásra hivatkoznak, ezek a függvények csak akkor lesznek ténylegesen meghívva, amikor először találkoznak. A rendszer kihagyja a visszajátszás során felmerülő további hívásokat, és a kimeneteket visszajátssza a vezénylő logikába.
Ha csak nem visszajátszásos végrehajtásokra szeretne naplókat írni, akkor csak akkor írhat feltételes kifejezést a naplóhoz, ha az "ismétlés" jelzője .false
Vegyük a fenti példát, de ezúttal visszajátszási ellenőrzésekkel.
[FunctionName("FunctionChain")]
public static async Task Run(
[OrchestrationTrigger] IDurableOrchestrationContext context,
ILogger log)
{
if (!context.IsReplaying) log.LogInformation("Calling F1.");
await context.CallActivityAsync("F1");
if (!context.IsReplaying) log.LogInformation("Calling F2.");
await context.CallActivityAsync("F2");
if (!context.IsReplaying) log.LogInformation("Calling F3");
await context.CallActivityAsync("F3");
log.LogInformation("Done!");
}
A Durable Functions 2.0-tól kezdve a .NET vezénylő függvények is létrehozhatnak egy ILogger
olyan parancsot, amely automatikusan kiszűri a naplókivonatokat a visszajátszás során. Ez az automatikus szűrés az IDurableOrchestrationContext.CreateReplaySafeLogger(ILogger) API használatával történik.
[FunctionName("FunctionChain")]
public static async Task Run(
[OrchestrationTrigger] IDurableOrchestrationContext context,
ILogger log)
{
log = context.CreateReplaySafeLogger(log);
log.LogInformation("Calling F1.");
await context.CallActivityAsync("F1");
log.LogInformation("Calling F2.");
await context.CallActivityAsync("F2");
log.LogInformation("Calling F3");
await context.CallActivityAsync("F3");
log.LogInformation("Done!");
}
Feljegyzés
Az előző C#-példák a Durable Functions 2.x-hez tartoznak. A Durable Functions 1.x esetén a helyett IDurableOrchestrationContext
a DurableOrchestrationContext
. A verziók közötti különbségekről további információt a Durable Functions verzióiról szóló cikkben talál.
A korábban említett módosítások esetén a napló kimenete a következő:
Calling F1.
Calling F2.
Calling F3.
Done!
Egyéni állapot
Az egyéni vezénylési állapot lehetővé teszi egyéni állapotérték beállítását a vezénylő függvényhez. Ez az egyéni állapot ezután látható a külső ügyfelek számára a HTTP-állapot lekérdezési API-val vagy nyelvspecifikus API-hívásokkal. Az egyéni vezénylési állapot lehetővé teszi a vezénylő függvények részletesebb monitorozását. A vezénylő függvénykódja például meghívhatja az "egyéni állapot beállítása" API-t egy hosszú ideig futó művelet előrehaladásának frissítéséhez. Egy ügyfél, például egy weblap vagy más külső rendszer, ezt követően rendszeres időközönként lekérdezheti a HTTP állapot lekérdezési API-jait a részletesebb előrehaladási információk érdekében. A vezénylőfüggvények egyéni állapotértékének beállítására szolgáló mintakódot az alábbiakban találja:
[FunctionName("SetStatusTest")]
public static async Task SetStatusTest([OrchestrationTrigger] IDurableOrchestrationContext context)
{
// ...do work...
// update the status of the orchestration with some arbitrary data
var customStatus = new { completionPercentage = 90.0, status = "Updating database records" };
context.SetCustomStatus(customStatus);
// ...do more work...
}
Feljegyzés
Az előző C# példa a Durable Functions 2.x-hez készült. A Durable Functions 1.x esetén a helyett IDurableOrchestrationContext
a DurableOrchestrationContext
. A verziók közötti különbségekről további információt a Durable Functions verzióiról szóló cikkben talál.
Amíg a vezénylés fut, a külső ügyfelek lekérhetik ezt az egyéni állapotot:
GET /runtime/webhooks/durabletask/instances/instance123?code=XYZ
Az ügyfelek a következő választ kapják:
{
"runtimeStatus": "Running",
"input": null,
"customStatus": { "completionPercentage": 90.0, "status": "Updating database records" },
"output": null,
"createdTime": "2017-10-06T18:30:24Z",
"lastUpdatedTime": "2017-10-06T19:40:30Z"
}
Figyelmeztetés
Az egyéni állapot hasznos adatai legfeljebb 16 KB UTF-16 JSON-szövegre korlátozódnak, mert el kell férnie egy Azure Table Storage-oszlopban. Ha nagyobb hasznos adatra van szüksége, külső tárolót is használhat.
Elosztott nyomkövetés
Az elosztott nyomkövetés nyomon követi a kéréseket, és bemutatja, hogy a különböző szolgáltatások hogyan kommunikálnak egymással. A Durable Functionsben a vezényléseket és a tevékenységeket is korrelálja. Ez hasznos annak megértéséhez, hogy a vezénylés mennyi időt vesz igénybe a teljes vezényléshez képest. Az is hasznos, ha tisztában van azzal, hogy egy alkalmazás hol tapasztal problémát, vagy hol történt kivétel. Ez a funkció minden nyelvhez és társzolgáltatóhoz támogatott.
Feljegyzés
Az elosztott nyomkövetési V2-hez a Durable Functions 2.12.0-s vagy újabb verziójára van szükség. Az elosztott nyomkövetési V2 is előzetes verziójú, ezért egyes Durable Functions-minták nem lettek kialakítva. A Tartós entitások műveletek például nem rendszerezettek, és a nyomkövetések nem jelennek meg az Application Insightsban.
Elosztott nyomkövetés beállítása
Az elosztott nyomkövetés beállításához frissítse a host.json, és állítson be egy Application Insights-erőforrást.
host.json
"durableTask": {
"tracing": {
"distributedTracingEnabled": true,
"Version": "V2"
}
}
Application Insights
Ha a függvényalkalmazás nincs Application Insights-erőforrással konfigurálva, akkor az itt leírt utasításokat követve konfigurálja.
A nyomok vizsgálata
Az Application Insights-erőforrásban lépjen a Tranzakciókeresés elemre. Az eredményekben ellenőrizze Request
Dependency
a Durable Functions-specifikus előtagokkal (pl. orchestration:
, activity:
stb.) kezdődő eseményeket. Ha kiválaszt egy ilyen eseményt, megnyit egy Gantt-diagramot, amely a végpontok közötti elosztott nyomkövetést jeleníti meg.
Hibaelhárítás
Ha nem látja a nyomkövetéseket az Application Insightsban, győződjön meg arról, hogy az alkalmazás futtatása után körülbelül öt percet kell várnia, hogy az összes adat propagálása az Application Insights-erőforrásba történjen.
Hibakeresés
Az Azure Functions közvetlenül támogatja a függvénykód hibakeresését, és ugyanez a támogatás továbbviszi a Durable Functionst, akár az Azure-ban, akár helyileg fut. A hibakereséskor azonban érdemes néhány viselkedést figyelembe venni:
- Visszajátszás: Az Orchestrator rendszeresen újrajátszja az új bemenetek fogadását. Ez a viselkedés azt jelenti, hogy egy vezénylőfüggvény egyetlen logikai végrehajtása ugyanazt a töréspontot többször is elérheti, különösen akkor, ha a függvénykód elején van beállítva.
- Várjon: Amikor egy vezénylő függvényben talál egy
await
hibát, az visszaveti az irányítást a Durable Task Framework diszpécsernek. Ha ez az első alkalom, hogy egy adottawait
feladatba ütközik, a társított tevékenység soha nem folytatódik. Mivel a feladat soha nem folytatódik, nem lehet túllépni a várakozáson (F10 a Visual Studióban). Az átlépés csak akkor működik, ha egy feladat visszajátszása történik. - Üzenetküldési időtúllépések: A Durable Functions belsőleg üzenetsor-üzeneteket használ a vezénylő, a tevékenység és az entitásfüggvények végrehajtásának ösztönzésére. Több virtuálisgép-környezetben a hibakeresés hosszabb ideig történő betörésével egy másik virtuális gép is átveheti az üzenetet, ami duplikált végrehajtást eredményezhet. Ez a viselkedés a rendszeres üzenetsor-eseményindító függvények esetében is létezik, de ebben a kontextusban fontos kiemelni, mivel az üzenetsorok implementálási részletek.
- Leállítás és indítás: A Durable függvényekben lévő üzenetek továbbra is megmaradnak a hibakeresési munkamenetek között. Ha leállítja a hibakeresést, és leállítja a helyi gazdagépfolyamatot egy tartós függvény végrehajtása közben, a függvény automatikusan újrafuthat egy későbbi hibakeresési munkamenetben. Ez a viselkedés zavaró lehet, ha nem várható. Ennek a viselkedésnek a elkerülése érdekében egy új tevékenységközpont használata vagy a feladatközpont tartalmának törlése a hibakeresési munkamenetek között.
Tipp.
Ha a vezénylő függvények töréspontjait állítja be, ha csak a nem visszajátszásos végrehajtást szeretné megszakítani, akkor beállíthat egy feltételes töréspontot, amely csak akkor törik meg, ha az "ismétlés" értéke .false
Tárolás
Alapértelmezés szerint a Durable Functions az Azure Storage-ban tárolja az állapotot. Ez a viselkedés azt jelenti, hogy az olyan eszközökkel, mint a Microsoft Azure Storage Explorer, megvizsgálhatja a vezénylések állapotát.
Ez azért hasznos a hibakereséshez, mert pontosan láthatja, hogy milyen állapotban lehet egy vezénylés. Az üzenetsorokban lévő üzeneteket is megvizsgálhatja, hogy megtudja, mi a függőben lévő munka (vagy néhány esetben elakadt).
Figyelmeztetés
Bár kényelmesen megtekintheti a végrehajtási előzményeket a táblatárolóban, ne függjön a táblától. A Durable Functions bővítmény fejlődésével változhat.
Feljegyzés
Az alapértelmezett Azure Storage-szolgáltató helyett más tárolószolgáltatók is konfigurálhatók. Az alkalmazáshoz konfigurált tárolószolgáltatótól függően előfordulhat, hogy a mögöttes állapot vizsgálatához különböző eszközöket kell használnia. További információkért tekintse meg a Durable Functions Storage-szolgáltatók dokumentációját.
Durable Functions Monitor
A Durable Functions Monitor egy grafikus eszköz a vezénylési és entitáspéldányok monitorozására, kezelésére és hibakeresésére. Visual Studio Code-bővítményként vagy önálló alkalmazásként érhető el. A beállítással és a funkciók listájával kapcsolatos információk ebben a wikiben találhatók.
A Durable Functions hibaelhárítási útmutatója
Az olyan gyakori problémák elhárításához, mint a elakadt vezénylések, a sikertelen indítás, a lassú futás stb., tekintse meg ezt a hibaelhárítási útmutatót.