Tijdelijke fouten afhandelen en efficiënt verbinding maken met Azure Database for MySQL

VAN TOEPASSING OP: Azure Database for MySQL - Enkele server

Belangrijk

Azure Database for MySQL: één server bevindt zich op het buitengebruikstellingspad. We raden u ten zeerste aan een upgrade uit te voeren naar Azure Database for MySQL - Flexibele server. Zie Wat gebeurt er met Azure Database for MySQL enkele server? voor meer informatie over migreren naar Azure Database for MySQL - Flexibele server.

In dit artikel wordt beschreven hoe u tijdelijke fouten kunt afhandelen en efficiënt verbinding kunt maken met Azure Database for MySQL.

Tijdelijke fouten

Een tijdelijke fout, ook wel een tijdelijke fout genoemd, is een fout die vanzelf wordt opgelost. Deze fouten worden meestal weergegeven als een verbinding met de databaseserver die wordt verbroken. Nieuwe verbindingen met een server kunnen ook niet worden geopend. Tijdelijke fouten kunnen bijvoorbeeld optreden wanneer er een hardware- of netwerkfout optreedt. Een andere reden kan een nieuwe versie van een PaaS-service zijn die wordt geïmplementeerd. De meeste van deze gebeurtenissen worden in minder dan 60 seconden automatisch verzacht door het systeem. Een best practice voor het ontwerpen en ontwikkelen van toepassingen in de cloud is tijdelijke fouten te verwachten. Stel dat ze op elk gewenst moment in elk onderdeel kunnen plaatsvinden en dat de juiste logica aanwezig is om deze situaties af te handelen.

Tijdelijke fouten verwerken

Tijdelijke fouten moeten worden verwerkt met behulp van logica voor opnieuw proberen. Situaties waarmee rekening moet worden gehouden:

  • Er treedt een fout op wanneer u een verbinding probeert te openen
  • Een niet-actieve verbinding wordt verbroken aan de serverzijde. Wanneer u een opdracht probeert uit te geven, kan deze niet worden uitgevoerd
  • Een actieve verbinding die momenteel een opdracht uitvoert, wordt verbroken.

Het eerste en tweede geval zijn redelijk eenvoudig te behandelen. Probeer de verbinding opnieuw te openen. Wanneer u slaagt, is de tijdelijke fout verzacht door het systeem. U kunt uw Azure Database for MySQL opnieuw gebruiken. We raden u aan om te wachten voordat u de verbinding opnieuw probeert uit te voeren. Ga terug als de eerste nieuwe pogingen mislukken. Op deze manier kan het systeem alle beschikbare resources gebruiken om de foutsituatie te verhelpen. Een goed patroon om te volgen is:

  • Wacht 5 seconden voordat u de eerste poging opnieuw probeert.
  • Voor elke volgende nieuwe poging wordt de wachttijd exponentieel verhoogd, tot maximaal 60 seconden.
  • Stel een maximum aantal nieuwe pogingen in waarop uw toepassing de bewerking als mislukt beschouwt.

Wanneer een verbinding met een actieve transactie mislukt, is het moeilijker om het herstel correct te verwerken. Er zijn twee gevallen: als de transactie het kenmerk Alleen-lezen heeft, is het veilig om de verbinding opnieuw te openen en de transactie opnieuw uit te voeren. Als de transactie echter ook naar de database heeft geschreven, moet u bepalen of de transactie is teruggedraaid of dat deze is geslaagd voordat de tijdelijke fout is opgetreden. In dat geval hebt u mogelijk niet de bevestiging van de doorvoer van de databaseserver ontvangen.

Een manier om dit te doen, is het genereren van een unieke id op de client die wordt gebruikt voor alle nieuwe pogingen. U geeft deze unieke id door als onderdeel van de transactie aan de server en om deze op te slaan in een kolom met een unieke beperking. Op deze manier kunt u de transactie veilig opnieuw proberen. Dit lukt als de vorige transactie is teruggedraaid en de door de client gegenereerde unieke id nog niet in het systeem bestaat. Deze fout geeft een dubbele sleutelschending aan als de unieke id eerder is opgeslagen omdat de vorige transactie is voltooid.

Wanneer uw programma communiceert met Azure Database for MySQL via middleware van derden, vraagt u de leverancier of de middleware logica voor opnieuw proberen bevat voor tijdelijke fouten.

Zorg ervoor dat u de logica voor opnieuw proberen test. Probeer bijvoorbeeld uw code uit te voeren tijdens het omhoog of omlaag schalen van de rekenresources van uw Azure Database for MySQL-server. Uw toepassing moet de korte downtime die tijdens deze bewerking optreedt, zonder problemen verwerken.

Efficiënt verbinding maken met Azure Database for MySQL

Databaseverbindingen zijn een beperkte resource, dus door effectief gebruik te maken van groepsgewijze verbindingen voor toegang tot Azure Database for MySQL worden de prestaties geoptimaliseerd. In de onderstaande sectie wordt uitgelegd hoe u groepsgewijze verbindingen of permanente verbindingen gebruikt om effectiever toegang te krijgen tot Azure Database for MySQL.

