Verziószámozási kihívások és kockázatcsökkentési stratégiák a Durable Functions

A Durable Functions verziószámozása alapvető fontosságú, mert a függvények elkerülhetetlenül hozzáadódnak, eltávolíthatók és módosulnak az alkalmazás élettartama során. Durable Functions lehetővé teszi a függvények összekapcsolását olyan módon, amely korábban nem volt lehetséges, és ez a láncolás hatással van a verziószámozás kezelésére.

Ez a cikk a következőkben nyújt segítséget:

Gyors stratégia összehasonlítása

Ha már tudja, hogy a módosítás kompatibilitástörő, használja ezt a táblázatot a kockázatcsökkentési stratégia kiválasztásához:

Strategy Legjobb a számára Részletek
Orkesztráció verziószámozás (ajánlott) A legtöbb alkalmazás jelentős változásokkal. A beépített futtatókörnyezeti funkció bármilyen háttérrendszerrel működik. Ugrás a fejezetre
Párhuzamos telepítések Azok az alkalmazások, amelyek nem használhatják a vezénylési verziószámozást, vagy teljes elkülönítést igényelnek külön feladatközpontokon vagy tárfiókokon keresztül. Ugrás a fejezetre
Az összes folyamatban lévő példány leállítása Prototípus-készítés és helyi fejlesztés, ahol a repülés közbeni vezénylések elvesztése elfogadható. Ugrás a fejezetre

Tip

Ha olyan beépített orchestration verziószámozási funkciót keres, amely futásidőben automatikus verzióelkülönítést biztosít, tekintse meg az Orchestration verziószámozás részt.

Important

Az üzembe helyezés előtt ellenőrizze, hogy a módosítás kompatibilitástörő változás-e:

  • Módosította egy tevékenység vagy entitásfüggvény nevét, bemeneti típusát vagy kimeneti típusát ?
  • A vezénylési kódban tevékenységeket, részvezényléseket, időzítőket vagy külső eseményeket vett fel, távolított el vagy átrendezett ?
  • Átnevezett vagy eltávolított egy olyan függvényt, amelyet a repülés közbeni vezénylések továbbra is meghívhatnak?

Ha bármelyikre igennel válaszolt, használja az alábbi kockázatcsökkentési stratégiák egyikét, hogy elkerülje a vezénylések futtatásának hibáit.

A kompatibilitástörő változások típusai

Számos példa van a kompatibilitást megszakító változásokra. Ez a cikk a leggyakoribb típusokat ismerteti. Mindegyik mögött az a fő téma, hogy a függvénykód módosítása hatással van az új és a meglévő függvényvezénylésekre is.

Tevékenység- vagy entitásfüggvény-aláírás módosítása

Az aláírás módosítása egy függvény nevének, bemenetének vagy kimenetének változására utal. Ha ilyen típusú módosítást végez egy tevékenység- vagy entitásfüggvényen, az megszakíthatja az attól függő orkesztáló függvényeket. Ez a viselkedés különösen igaz a típusbiztos nyelvekre. Ha a módosításnak megfelelően frissíti az orchestration függvényt, megszakíthatja a meglévő, folyamatban lévő példányokat.

Vegyük például a következő vezénylő függvényt.

[FunctionName("FooBar")]
public static Task Run([OrchestrationTrigger] IDurableOrchestrationContext context)
{
    bool result = await context.CallActivityAsync<bool>("Foo");
    await context.CallActivityAsync("Bar", result);
}

Ez a függvény a Foo eredményét veszi fel, és átadja a Bar-nak. Tegyük fel, hogy a Foo visszatérési értékét logikai értékről sztringre kell módosítania az eredményértékek szélesebb körének támogatásához. Az eredmény így néz ki:

[FunctionName("FooBar")]
public static Task Run([OrchestrationTrigger] IDurableOrchestrationContext context)
{
    string result = await context.CallActivityAsync<string>("Foo");
    await context.CallActivityAsync("Bar", result);
}

Ez a módosítás a vezénylő függvény összes új példánya esetében jól működik, de megszakíthatja a repülés közbeni példányokat. Vegyük például azt az esetet, amikor egy vezénylési példány meghív egy nevű Foofüggvényt, visszaad egy logikai értéket, majd ellenőrzőpontokat. Ha az aláírás módosítása ezen a ponton van üzembe helyezve, az ellenőrzőponttal megadott példány azonnal meghiúsul, amikor újraindul, és visszajátssza a hívást Foo. Ez a hiba azért fordul elő, mert az előzménytáblában szereplő eredmény logikai érték, de az új kód megpróbálja sztringértékké deszerializálni, ami váratlan viselkedést vagy futásidejű kivételt eredményez a típusbiztos nyelvek esetében.

Ez a példa egyike annak a számos módszernek, amellyel a függvényszignatúra módosítása megtörheti a meglévő példányokat. Általánosságban elmondható, hogy ha egy vezénylőnek módosítania kell a függvények hívását, akkor a változás valószínűleg problémás lesz.

Az Orchestrator logikájának változásai

A verziószámozási problémák másik osztálya a vezénylő függvény kódjának olyan módosításából ered, amely megváltoztatja a repülés közbeni példányok végrehajtási útvonalát.

Vegye figyelembe a következő orchestrátor függvényt:

[FunctionName("FooBar")]
public static Task Run([OrchestrationTrigger] IDurableOrchestrationContext context)
{
    bool result = await context.CallActivityAsync<bool>("Foo");
    await context.CallActivityAsync("Bar", result);
}

Most tegyük fel, hogy új függvényhívást szeretne hozzáadni a két meglévő függvényhívás között.

[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);
}

