Obsługa przejściowych błędów i wydajne łączenie się z usługą Azure Database for MySQL

DOTYCZY: Azure Database for MySQL — pojedynczy serwer

Ważne

Pojedynczy serwer usługi Azure Database for MySQL znajduje się na ścieżce wycofania. Zdecydowanie zalecamy uaktualnienie do serwera elastycznego usługi Azure Database for MySQL. Aby uzyskać więcej informacji na temat migracji do serwera elastycznego usługi Azure Database for MySQL, zobacz Co się dzieje z usługą Azure Database for MySQL — pojedynczy serwer?

W tym artykule opisano sposób obsługi błędów przejściowych i wydajnego nawiązywania połączenia z usługą Azure Database for MySQL.

Błędy przejściowe

Błąd przejściowy, znany również jako błąd przejściowy, jest błędem, który sam się rozwiąże. Najczęściej te błędy manifestują się jako połączenie z serwerem bazy danych, który jest porzucony. Nie można również otworzyć nowych połączeń z serwerem. Błędy przejściowe mogą wystąpić na przykład w przypadku awarii sprzętu lub sieci. Innym powodem może być nowa wersja usługi PaaS, która jest wdrażana. Większość z tych zdarzeń jest automatycznie ograniczana przez system w mniej niż 60 sekund. Najlepszym rozwiązaniem w zakresie projektowania i opracowywania aplikacji w chmurze jest oczekiwanie na błędy przejściowe. Załóżmy, że mogą one wystąpić w dowolnym składniku w dowolnym momencie i mieć odpowiednią logikę do obsługi tych sytuacji.

Obsługa błędów przejściowych

Błędy przejściowe powinny być obsługiwane przy użyciu logiki ponawiania prób. Sytuacje, które należy rozważyć:

  • Podczas próby otwarcia połączenia występuje błąd
  • Bezczynne połączenie jest porzucane po stronie serwera. Podczas próby wydania polecenia nie można go wykonać
  • Aktywne połączenie, które aktualnie wykonuje polecenie, jest porzucane.

Pierwszy i drugi przypadek są dość proste do obsługi. Spróbuj ponownie otworzyć połączenie. Po pomyślnym zakończeniu błąd przejściowy został skorygowany przez system. Możesz ponownie użyć usługi Azure Database for MySQL. Zalecamy, aby przed ponowić próbę nawiązania połączenia. Wycofaj się, jeśli początkowe próby nie ponawiają się. Dzięki temu system może użyć wszystkich dostępnych zasobów, aby przezwyciężyć sytuację z błędem. Dobrym wzorcem do naśladowania jest:

  • Poczekaj 5 sekund przed pierwszą ponowną próbą.
  • Dla każdego ponawiania próby zwiększ wykładniczo czas oczekiwania do 60 sekund.
  • Ustaw maksymalną liczbę ponownych prób, w którym aplikacja uzna, że operacja nie powiodła się.

Jeśli połączenie z aktywną transakcją zakończy się niepowodzeniem, trudniej jest poprawnie obsłużyć odzyskiwanie. Istnieją dwa przypadki: jeśli transakcja była tylko do odczytu, można bezpiecznie ponownie otworzyć połączenie i ponowić próbę transakcji. Jeśli jednak transakcja była również zapisywana w bazie danych, musisz określić, czy transakcja została wycofana lub czy powiodła się, zanim wystąpi błąd przejściowy. W takim przypadku po prostu nie otrzymano potwierdzenia zatwierdzenia z serwera bazy danych.

Jednym ze sposobów wykonania tej czynności jest wygenerowanie unikatowego identyfikatora na kliencie, który jest używany dla wszystkich ponownych prób. Ten unikatowy identyfikator należy przekazać jako część transakcji do serwera i zapisać go w kolumnie z unikatowym ograniczeniem. W ten sposób można bezpiecznie ponowić próbę transakcji. Powiedzie się, jeśli poprzednia transakcja została wycofana, a unikatowy identyfikator wygenerowany przez klienta jeszcze nie istnieje w systemie. Zakończy się to niepowodzeniem wskazującym naruszenie zduplikowanego klucza, jeśli unikatowy identyfikator został wcześniej zapisany, ponieważ poprzednia transakcja została pomyślnie ukończona.

Gdy program komunikuje się z usługą Azure Database for MySQL za pośrednictwem oprogramowania pośredniczącego innej firmy, zapytaj dostawcę, czy oprogramowanie pośredniczące zawiera logikę ponawiania prób dla błędów przejściowych.

Pamiętaj, aby przetestować logikę ponawiania prób. Na przykład spróbuj wykonać kod podczas skalowania w górę lub w dół zasobów obliczeniowych serwera usługi Azure Database for MySQL. Aplikacja powinna obsługiwać krótki przestój, który występuje podczas tej operacji bez żadnych problemów.

