Gyakorlat – Újrapróbálkozási szabályzat megvalósítása az alkalmazásban

Befejeződött

Csapata csevegőalkalmazását már továbbfejlesztette, hogy észlelje a hibákat. Felhőalapú adatbázis használatakor különböző átmeneti hibák léphetnek fel. Ebben a gyakorlatban a kapcsolati problémák megoldására összpontosítunk egy újrapróbálkozási szabályzat implementálásával.

Ha a hiba adatbázis-kapcsolati problémák miatt merül fel, a következő stratégiát vezetjük be:

  • Hálózati hiba esetén gyors újracsatlakozási próbálkozás
  • 60 másodpercenként újabb csatlakozási kísérlet
  • Újrapróbálkozás legfeljebb ötször
  • Öt újrapróbálkozás után a felhasználó értesítése az adatbázis elérhetetlenségéről, és kilépés

Más, ismeretlen hiba esetén az alkalmazás futása megszakad.

Újrapróbálkozási szabályzat megvalósítása osztály használatával

  1. Futtassa az alábbi parancsot a Cloud Shellben a C# chatapp-retry mappához való navigáláshoz.

    cd ~/mslearn-handle-transient-errors-in-your-app/csharp/chatapp-retry/
    
  2. Ez a verzió tartalmazza az újrapróbálkozási szabályzat osztály kódolásának első vázlatát. Tartozik hozzá egy appsettings.json nevű konfigurációs fájl, amellyel a rendszergazdák beállíthatják az újrapróbálkozások késleltetését és számát.

    {
        "number-of-retries": 5,
        "delay": 60000
    }
    
  3. Nyissa meg a RetryPolicy osztályt.

    code RetryPolicy.cs
    

    Szánjon időt az osztály kódjának elolvasására.

    A RetryPolicy osztály nyomon követi az újrapróbálkozások számát, és kezeli a kóddal való ismételt próbálkozás előtti késleltetést. Az újrapróbálkozási logika nagy részét a CanRetry() metódus tartalmazza:

    using System;
    using Microsoft.Extensions.Configuration;
    using System.Threading;
    using System.Diagnostics;
    using System.IO;
    
    
    namespace csharp_chatapp_retry
    {
        public class RetryPolicy
        {
            private int currentTries = 0;
            static public IConfiguration configuration { get; set; }
    
            /// <summary>
            /// Constructor - reads config for number of retries and delay
            /// </summary>
            public RetryPolicy()
            {
                ConfigurationBuilder configurationBuilder = new ConfigurationBuilder();
                configurationBuilder.SetBasePath(Directory.GetCurrentDirectory());
                configurationBuilder.AddJsonFile("appsettings.json");
                configuration = configurationBuilder.Build();
            }
    
            /// <summary>
            /// Method to implement retry policy controlled by configuration
            /// </summary>
            /// <returns>Returns true if it's ok to retry</returns>
            public bool CanRetry()
            {
                // Keep track of current retries
                currentTries++;
                Console.WriteLine($"Retrying: {currentTries}");
    
                // Use a delay if this isn't the first try
                if (currentTries != 1)
                {
                    Thread.Sleep(int.Parse(configuration["delay"]));
                }
    
                if (currentTries < int.Parse(configuration["number-of-retries"])) {
                    return true;
                } else {
                    return false;
                }
            }
    
            public void ResetRetries()
            {
                currentTries = 0;
            }
        }
    }
    

    A canRetry metódus ellenőrzi az újrapróbálkozások számát, majd visszatér true a hívó kódhoz, ha nem működik az újrapróbálkozás, vagy false ha az alkalmazásnak most le kell állnia.

    Most már használhatjuk ezt az osztályt az alkalmazásunkban egy újrapróbálkozési szabályzat implementálásához.