Ez a módosítás egy új függvényhívást ad hozzá SendNotification és Foo között Bar. Nincsenek aláírásmódosítások. A probléma akkor jelentkezik, ha egy meglévő példány újraindul a hívásból Bar. Visszajátszás során, ha az eredeti Foo hívás true-et adott vissza, akkor a vezénylő a SendNotification-be hív, amely nincs benne a végrehajtási előzményeiben. A futtatókörnyezet észleli ezt az inkonzisztenciát, és nem determinisztikus vezénylési hibát jelez, mert hívást észlelt SendNotification, amikor a Bar hívást várta. Ugyanez a probléma akkor fordulhat elő, ha API-hívásokat ad hozzá más tartós műveletekhez, például tartós időzítőket hoz létre, külső eseményekre vár, vagy al-vezényléseket hív meg.

Kockázatcsökkentési stratégiák

Warning

A kompatibilitástörő módosítások kockázatcsökkentési stratégia nélkül történő üzembe helyezése (a "do nothing" megközelítés) miatt a vezénylések nemdeterminista vezénylési hibákkal meghiúsulhatnak, határozatlan ideig elakadhatnak egy Running állapotban, vagy alacsony szintű futásidejű hibákat válthatnak ki, amelyek rontják a teljesítményt. A kompatibilitástörő módosítások üzembe helyezésekor mindig használja az alábbi stratégiák egyikét.

A jelen szakaszban szereplő többi stratégiával ellentétben a vezénylési verziószámozás egy beépített futtatókörnyezeti funkció , amely automatikus verzióelkülönítést biztosít. Nem kell külön üzembe helyezéseket, feladatközpontokat vagy tárfiókokat kezelnie. Ehelyett maga a futtatókörnyezet nyomon követi a verzióinformációkat, és biztosítja, hogy a vezénylési példányokat kompatibilis feldolgozók dolgozzák fel.

Orkesztráció verziószámozással:

  • Minden vezénylési példány létrehozásakor véglegesen hozzá van rendelve egy verzió.
  • Az Orchestrator-függvények ennek megfelelően meg tudják vizsgálni a verziójukat és az ágvégrehajtásukat, így a régi és az új kódútvonalak ugyanabban a kódbázisban maradnak.
  • Az újabb verziójú vezénylő függvényt futtató munkavállalók továbbra is végrehajthatják a régebbi verziók által létrehozott vezénylési példányokat.
  • A futtatókörnyezet megakadályozza, hogy a régebbi orkesztátorfunkció-verziókat futtató dolgozók orkesztálásokat hajtsanak végre újabb verziójú rendszerekkel.

Ez a megközelítés minimális konfigurálást igényel (verziósztringet és opcionális egyeztetési stratégiát), és kompatibilis bármely társzolgáltatóval. Ez az ajánlott stratégia azokhoz az alkalmazásokhoz, amelyeknek támogatniuk kell a kompatibilitástörő változásokat a nulla állásidős üzemelő példányok fenntartása mellett.

Részletes konfigurációs és megvalósítási útmutatásért tekintse meg az Orchestration verziószámozását.

Az összes folyamatban lévő példány leállítása

Egy másik lehetőség az összes fedélzeti példány leállítása. Ha az alapértelmezett Azure Storage szolgáltatót használja a Durable Functions esetében, állítsa le az összes példányt a belső control-queue és workitem-queue sorrendektartalmának törlésével. Másik lehetőségként állítsa le a függvényalkalmazást, törölje ezeket az üzenetsorokat, és indítsa újra az alkalmazást. Az üzenetsorok automatikusan újra létrejönnek az alkalmazás újraindítása után. Előfordulhat, hogy a korábbi orchestration példányok határozatlan ideig "Futó" állapotban maradnak, de nem zsúfolják tele a naplóit hibaüzenetekkel, és nem okoznak semmilyen kárt az alkalmazásban. Ez a megközelítés ideális a prototípus gyors fejlesztéséhez, beleértve a helyi fejlesztést is.

Warning

Ez a megközelítés közvetlen hozzáférést igényel az alapul szolgáló tárolási erőforrásokhoz, és nem megfelelő az Durable Functions által támogatott összes tárolószolgáltató számára.

Párhuzamos üzemelő példányok

A kompatibilitástörő módosítások biztonságos üzembe helyezésének legbiztosabb módja az, ha a régebbi verziók mellett helyezi üzembe őket. Az alábbi technikák egyikét használhatja:

  • Különböző tárfiók: Az összes frissítés üzembe helyezése új függvényalkalmazásként egy másik tárfiókkal. Ez teljesen elkülöníti az új verzió állapotát a régi verziótól.
  • Eltérő feladatközpont: A függvényalkalmazás új példányának üzembe helyezése ugyanazzal a tárfiókkal, de frissített feladatközpont-névvel . Ez a módszer új tárolási összetevőket hoz létre az új verzióhoz, míg a régi verzió továbbra is használja a meglévő összetevőket.

A Azure egymás melletti üzembe helyezésekor a deployment-tárolóhelyek használatával egyszerre futtathatja a két verziót egyetlen aktív produkciós ponttal. Ha készen áll az új vezénylési logika elérhetővé tételére, cserélje le az új verzióra az éles környezetben.

Note

Ez az útmutató Azure Storage-specifikus kifejezéseket használ, de általában az összes támogatott Durable Functions társzolgáltatóra vonatkozik.

Note

Az üzembehelyezési pontok felcserélése a HTTP- és webhook-eseményindítókkal működik a legjobban. Nem HTTP-eseményindítók, például üzenetsorok vagy Event Hubs esetén az eseményindító definíciójának olyan alkalmazásbeállításból kell származnia , amely a felcserélési művelet részeként frissül.

Következő lépések