Megosztás a következőn keresztül:


Az áramkör-megszakító minta implementálása

Tipp.

Ez a tartalom egy részlet a .NET-alkalmazásokhoz készült .NET-alkalmazásokhoz készült eBook, .NET Microservices Architecture című eBookból, amely elérhető a .NET Docs-on vagy egy ingyenesen letölthető PDF-fájlként, amely offline módban is olvasható.

.NET Microservices Architecture for Containerized .NET Applications eBook cover thumbnail.

Ahogy korábban már említettük, olyan hibákat kell kezelnie, amelyek helyreállítása változó ideig tarthat, ahogy az is előfordulhat, amikor távoli szolgáltatáshoz vagy erőforráshoz próbál csatlakozni. Az ilyen típusú hibák kezelése javíthatja az alkalmazások stabilitását és rugalmasságát.

Elosztott környezetben a távoli erőforrásokra és szolgáltatásokra irányuló hívások átmeneti hibák, például lassú hálózati kapcsolatok és időtúllépések miatt meghiúsulhatnak, vagy ha az erőforrások lassan válaszolnak, vagy átmenetileg nem érhetők el. Ezek a hibák általában rövid idő után kijavítják magukat, és egy robusztus felhőalkalmazásnak fel kell készülnie arra, hogy kezelni tudja őket egy olyan stratégiával, mint az "Újrapróbálkozási minta".

Lehetnek azonban olyan helyzetek is, amikor a hibák olyan váratlan események miatt keletkeznek, amelyek kijavítása hosszabb időt vehet igénybe. Az ilyen hibák súlyossága a részleges kapcsolódási problémától a szolgáltatás teljes leállásáig terjedhet. Ilyen helyzetekben értelmetlen lehet, ha egy alkalmazás folyamatosan újrapróbálkozott egy olyan művelettel, amely nem valószínű, hogy sikeres lesz.

Ehelyett az alkalmazást kódolva kell elfogadni, hogy a művelet meghiúsult, és ennek megfelelően kezelje a hibát.

A Http-újrapróbálkozások gondtalan használata szolgáltatásmegtagadási (DoS-) támadást eredményezhet a saját szoftverén belül. Ha egy mikroszolgáltatás meghiúsul vagy lassan teljesít, több ügyfél is újrapróbálkozott a sikertelen kérelmekkel. Ez veszélyes kockázatot jelent, ha exponenciálisan növeli a meghibásodott szolgáltatásra irányuló forgalmat.

Ezért szüksége van valamilyen védelmi gátra, hogy a túlzott kérések leálljanak, amikor nem érdemes tovább próbálkozni. Ez a védőfal pontosan a megszakító.

Az áramkör-megszakító mintának más célja van, mint az "Újrapróbálkozási minta". Az "Újrapróbálkozási minta" lehetővé teszi, hogy az alkalmazás újrapróbálkozjon egy műveletet abban a reményben, hogy a művelet végül sikeres lesz. Az áramkör-megszakító minta megakadályozza, hogy egy alkalmazás olyan műveletet hajtson végre, amely valószínűleg sikertelen lesz. Az alkalmazások kombinálhatják ezt a két mintát. Az újrapróbálkozási logikának azonban érzékenynek kell lennie az áramkör-megszakító által visszaadott kivételre, és fel kell hagynia az újrapróbálkozási kísérletekből, ha az áramkör-megszakító azt jelzi, hogy a hiba nem átmeneti.

Kapcsolatcsoport-megszakító minta implementálása a Pollyval és a Pollyval IHttpClientFactory

Az újrapróbálkozások implementálásához hasonlóan az áramkör-megszakítók ajánlott megközelítése az olyan bevált .NET-kódtárak kihasználása, mint a Polly és a vele való IHttpClientFactorynatív integráció.

Az áramkör-megszakító házirend hozzáadása a IHttpClientFactory kimenő köztes szoftver folyamatához olyan egyszerű, mintha egyetlen növekményes kódrészletet ad hozzá a használat során IHttpClientFactorymár meglévőkhöz.

A HTTP-hívások újrapróbálkozásához használt kódhoz csak az a kód tartozik, amelyben hozzáadja a megszakító házirendet a használni kívánt szabályzatok listájához, ahogyan az az alábbi növekményes kódban is látható.

// Program.cs
var retryPolicy = GetRetryPolicy();
var circuitBreakerPolicy = GetCircuitBreakerPolicy();