wydajne Połączenie w usłudze Azure Database for MySQL

Połączenia bazy danych są ograniczonym zasobem, dlatego efektywne wykorzystanie puli połączeń w celu uzyskania dostępu do usługi Azure Database for MySQL optymalizuje wydajność. W poniższej sekcji wyjaśniono, jak używać buforowania połączeń lub połączeń trwałych w celu bardziej efektywnego uzyskiwania dostępu do usługi Azure Database for MySQL.

Zarządzanie połączeniami bazy danych może mieć znaczący wpływ na wydajność aplikacji jako całości. Aby zoptymalizować wydajność aplikacji, należy zmniejszyć liczbę nawiązań połączeń i czas nawiązywania połączeń w kluczowych ścieżkach kodu. Zdecydowanie zalecamy używanie buforowania połączeń z bazą danych lub połączeń trwałych w celu nawiązania połączenia z usługą Azure Database for MySQL. Buforowanie połączeń z bazą danych obsługuje tworzenie, zarządzanie i alokację połączeń bazy danych. Gdy program żąda połączenia z bazą danych, określa priorytet alokacji istniejących bezczynnych połączeń bazy danych, a nie tworzenia nowego połączenia. Po zakończeniu korzystania z połączenia z bazą danych połączenie jest odzyskiwane w ramach przygotowań do dalszego użycia, a nie po prostu jest zamykane.

Aby uzyskać lepszą ilustrację, ten artykuł zawiera przykładowy kod , który używa języka JAVA jako przykładu. Aby uzyskać więcej informacji, zobacz Apache common DBCP.

Uwaga

Serwer konfiguruje mechanizm przekroczenia limitu czasu, aby zamknąć połączenie, które było w stanie bezczynności przez jakiś czas, aby zwolnić zasoby. Pamiętaj, aby skonfigurować system weryfikacji, aby zapewnić skuteczność połączeń trwałych podczas korzystania z nich. Aby uzyskać więcej informacji, zobacz Konfigurowanie systemów weryfikacji po stronie klienta, aby zapewnić skuteczność połączeń trwałych.

Koncepcja połączeń trwałych jest podobna do koncepcji buforowania połączeń. Zamiana krótkich połączeń na połączenia trwałe wymaga tylko drobnych zmian w kodzie, ale ma ona duży wpływ na poprawę wydajności w wielu typowych scenariuszach aplikacji.

Uzyskiwanie dostępu do baz danych przy użyciu mechanizmu oczekiwania i ponawiania prób z krótkimi połączeniami

Jeśli masz ograniczenia zasobów, zdecydowanie zalecamy używanie buforowania baz danych lub połączeń trwałych w celu uzyskiwania dostępu do baz danych. Jeśli w aplikacji występują krótkie połączenia i występują błędy połączeń, gdy zbliżasz się do górnego limitu liczby połączeń współbieżnych, możesz spróbować poczekać i ponowić próbę mechanizmu. Możesz ustawić odpowiedni czas oczekiwania z krótszym czasem oczekiwania po pierwszej próbie. Następnie możesz spróbować wielokrotnie czekać na zdarzenia.

Konfigurowanie mechanizmów weryfikacji na klientach w celu potwierdzenia skuteczności połączeń trwałych

Serwer konfiguruje mechanizm przekroczenia limitu czasu, aby zamknąć połączenie, które było w stanie bezczynności przez jakiś czas, aby zwolnić zasoby. Gdy klient ponownie uzyskuje dostęp do bazy danych, jest odpowiednikiem tworzenia nowego żądania połączenia między klientem a serwerem. Aby zapewnić skuteczność połączeń podczas procesu ich używania, skonfiguruj mechanizm weryfikacji na kliencie. Jak pokazano w poniższym przykładzie, można użyć puli połączeń Tomcat JDBC, aby skonfigurować ten mechanizm weryfikacji.

Ustawiając parametr TestOnBorrow, gdy istnieje nowe żądanie, pula połączeń automatycznie weryfikuje skuteczność wszystkich dostępnych bezczynnych połączeń. Jeśli takie połączenie jest skuteczne, zostanie zwrócona bezpośrednio, w przeciwnym razie pula połączeń wycofa połączenie. Następnie pula połączeń tworzy nowe efektywne połączenie i zwraca je. Ten proces zapewnia wydajny dostęp do bazy danych.

Aby uzyskać informacje na temat określonych ustawień, zobacz oficjalny dokument wprowadzający pulę połączeń JDBC. Należy przede wszystkim ustawić następujące trzy parametry: TestOnBorrow (ustawiona na wartość true), ValidationQuery (ustawiona na SELECT 1) i ValidationQueryTimeout (ustawiona na 1). Poniżej przedstawiono konkretny przykładowy kod:

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) {}
          }
      }
  }

Następne kroki