Het beheren van databaseverbindingen kan een aanzienlijke invloed hebben op de prestaties van de toepassing als geheel. Om de prestaties van uw toepassing te optimaliseren, moet het doel zijn om het aantal keren dat verbindingen tot stand worden gebracht en de tijd voor het tot stand brengen van verbindingen in sleutelcodepaden te verminderen. U wordt ten zeerste aangeraden databaseverbindingsgroepen of permanente verbindingen te gebruiken om verbinding te maken met Azure Database for MySQL. Databaseverbindingsgroepering verwerkt het maken, beheren en toewijzen van databaseverbindingen. Wanneer een programma een databaseverbinding aanvraagt, geeft het prioriteit aan de toewijzing van bestaande niet-actieve databaseverbindingen in plaats van het maken van een nieuwe verbinding. Nadat het programma klaar is met het gebruik van de databaseverbinding, wordt de verbinding hersteld ter voorbereiding op verder gebruik, in plaats van gewoon te worden gesloten.

Ter illustratie biedt dit artikel een voorbeeldcode die gebruikmaakt van JAVA als voorbeeld. Zie Algemene Apache DBCP voor meer informatie.

Notitie

De server configureert een time-outmechanisme om een verbinding te sluiten die al enige tijd inactief is om resources vrij te maken. Zorg ervoor dat u het verificatiesysteem instelt om de effectiviteit van permanente verbindingen te garanderen wanneer u deze gebruikt. Zie Verificatiesystemen aan de clientzijde configureren om de effectiviteit van permanente verbindingen te garanderen voor meer informatie.

Het concept van permanente verbindingen is vergelijkbaar met dat van groepsgewijze verbindingen. Voor het vervangen van korte verbindingen door permanente verbindingen zijn slechts kleine wijzigingen in de code vereist, maar dit heeft een groot effect op het verbeteren van de prestaties in veel typische toepassingsscenario's.

Toegang tot databases met behulp van het mechanisme voor wachten en opnieuw proberen met korte verbindingen

Als u resourcebeperkingen hebt, raden we u ten zeerste aan om databasegroepering of permanente verbindingen te gebruiken om toegang te krijgen tot databases. Als uw toepassing korte verbindingen gebruikt en verbindingsfouten ondervindt wanneer u de bovengrens voor het aantal gelijktijdige verbindingen nadert, kunt u het mechanisme wachten en opnieuw proberen. U kunt een geschikte wachttijd instellen, met een kortere wachttijd na de eerste poging. Daarna kunt u meerdere keren proberen te wachten op gebeurtenissen.

Verificatiemechanismen in clients configureren om de effectiviteit van permanente verbindingen te bevestigen

De server configureert een time-outmechanisme om een verbinding te sluiten die al enige tijd inactief is om resources vrij te maken. Wanneer de client de database opnieuw opent, is dit gelijk aan het maken van een nieuwe verbindingsaanvraag tussen de client en de server. Configureer een verificatiemechanisme op de client om de effectiviteit van verbindingen tijdens het gebruik ervan te garanderen. Zoals in het volgende voorbeeld wordt weergegeven, kunt u Tomcat JDBC-verbindingsgroepen gebruiken om dit verificatiemechanisme te configureren.

Door de parameter TestOnBorrow in te stellen wanneer er een nieuwe aanvraag is, controleert de verbindingsgroep automatisch de effectiviteit van alle beschikbare niet-actieve verbindingen. Als een dergelijke verbinding effectief is, wordt de verbinding rechtstreeks geretourneerd, anders wordt de verbindingsgroep ingetrokken. De verbindingsgroep maakt vervolgens een nieuwe effectieve verbinding en retourneert deze. Dit proces zorgt ervoor dat de database efficiënt wordt geopend.

Zie het officiële introductiedocument voor de JDBC-verbindingsgroep voor meer informatie over de specifieke instellingen. U moet voornamelijk de volgende drie parameters instellen: TestOnBorrow (ingesteld op true), ValidationQuery (ingesteld op SELECT 1) en ValidationQueryTimeout (ingesteld op 1). De specifieke voorbeeldcode wordt hieronder weergegeven:

public class SimpleTestOnBorrowExample {
      public static void main(String[] args) throws Exception {
          PoolProperties p = new PoolProperties();
          p.setUrl("jdbc:mysql://localhost:3306/mysql");
          p.setDriverClassName("com.mysql.jdbc.Driver");
          p.setUsername("root");
          p.setPassword("password");
            // The indication of whether objects will be validated by the idle object evictor (if any). 
            // If an object fails to validate, it will be dropped from the pool. 
            // NOTE - for a true value to have any effect, the validationQuery or validatorClassName parameter must be set to a non-null string. 
          p.setTestOnBorrow(true); 

            // The SQL query that will be used to validate connections from this pool before returning them to the caller.
            // If specified, this query does not have to return any data, it just can't throw a SQLException.
          p.setValidationQuery("SELECT 1");

            // The timeout in seconds before a connection validation queries fail. 
            // This works by calling java.sql.Statement.setQueryTimeout(seconds) on the statement that executes the validationQuery. 
            // The pool itself doesn't timeout the query, it is still up to the JDBC driver to enforce query timeouts. 
            // A value less than or equal to zero will disable this feature.
          p.setValidationQueryTimeout(1);
            // set other useful pool properties.
          DataSource datasource = new DataSource();
          datasource.setPoolProperties(p);

          Connection con = null;
          try {
            con = datasource.getConnection();
            // execute your query here
          } finally {
            if (con!=null) try {con.close();}catch (Exception ignore) {}
          }
      }
  }

Volgende stappen