Újrapróbálkozási szabályzat hozzáadása

  1. Válassza ki a szerkesztő jobb felső sarkában található három három pontot (...), majd válassza a Fájl megnyitása ...lehetőséget. Válassza a Program.cs lehetőséget a fájlválasztó párbeszédpanelen, majd nyomja le az Enter billentyűt.

  2. Az osztály connectionString változójának értékét írja át az Azure Cosmos DB-adatbázis korábban megállapított kapcsolati sztringjére.

  3. Görgessen le a getAllChats() metódusig.

    private static void getAllChats()
    {
        messages = database.GetCollection<ChatMessage>(collectionName);
        try
        {
            allMessages = messages.Find(new BsonDocument()).ToList();
            foreach (ChatMessage chat in allMessages)
            {
                Console.WriteLine($"{chat.Name}: {chat.Message}");
            }
            Console.WriteLine("\n");
        }
        catch (MongoDB.Driver.MongoConnectionException e)
        {
            diagnose(e);
        }
        catch (System.TimeoutException e)
        {
            diagnose(e);
        }
        catch (Exception e)
        {
            diagnose(e);
            throw e;
        }
    }
    
  4. Szúrja be a kapcsolatot ismételten megkísérlő kódot a MongoDB-re vonatkozó két catch blokkba.

        if (retries.CanRetry())
        {
            diagnose(e);
            getAllChats(); //retry
        } else {
            Console.WriteLine("Maximum retries - need to close.");
            throw e;
        }
    
  5. A metódus kódjának az alábbinak kell lennie:

        private static void getAllChats()
        {
            messages = database.GetCollection<ChatMessage>(collectionName);
            try
            {
                allMessages = messages.Find(new BsonDocument()).ToList();
                foreach (ChatMessage chat in allMessages)
                {
                    Console.WriteLine(String.Format("{0}: {1}", chat.Name, chat.Message));
                }
                Console.WriteLine("\n");
            }
            catch (MongoDB.Driver.MongoConnectionException e)
            {
                if (retries.CanRetry())
                {
                    diagnose(e);
                    getAllChats(); //retry
                } else {
                    Console.WriteLine("Maximum retries - need to close.");
                    throw e;
                }
            }
            catch (System.TimeoutException e)
            {
                if (retries.CanRetry())
                {
                    diagnose(e);
                    getAllChats(); //retry
                } else {
                    Console.WriteLine("Maximum retries - need to close.");
                    throw e;
                }
            }
            catch (Exception e)
            {
                diagnose(e);
                throw e;
            }
        }
    
  6. Definiálja a retries objektumot, és állítsa alaphelyzetbe az adatbázis minden hívásakor. A main metódus elé szúrja be a retries objektum deklarációját:

        private static RetryPolicy retries = new RetryPolicy();
    
  7. A retries objektumot a Program.csMain() metódusának while-ciklusában állíthatja alaphelyzetbe, az alábbi kódrészletben látható módon.

    while(choice != 'Q' && choice != 'q')
    {
        retries.Reset();
        Console.WriteLine();
        ChatMessage newChat = new ChatMessage();
        switch (choice)
        {
            case 'N':
    
  8. A módosítások mentéséhez válassza a szerkesztőfelület jobb felső részén található három pontot (...), majd a Szerkesztő bezárása, végül a Mentés lehetőséget.

  9. Fordítsa le és futtassa az alkalmazást.

    dotnet build
    dotnet run
    
  10. Az alkalmazás a fordítást követően elindul. Írjon be üzenetet az N bemenettel, majd a név és az üzenet begépelésével.

  11. Listázza ki az összes üzenetet az R, majd az Enter billentyű lenyomásával.

  12. Hagyja futni az alkalmazást.

Újrapróbálkozási szabályzat megvalósítása osztály használatával

  1. A Cloud Shellben lépjen a Java chatapp-retry mappájába.

    cd ~/mslearn-handle-transient-errors-in-your-app/java/chatapp-retry/
    
  2. Ez a verzió tartalmazza az újrapróbálkozási szabályzat osztály kódolásának első vázlatát. Tartozik hozzá egy config.properties nevű konfigurációs fájl, amellyel a rendszergazdák beállíthatják az újrapróbálkozások késleltetését és számát.

    number_of_retries=5
    delay=60
    
  3. Nyissa meg a RetryPolicy osztályt.

    code RetryPolicy.java
    
  4. Az osztály nyomon követi az újrapróbálkozások számát, és kezeli a kóddal való ismételt próbálkozás előtti késleltetést. A canRetry metódus fő logikája a következő:

    public boolean canRetry() throws InterruptedException {
        // Keep track of current retries
        currentTries++;
        System.out.printf("Retrying: %s\n", currentTries);
    
        // Use a delay if this isn't the first try
        if (currentTries != 1)
        {
            TimeUnit.SECONDS.sleep(Integer.parseInt(props.getProperty("delay")));
        }
    
        if (currentTries < Integer.parseInt(props.getProperty("number_of_retries"))) {
            return true;
        } else {
            return false;
        }
    }
    

    A canRetry metódus ellenőrzi az újrapróbálkozások számát, majd visszatér true a hívó kódhoz, ha nem működik az újrapróbálkozás, vagy false ha az alkalmazásnak most le kell állnia.

  5. Ezzel az osztálysal újrapróbálkozési szabályzatot adhat hozzá a csevegőalkalmazáshoz.

Újrapróbálkozási szabályzat hozzáadása

  1. Jelölje ki a szerkesztő jobb felső sarkában található három három pontot (...), majd válassza a Megnyitás lehetőséget a javaChat.java párbeszédpanelen, majd nyomja le az Enter billentyűt.

  2. Keresse meg a printAllMessages() metódust a javaChat.java kódban.

  3. Írja felül a printAllMessages implementációját a következő kóddal. Ez a kód újrapróbálkozási logikát ad a MongoDB catch blokkokhoz.

        private static void printAllMessages (MongoCollection<Document> collection) throws InterruptedException {
            try {
                // Return all messages
                collection.find().forEach((Consumer<Document>) document -> {
                    System.out.printf("%s: %s\n", document.get("name"), document.get("message"));
                });
            }
            catch (com.mongodb.MongoCommandException e) {
                if (retries.canRetry())
                {
                    diagnose(e);
                    printAllMessages(collection); //retry
                } else {
                    System.out.println("Maximum retries - need to close.");
                    throw e;
                }
            }
            catch (com.mongodb.MongoSecurityException e) {
                if (retries.canRetry())
                {
                    diagnose(e);
                    printAllMessages(collection); //retry
                } else {
                    System.out.println("Maximum retries - need to close.");
                    throw e;
                }
            }
            catch (Exception e) {
                diagnose(e);
                throw e;
            }
        }
    
  4. A javaChat.javaMain metódusa elé szúrja be a RetryPolicy objektum deklarációját.

    private static RetryPolicy retries;
    
  5. A Main metóduson belül példányosítsa a retries változót:

        try{
            retries = new RetryPolicy();
        } catch(FileNotFoundException e) {
            e.printStackTrace();
        }
    
  6. Az újrapróbálkozások alaphelyzetbe állításához szúrja be az alábbi sort a while-cikluis elejére.

        retries.resetRetries();
    
  7. Mentse a fájlt, és zárja be a szerkesztőt. Használja a szerkesztő jobb felső sarkában található ... menü parancsait, vagy a ctrl+S billentyűkombinációval mentse a fájlt, a Ctrl+Q billentyűkombinációval pedig zárja be a szerkesztőt.

  8. Hozza létre a projektet a következő paranccsal:

    javac -cp .:lib/* -d . javaChat.java RetryPolicy.java
    
  9. Futtassa az alkalmazást a Cloud Shellben kiadott alábbi paranccsal.

    java -cp .:lib/* learn.javachatapp.javaChat
    

Újrapróbálkozási szabályzat megvalósítása függvény használatával

  1. A Cloud Shellben lépjen a csomópont csevegőalkalmazás-újrapróbálkozás mappájához.

    cd ~/mslearn-handle-transient-errors-in-your-app/node/chatapp-retry/
    
  2. Ez a verzió tartalmazza az újrapróbálkozási szabályzat osztály kódolásának első vázlatát. Tartozik hozzá egy appsettings.json nevű konfigurációs fájl, amellyel a rendszergazdák beállíthatják az újrapróbálkozások késleltetését és számát.

    {
        "number_of_retries": 5,
        "delay": 60000
    }
    
  3. Töltse le a függőségeket.

    npm install
    
  4. Nyissa meg a retryPolicy.js parancsfájlt.

    code retryPolicy.js
    
  5. Az osztály nyomon követi az újrapróbálkozások számát, és kezeli a kóddal való ismételt próbálkozás előtti késleltetést. A fő logikát a checkRetries függvény tartalmazza:

    
    method.checkRetries = function() {
        this._currentTries = this._currentTries + 1;
        console.log('Retrying: ' + this._currentTries);
    
        // Use a delay if this isn't the first try
        if (this._currentTries != 1)
        {
            sleep(config.delay);
        }
    
        if (this._currentTries < config.number_of_retries) {
            return true;
        } else {
            return false;
        }
    };
    

    A canRetry metódus ellenőrzi az újrapróbálkozások számát, majd visszatér true a hívó kódhoz, ha nem működik az újrapróbálkozás, vagy false ha az alkalmazásnak most le kell állnia.

  6. Ezzel az osztálysal újrapróbálkozési szabályzatot adhat hozzá a csevegőalkalmazáshoz.

Újrapróbálkozási szabályzat hozzáadása

  1. Jelölje ki a szerkesztő jobb felső sarkában található három három pontot (...), majd válassza a Megnyitás lehetőséget a server.js párbeszédpanelen, majd nyomja le az Enter billentyűt.

  2. Görgessen le az adatbázishoz való kapcsolódást végző mongoose-híváshoz.

    
    // Connect to MongoDB
    mongoose.connect( dbUrl, options )
      .then(() => console.log('Connection to MongoDB successful'))
      .catch(function(e) {
        console.log(e); // "error connecting to the database"
      });
    
    
  3. A catch-ígéreten belül szúrja be az újrapróbálkozási szabályzatot használó kódot.

      .catch(function(e) {
        if (retries.checkRetries()) {
          // need to retry
        } else {
          console.log(e); // "error connecting to the database"
        }
      });
    
  4. A JavaScriptben többféleképpen is próbálkozhat újra a kóddal. Az egyszerűség kedvéért ez a példa rekurziót használ. A kapcsolódás kódját írja felül az alábbival.

    // Connect to MongoDB
    function connectWithRetry() {
      mongoose.connect( dbUrl, options )
      .then(() => console.log('Connection to MongoDB successful'))
      .catch(function(e) {
        if (retries.checkRetries()) {
          connectWithRetry();
        } else {
          console.log(e); // "error connecting to the database"
        }
      });
    }
    
    // Using the retry policy
    connectWithRetry();
    

    Tipp.

    Léteznek más újrapróbálkozási NPM-csomagok, például a polly-js, amelyek egyszerűbb kódot eredményeznek, és olyan további funkciókat is kínálnak, mint az exponenciális visszatartás.

  5. Definiálja a retries objektumot, majd a 6. sorban foglalja be a retryPolicy.js fájlt...

    // Include packages
    var express = require('express'), http = require('http');
    var bodyParser = require('body-parser')
    var mongoose = require('mongoose');
    var app = express();
    
    // Start node app listening
    var server = http.createServer(app);
    server.listen(8000);
    server.on('error', function (err) {
      console.log(err);
    })
    
    

    ...az alábbi kód beszúrásával:

    // add the retry policy
    let retry = require('./retryPolicy.js');
    let retries = new retry();
    
  6. Mentse a fájlt, és zárja be a szerkesztőt. Használja a szerkesztő jobb felső sarkában található ... menü parancsait, vagy a ctrl+S billentyűkombinációval mentse a fájlt, a Ctrl+Q billentyűkombinációval pedig zárja be a szerkesztőt.

  7. Ha a böngésző nem az előző gyakorlatból van megnyitva, futtassa a következőt:

    curl -X POST http://localhost:8888/openPort/8000;
    
  8. Futtassa a Node-alkalmazást a következőkkel:

    npm build
    npm start
    
  9. Válassza ki az előző lépésben visszaadott hivatkozást.

  10. Írjon be néhány üzenetet, majd frissítse az oldalt. Hagyja futni az alkalmazást.

Az újrapróbálkozási kód tesztelése

Ha az Azure Cosmos DB-hez még be van kapcsolva a tűzfal, akkor a csevegőalkalmazás nem tud az adatbázishoz kapcsolódni. Ellenkező esetben: ha az csevegőalkalmazás még működik, kapcsolja be a tűzfalat az alábbi lépések végrehajtásával.

  1. Jelentkezzen be az Azure Portalra ugyanazzal a fiókkal, amellyel a tesztkörnyezetet aktiválta.

  2. Az Azure Portal menüjében vagy a Kezdőlapon válassza az Azure Cosmos DB elemet.

  3. Az adatbázisfiókok listájában azt válassza ki, amelynek neve a learn-cosmos-db- sztringgel kezdődik.

  4. Az Azure Cosmos DB panelen válassza a Tűzfalak és virtuális hálózatok lehetőséget.

  5. A Hozzáférés engedélyezése innen beállításnál válassza a Kijelölt hálózatok lehetőséget.

  6. Távolítsa el a Hozzáférés engedélyezése az Azure Portalról jelölőnégyzet jelölését.

  7. Jelölje ki a Tudomásul veszem, hogy a jelenlegi beállítások az összes virtuális hálózatot és IP-címet blokkolják, köztük az Azure Portalt is elemet.

  8. A tűzfal-konfiguráció módosításainak mentéséhez válassza a Mentés lehetőséget. Ezek a módosítások engedélyezték az Azure Cosmos DB-fiók tűzfalát, amely letiltja a Hozzáférést a Cloud Shellből, és szimulálja a kapcsolat megszakadását.

    Megjegyzés:

    A tűzfal frissítése időt vesz igénybe. Várja meg, amíg befejeződik, mielőtt továbbhalad a következő lépésre.

  9. Futtassa az alkalmazást, és válassza az R lehetőséget az összes üzenet frissítéséhez. Az alkalmazás elkapja a System.TimeoutException kapcsolatot, és újrapróbálkozza az adatbázissal való kapcsolatot.

A projekt appsettings.json fájljában megadott beállítás alapján number-of-retries a kód legfeljebb ötször próbálkozik újra a csatlakozással.

A projekt config.properties fájljában megadott beállítás alapján number_of_retries a kód legfeljebb ötször próbálkozik újra a csatlakozással.

A projekt appsettings.json fájljában megadott beállítás alapján number-of-retries a kód legfeljebb ötször próbálkozik újra a csatlakozással.

  1. Az Azure Portalon válassza a Minden hálózat lehetőséget, majd válassza a Mentés lehetőséget a tűzfal letiltásához.

  2. Ha az alkalmazás már lefutott, indítsa újra.

  3. Ha a tűzfalat időben eltávolítják, a csevegőalkalmazás helyreállítja, újracsatlakoztatja és megjeleníti a tárolt üzeneteket.

Az újrapróbálkozási szabályzat módosítása

  1. Lépjen ki az alkalmazásból, és módosítsa az újrapróbálkozási szabályzat konfigurációját úgy, hogy csak 5 másodpercig (5000 ezredmásodpercig) várakozzon az újrapróbálkozások között.
  1. Nyissa meg a konfigurációs fájlt a kódszerkesztőben.

    code appsettings.json
    
  2. A késleltetés értékét állítsa be 60000 helyett az 5000 értékre.

  3. Mentse a fájlt, és zárja be a szerkesztőt. Használja a szerkesztő jobb felső sarkában található ... menü parancsait, vagy a ctrl+S billentyűkombinációval mentse a fájlt, a Ctrl+Q billentyűkombinációval pedig zárja be a szerkesztőt.

  4. Futtassa az alkalmazást, és figyelje meg, hogy az újrapróbálkozások gyorsabban követik egymást.

    dotnet run
    
  1. Nyissa meg a konfigurációs fájlt a kódszerkesztőben.

    code config.properties
    
  2. A késleltetés értékét állítsa be 60 helyett az 5 értékre.

  3. Mentse a fájlt, és zárja be a szerkesztőt. Használja a szerkesztő jobb felső sarkában található ... menü parancsait, vagy a ctrl+S billentyűkombinációval mentse a fájlt, a Ctrl+Q billentyűkombinációval pedig zárja be a szerkesztőt.

  4. Futtassa az alkalmazást, és figyelje meg, hogy az újrapróbálkozások gyorsabban követik egymást.

    java -cp .:lib/* learn.javachatapp.javaChat
    
  1. Nyissa meg a konfigurációs fájlt a kódszerkesztőben.

    code appsettings.json
    
  2. A késleltetés értékét állítsa be 60000 helyett az 5000 értékre.

  3. Mentse a fájlt, és zárja be a szerkesztőt. Használja a szerkesztő jobb felső sarkában található ... menü parancsait, vagy a ctrl+S billentyűkombinációval mentse a fájlt, a Ctrl+Q billentyűkombinációval pedig zárja be a szerkesztőt.

  4. Futtassa az alkalmazást, és figyelje meg, hogy az újrapróbálkozások gyorsabban követik egymást.

    npm start