builder.Services.AddHttpClient<IBasketService, BasketService>()
        .SetHandlerLifetime(TimeSpan.FromMinutes(5))  // Sample: default lifetime is 2 minutes
        .AddHttpMessageHandler<HttpClientAuthorizationDelegatingHandler>()
        .AddPolicyHandler(retryPolicy)
        .AddPolicyHandler(circuitBreakerPolicy);

Ez AddPolicyHandler() a módszer adja hozzá a szabályzatokat a HttpClient használni kívánt objektumokhoz. Ebben az esetben polly szabályzatot ad hozzá egy áramkör-megszakítóhoz.

A modulárisabb megközelítés érdekében a megszakító házirend egy külön metódusban van definiálva, az alábbi GetCircuitBreakerPolicy()kódban látható módon:

// also in Program.cs
static IAsyncPolicy<HttpResponseMessage> GetCircuitBreakerPolicy()
{
    return HttpPolicyExtensions
        .HandleTransientHttpError()
        .CircuitBreakerAsync(5, TimeSpan.FromSeconds(30));
}

A fenti kód példában a megszakító házirend úgy van konfigurálva, hogy megszakítsa vagy megnyissa a kapcsolatcsoportot, amikor a Http-kérések újrapróbálásakor öt egymást követő hiba történt. Amikor ez történik, a kapcsolatcsoport 30 másodpercig megszakad: ebben az időszakban a hívásokat a megszakító azonnal meghiúsul, nem pedig ténylegesen helyezi el. A szabályzat automatikusan hibaként értelmezi a releváns kivételeket és a HTTP-állapotkódokat .

A kapcsolatcsoport-megszakítókat arra is érdemes használni, hogy a kérelmeket tartalék infrastruktúrára irányítsák át, ha egy olyan erőforrással kapcsolatos probléma merült fel, amely más környezetben van üzembe helyezve, mint a HTTP-hívást végrehajtó ügyfélalkalmazás vagy szolgáltatás. Így ha az adatközpontban olyan kimaradás történik, amely csak a háttérbeli mikroszolgáltatásokat érinti, az ügyfélalkalmazásokat azonban nem, az ügyfélalkalmazások átirányíthatják a tartalék szolgáltatásokra. A Polly egy új szabályzatot tervez a feladatátvételi szabályzat forgatókönyvének automatizálásához.

Ezek a funkciók olyan esetekre szolgálnak, amikor a feladatátvételt a .NET-kódból kezeli, nem pedig automatikusan az Azure-ban, a hely átláthatóságával.

Használat szempontjából a HttpClient használatakor itt nem kell újat hozzáadni, mert a kód ugyanaz, mint a korábbi HttpClientIHttpClientFactoryszakaszokban látható.

Http újrapróbálkozási és megszakítók tesztelése az eShopOnContainersben

Amikor elindítja az eShopOnContainers megoldást egy Docker-gazdagépen, több tárolót kell elindítania. Egyes tárolók indítása és inicializálása lassabb, például az SQL Server-tároló. Ez különösen igaz az eShopOnContainers alkalmazás Dockerben való első üzembe helyezésére, mert be kell állítania a rendszerképeket és az adatbázist. Az a tény, hogy egyes tárolók lassabban indulnak el, mint mások, a többi szolgáltatás kezdetben HTTP-kivételeket okozhat, még akkor is, ha docker-compose szinten állítja be a tárolók közötti függőségeket, ahogyan azt az előző szakaszokban ismertetjük. A tárolók közötti docker-compose függőségek csak a folyamat szintjén vannak. A tároló belépési pontjának folyamata elindítható, de előfordulhat, hogy az SQL Server nem áll készen a lekérdezésekre. Az eredmény több hiba kaszkádja lehet, és az alkalmazás kivételt kaphat az adott tároló használata során.

Az ilyen típusú hibák indításkor is megjelenhetnek, amikor az alkalmazás üzembe helyezése a felhőben történik. Ebben az esetben előfordulhat, hogy a vezénylők tárolókat helyeznek át egyik csomópontról vagy virtuális gépről a másikra (azaz új példányok indítása) a tárolók számának a fürt csomópontjai közötti elosztásakor.

Az "eShopOnContainers" a korábban bemutatott Újrapróbálkozási minta használatával oldja meg ezeket a problémákat az összes tároló indításakor.

Az áramkör-megszakító tesztelése az eShopOnContainersben

Többféleképpen is megszakíthatja/megnyithatja a kapcsolatcsoportot, és tesztelheti az eShopOnContainers használatával.

