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 enkele server bevindt zich op het buitengebruikstellingspad. We raden u ten zeerste aan een upgrade uit te voeren naar een flexibele Azure Database for MySQL-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 verwerkt en efficiënt verbinding maakt met Azure Database for MySQL.

Tijdelijke fouten

Een tijdelijke fout, ook wel een tijdelijke fout genoemd, is een fout die zichzelf oplost. Meestal zijn deze fouten zichtbaar als een verbinding met de databaseserver die wordt verwijderd. Er kunnen ook geen nieuwe verbindingen met een server worden geopend. Tijdelijke fouten kunnen bijvoorbeeld optreden wanneer er hardware- of netwerkfouten optreden. 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 beperkt door het systeem. Een best practice voor het ontwerpen en ontwikkelen van toepassingen in de cloud is het verwachten van tijdelijke fouten. 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 afhandelen

Tijdelijke fouten moeten worden verwerkt met behulp van logica voor opnieuw proberen. Situaties die moeten worden overwogen:

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

De eerste en tweede zaak zijn redelijk eenvoudig te verwerken. Probeer de verbinding opnieuw te openen. Wanneer u slaagt, is de tijdelijke fout opgelost door het systeem. U kunt uw Azure Database for MySQL opnieuw gebruiken. U wordt aangeraden te wachten voordat u de verbinding opnieuw probeert uit te voeren. Teruggaan als de eerste nieuwe pogingen mislukken. Op deze manier kan het systeem alle beschikbare resources gebruiken om de foutsituatie te verhelpen. Een goed patroon is:

  • Wacht vijf seconden voordat u het opnieuw probeert.
  • Voor elke volgende nieuwe poging neemt de wachttijd exponentieel toe, tot 60 seconden.
  • Stel een maximum aantal nieuwe pogingen in op welk punt de bewerking is mislukt door uw toepassing.

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 is geschreven, moet u bepalen of de transactie is teruggedraaid of als 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 als onderdeel van de transactie door aan de server en slaat deze op 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 bestaat in het systeem. Er mislukt een schending van een dubbele sleutel 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 verwerken die tijdens deze bewerking wordt aangetroffen zonder problemen.

Verbinding maken efficiënt naar 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 verbindingspooling 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. We raden u ten zeerste aan databaseverbindingspooling of permanente verbindingen te gebruiken om verbinding te maken met Azure Database for MySQL. Databaseverbindingspooling verwerkt het maken, beheren en toewijzen van databaseverbindingen. Wanneer een programma een databaseverbinding aanvraagt, wordt prioriteit gegeven aan de toewijzing van bestaande niet-actieve databaseverbindingen in plaats van aan 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 afgesloten.

Voor een betere illustratie bevat dit artikel een stukje voorbeeldcode die gebruikmaakt van JAVA als voorbeeld. Zie Apache Common DBCP voor meer informatie.

Notitie

De server configureert een time-outmechanisme om een verbinding te sluiten die 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 voor meer informatie om de effectiviteit van permanente verbindingen te garanderen.

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

Access-databases met behulp van een mechanisme voor wachten en opnieuw proberen met korte verbindingen

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

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

De server configureert een time-outmechanisme om een verbinding te sluiten die enige tijd inactief is om resources vrij te maken. Wanneer de client de database opnieuw opent, is deze 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 wordt weergegeven in het volgende voorbeeld, kunt u Tomcat JDBC-verbindingspooling 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 beschikbare inactieve verbindingen. Als een dergelijke verbinding effectief is, wordt deze rechtstreeks geretourneerd, anders trekt de verbindingsgroep de verbinding in. 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 inleidingsdocument 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