Az egyik lehetőség az, hogy az újrapróbálkozések engedélyezett számát 1-re csökkenti az áramkör-megszakító házirendben, és újra üzembe helyezi a teljes megoldást a Dockerben. Egyetlen újrapróbálkozással jó esély van arra, hogy egy HTTP-kérés sikertelen lesz az üzembe helyezés során, megnyílik az áramkör-megszakító, és hibaüzenet jelenik meg.

Egy másik lehetőség a Basket mikroszolgáltatásban implementált egyéni köztes szoftver használata. Ha ez a köztes szoftver engedélyezve van, az összes HTTP-kérést elfogja, és az 500-os állapotkódot adja vissza. A köztes szoftver engedélyezéséhez get kérést kell küldenie a sikertelen URI-hoz, például az alábbiak szerint:

  • GET http://localhost:5103/failing
    Ez a kérés a köztes szoftver aktuális állapotát adja vissza. Ha a köztes szoftver engedélyezve van, a kérés az 500-os állapotkódot adja vissza. Ha a köztes szoftver le van tiltva, nincs válasz.

  • GET http://localhost:5103/failing?enable
    Ez a kérés engedélyezi a köztes szoftvereket.

  • GET http://localhost:5103/failing?disable
    Ez a kérés letiltja a köztes szoftvereket.

Ha például az alkalmazás fut, engedélyezheti a köztes szoftvereket a következő URI használatával bármely böngészőben. Vegye figyelembe, hogy a rendelési mikroszolgáltatás az 5103-at használja.

http://localhost:5103/failing?enable

Ezután az URI http://localhost:5103/failinghasználatával ellenőrizheti az állapotot, ahogy a 8–5. ábrán látható.

Screenshot of checking the status of failing middleware simulation.

8-5. ábra. A "Sikertelen" ASP.NET köztes szoftver állapotának ellenőrzése – Ebben az esetben le van tiltva.

Ekkor a Basket mikroszolgáltatás 500-os állapotkóddal válaszol, amikor meghívja.

A köztes szoftver futtatása után megpróbálhat rendelést készíteni az MVC webalkalmazásból. Mivel a kérések sikertelenek, a kapcsolatcsoport megnyílik.

Az alábbi példában láthatja, hogy az MVC-webalkalmazásnak van egy fogási blokkja a megrendelések leadására szolgáló logikában. Ha a kód egy nyitott áramköri kivételt kap, a felhasználónak egy rövid üzenet jelenik meg, amely arra utasítja őket, hogy várjanak.

public class CartController : Controller
{
    //…
    public async Task<IActionResult> Index()
    {
        try
        {
            var user = _appUserParser.Parse(HttpContext.User);
            //Http requests using the Typed Client (Service Agent)
            var vm = await _basketSvc.GetBasket(user);
            return View(vm);
        }
        catch (BrokenCircuitException)
        {
            // Catches error when Basket.api is in circuit-opened mode
            HandleBrokenCircuitException();
        }
        return View();
    }

    private void HandleBrokenCircuitException()
    {
        TempData["BasketInoperativeMsg"] = "Basket Service is inoperative, please try later on. (Business message due to Circuit-Breaker)";
    }
}

A táblázat ezt foglalja össze. Az Újrapróbálkozás szabályzat többször is megpróbál HTTP-kérést küldeni, és HTTP-hibákat kap. Amikor az újrapróbálkozások száma eléri a megszakító házirend maximális számát (ebben az esetben 5), az alkalmazás BrokenCircuitException értéket ad vissza. Az eredmény egy barátságos üzenet, ahogyan a 8-6. ábrán látható.

Screenshot of the MVC web app with basket service inoperative error.

8-6. ábra. Az áramkör-megszakító hibát ad vissza a felhasználói felületnek

A kapcsolatcsoport megnyitásának/megszakításának különböző logikáját implementálhatja. Ha tartalék adatközpontot vagy redundáns háttérrendszert használ, megpróbálhat HTTP-kérést egy másik háttérbeli mikroszolgáltatással.

Végül, egy másik lehetőség a CircuitBreakerPolicy használat Isolate (amely kényszeríti nyitott és tartja nyitva a kapcsolatcsoport) és Reset (amely bezárja újra). Ezekkel létrehozhat egy segédprogram HTTP-végpontot, amely közvetlenül a szabályzaton hívja meg az elkülönítést és az alaphelyzetbe állítást. Az ilyen HTTP-végpontok éles környezetben is használhatók, megfelelően védve egy alsóbb rétegbeli rendszer ideiglenes elkülönítéséhez, például a frissítéshez. Vagy manuálisan is meg lehet rántni a kapcsolatcsoportot, hogy megvédje a hibásnak vélt alsóbb rétegbeli rendszert.

További erőforrások