Teilen Sie eine Idee und nutzen Sie Instrumentierungstechnologie, um das Problem langsamer Abfragetests zu lösen.

Vor einiger Zeit hatte das System, für dessen Test ich verantwortlich war, Probleme beim Betrieb in der Produktionsumgebung . Das System stellt hohe Anforderungen an die Reaktionszeit. Wenn das Problem auftritt, ist die Parallelität sehr hoch. Es kommt zu einer großen Anzahl von Anforderungszeitüberschreitungen. Der Anteil der Zeitüberschreitungsanforderungen wird mit der Zeit immer höher. Am Ende schlagen fast alle Anforderungen fehl . Nach dem rollierenden Neustart aller Prozesse kam es bald erneut zu einer Zeitüberschreitung.

Nach der Untersuchung wurde festgestellt, dass eine Datenbankabfrageanweisung geändert wurde, als die neue Version eine bestimmte Funktion implementierte. Nach der Änderung verwendeten die Abfragebedingungen der Abfrageanweisung das Indexfeld nicht und die abgefragte Tabelle war in der Produktionsumgebung sehr groß , also diese Abfrageoperation Der Zeitverbrauch hat sich von Millisekunden auf Sekunden geändert, was eine sogenannte langsame Abfrage bildet. In Verbindung mit einer großen Parallelität kommt es zu einer Tragödie.

Nach dem Vorfall dachte unser Testteam darüber nach: Warum wurde ein so schwerwiegendes Problem in der Testumgebung nicht entdeckt? Zwei Gründe werden zusammengefasst : Erstens ist der Grad der Parallelität in der Testumgebung für Funktionstests nicht hoch , und es tritt keine Zeitüberschreitung auf, selbst wenn eine einzelne Anforderung langsamer wird; zweitens ist das Datenvolumen der Datenbanktabelle der Testumgebung viel kleiner als die der Produktionsumgebung , sodass einzelne Abfragevorgänge viel schneller sind als Produktionsvorgänge, sodass bei Anforderungen während Stresstests selten eine Zeitüberschreitung auftritt.

suchen

Zusammenfassend lässt sich sagen, dass es schwierig ist, eine langsame Abfrage während des Testvorgangs manuell zu identifizieren. Um zu verhindern, dass ein solches Problem erneut auftritt, haben wir in nachfolgenden Versionstests einige Versuche unternommen.

Da wir bereits über interne Code-Scan-Tools verfügen und jede Version einige Probleme durch Scannen identifiziert, haben wir zunächst darüber nachgedacht, den Originalcode statisch zu scannen, alle Datenbankabfrageanweisungen herauszufischen und sie dann zu analysieren. Nach dem eigentlichen Betrieb haben wir festgestellt, dass unser System eine große Anzahl von Frameworks für Datenbankoperationen verwendet. Verschiedene Module verwenden unterschiedliche Frameworks. Die extrahierten Datenbankanweisungen sind alle seltsam und enthalten Codeelemente, bei denen es sich nicht um Anweisungen handelt, die direkt ausgeführt werden können Große Systeme, manuell Die Analyse dieser Aussagen ist zu aufwändig und diese Methode ist nicht durchführbar.

Dann dachten wir, dass wir dieses Problem von der Datenbankseite aus lösen können. Durch Einschalten des langsamen Abfrageprotokollschalters von MySQL können wir während des Funktionstests alle Datenbankabfragevorgänge aufzeichnen, die länger als die Konfigurationszeit long_query_time sind, und dann analysieren, ob Es gibt nacheinander ein langsames Abfrageproblem.

Während des Prozesses haben wir viele Abfrageanweisungen aufgefangen, die langsam ausgeführt wurden. Nach der Analyse stellten wir jedoch fest, dass die meisten dieser Anweisungen von Testern ausgeführt wurden, um die Datenbank manuell abzufragen. Noch bedauerlicher ist dies aufgrund der geringen Größenordnung von Testdaten, Produktionsprobleme, die zuvor aufgetreten sind. Die Ausführungszeit der problematischen Abfrageanweisung in der Testumgebung hat long_query_time nicht überschritten, sodass sie nicht identifiziert werden konnte.

Es ist ersichtlich, dass diese Methode eine hohe Wahrscheinlichkeit falsch positiver und falsch negativer Ergebnisse aufweist und nicht durchführbar ist.

Innovation

Vorhandene Tools können unsere Anforderungen zur Identifizierung langsamer Abfrageanweisungen nicht erfüllen, daher haben wir uns entschieden, unsere eigenen Tools zu entwickeln. Durch viele Analysen und Experimente haben wir eine effiziente, genaue und vielseitige Lösung erhalten:

Bild

Nach der Analyse müssen zwei Probleme gelöst werden, um langsame Abfrageanweisungen zu identifizieren : Erstens, wie man die vom System ausgeführte Abfrageanweisung erhält , und zweitens, wie man analysiert, ob eine bestimmte Abfrage eine langsame Abfrage ist .

Um das erste Problem zu lösen, dachten wir über den Einsatz von Instrumentierungstechnologie nach .

Für eine Abfrageoperation interagiert diese Operation schließlich mit der Zieldatenbank, unabhängig davon, wie der Anwendungscode der oberen Ebene geschrieben ist oder welches Datenbankframework verwendet wird. Bei der Interaktion muss es sich um eine Standard-SQL-Anweisung handeln. Auf dieser Grundlage haben wir eine umfassende Analyse dieser Anwendung durchgeführt. Unser System wird auf Jboss bereitgestellt. Durch eine schichtweise Analyse haben wir diese Methode gefunden, die tatsächlich Abfragevorgänge und Datenbankinteraktionen durchführt. Sie befindet sich im JCA-Paket von Jboss und wird wie folgt geteilt. Zwei Orte:

① org.jboss.jca.adapters.jdbc.WrappedPreparedStatement.executeQuery()② org.jboss.jca.adapters.jdbc.WrappedStatement.executeQuery()

Durch eine große Anzahl von Experimenten haben wir festgestellt, dass alle Datenbankabfragevorgänge in unserem System zum Abschluss eine von ①② aufrufen müssen (andere Systeme rufen möglicherweise andere Methoden von JCA mit unterschiedlicher Implementierungslogik auf). Durch das Setzen eines Breakpoint-Bugs in ①② haben wir festgestellt, dass die SQL-Anweisung innerhalb der ①②-Methode vollständig sichtbar ist.

Als Nächstes verwendeten wir die Java Instrument API und die daraus abgeleiteten Open-Source-Komponenten, um ein Agentenprogramm zu erstellen. Starten Sie den Agenten, und der Agent fügt an diesen beiden Stellen dynamisch Stubs ein, wenn das Anwendungssystemprogramm ausgeführt wird. Der Inhalt des Stubs ist sehr einfach: Drucken Sie die ausgeführte SQL-Anweisung im Speicher des aktuellen Methodenkörpers an einen festen Ort ( Angenommen, wir setzen die SQL-Anweisung in die Protokolldatei A). Im Vergleich zum Schreiben eines zusätzlichen Drucksatzes innerhalb des Methodenkörpers von ①② verursacht die bloße Ausführung eines Druckvorgangs keine Beeinträchtigung der Geschäftslogik.

Wir haben also etwa Folgendes erreicht: Wenn das Anwendungssystem eine Datenbankabfrageoperation durchführen möchte, ruft es eines von ①② auf, um die Abfrage-SQL auszuführen. Wenn ①② aufgerufen wird, wird die ausgeführte SQL-Anweisung in die Protokolldatei A ausgegeben. Auf diese Weise zeichnet jeder Abfragevorgang die eigentliche Abfrageanweisung in der Protokolldatei A auf und vervollständigt so die Sammlung der Abfrageanweisungen.

Durch Instrumentierung haben wir eine große Anzahl von SQL-Anweisungen erhalten. Als Nächstes haben wir das zweite Problem gelöst: Wie kann festgestellt werden, ob eine Abfrageanweisung eine langsame Abfrage ist?

Aufgrund der Größenordnungsunterschiede zwischen Test- und Produktionsdaten ist es offensichtlich unwissenschaftlich, eine Beurteilung anhand der Ausführungszeit vorzunehmen. Gleichzeitig haben wir insgesamt Zehntausende SQL-Anweisungen erhalten, und eine direkte manuelle Analyse ist offensichtlich nicht möglich.

Wir haben an den von MySQL bereitgestellten EXPLAIN-Befehl gedacht, um SQL-Anweisungen zu erweitern und die Ausführungsgeschwindigkeit anhand des MySQL-Ausführungsplans wissenschaftlich zu beurteilen. Jede ausführbare SQL-Anweisung kann direkt mit dem EXPLAIN-Befehl abgerufen werden

Bild

Jede Spaltenbezeichnung im Ausführungsplan kann im Matching-Prozess als besorgniserregendes Element verwendet werden. Wir nennen es ein Indikatorelement. Wir verwenden die beiden wichtigsten Indikatorelemente im Zusammenhang mit der Abfrageeffizienz:

1. Schlüssel: Gibt den Schlüssel des Index an, der verwendet wird, wenn diese SQL-Anweisung ausgeführt wird.
2. Typ: Zugriffsmethode, die angibt, dass die Ausführung der SQL-Anweisung der Weg ist, die erforderlichen Zeilen in der Datenbanktabelle zu finden Mögliche Werte sind wie folgt:

system > const > eq_ref > ref > fulltext > ref_or_null > index_merge > unique_subquery > index_subquery > range > index > ALL

Von System zu ALL geht die Leistung von gut nach schlecht. Im Allgemeinen sollte garantiert werden, dass sie mindestens das Reichweitenniveau erreicht.

Im ersten Schritt wandeln wir alle SQL-Anweisungen in der Protokolldatei A nacheinander in Ausführungspläne um;

Der zweite Schritt besteht darin, eine Reihe von Regeln festzulegen, die auf den tatsächlichen Anforderungen des Systems basieren, um den Ausführungsplan zu filtern und Anweisungen zu finden, bei denen es sich möglicherweise um langsame Abfragen handelt.

Die Regeln für den Abgleich langsamer Abfragen in unserem System sind:

Geben Sie [NULL] ein ODER geben Sie [ Bereich, Index, ALLE] ODER Zeilen >= 1000 ein

Diese Regel bedeutet: Wenn eine SQL-Anweisung nicht indiziert wurde oder die Zugriffsmethode „Bereich“, „Index“ oder „ALL“ ist oder die geschätzte Anzahl der gescannten Zeilen größer oder gleich 1.000 ist, handelt es sich möglicherweise um eine langsame Abfrage.

Der dritte Schritt besteht darin, Anweisungen manuell zu analysieren, bei denen es sich möglicherweise um langsame Abfragen handelt.

Durch den zweiten Screening-Schritt haben wir die Anzahl der zu analysierenden SQL-Anweisungen von Hunderttausenden auf ein Dutzend reduziert und sie dann einzeln manuell analysiert.

Auf diese Weise haben wir den langsamen Abfragetest des Systems abgeschlossen. Die SQL-Anweisung, die in der Vergangenheit Produktionsprobleme verursachte, war ein Volltreffer, und andere mutmaßlich langsame Abfrageanweisungen wurden manuell anhand von Faktoren wie der Abfragehäufigkeit und der Größenordnung der Produktionsdatentabelle als nicht langsam eingestuft.

brechende Wellen

Später haben wir diese Lösung durch die Implementierung konfigurierbarer Agent-Instrumentierungsstandorte und Filterregeln für langsame Abfragen zu einem allgemeinen Framework optimiert und auf mehrere Systeme in der Abteilung ausgeweitet und dabei mehrere versteckte Gefahren langsamer Abfragen entdeckt.

Für diese auf Instrumentierung basierende langsame Abfragetestmethode ergeben sich folgende zusammenfassende Vorteile :

1. SQL-Anweisungen bieten umfassende Abdeckung und hohe Genauigkeit. Nur die Vorbereitung der Instrumentierungspunktanalyse kann die Erfassung aller SQL-Anweisungen garantieren, die während der Ausführung des Programms ausgeführt werden (da die tatsächlich ausgeführten SQL-Anweisungen erfasst werden können, hängt dies von der Vollständigkeit des Funktionstests ab) und die Analyse basierend auf dem Ausführungsplan ist leistungsfähiger. Es ist wissenschaftlich, wird nicht durch die Größe der Daten beeinflusst und weist eine höhere Genauigkeit auf.

2. Es verfügt über eine hervorragende Vielseitigkeit . Die Einfügeposition ist konfigurierbar und durch einfaches Ändern der Konfiguration können verschiedene Systeme verwendet werden. Bei den Stubs handelt es sich im Allgemeinen um bestimmte Klassen und Methoden des Datenbanktreiberpakets, die die zugrunde liegende Interaktion mit der Datenbank implementieren, und haben keinen Bezug zur spezifischen Anwendungsimplementierung. Mit anderen Worten, unabhängig von der Programmfunktion und unabhängig vom Datenbankframework wird verwendet, sofern die Konfiguration korrekt ist. Die Datenbankinteraktionsklassen und ihre Methoden können angepasst werden.

3. Nicht-invasiv, steckbar und für die zu testende Anwendung nicht wahrnehmbar. Wenn der Agent startet, ist die Instrumentierung dynamisch. Wenn der Agent stoppt, verschwindet der Instrumentierungspunkt. Es müssen keine Änderungen am Quellcode der zu testenden Anwendung vorgenommen werden. Der Erkennungsprozess hat keine Auswirkungen auf die Funktionen und kann während des Funktionstests leise abgeschlossen werden.


etwas Übung

Einige Studenten in der TesterHome-Community haben einige Gedanken und Praktiken, nachdem sie diese Idee gesehen haben:

1. Es fühlt sich wirklich erstaunlich an. Unsere Ideen zur Lösung dieses Problems sind so ähnlich. Ein Open-Source-Projekt, an dem ich vor zwei Jahren gearbeitet habe, nutzte diese Idee, wurde aber nicht gefördert. Nachdem ich das Unternehmen gewechselt habe, habe ich häufiger go verwendet. Das hat es schon lange her. Keine Updates mehr. https://github.com/bugVanisher/no-slow-query

2. Das Mybatis-Plug-in reicht aus. Natürliche Affinität. Ein JAR-Paket. Wird vom gesamten Unternehmen referenziert. Die Kosten für den Java-Agenten sind relativ hoch.

Dies ist ein Plug-in, das ich erstellt habe, um zu verhindern, dass Where-Tags ungültig werden. Dasselbe gilt für andere Methoden https://github.com/Forest10/forest10-tool/blob/master/src/main/java/com/forest10/mybatis /interceptor/BatchModifyForbiddenInterceptor. java

3. Basierend auf den Ideen des Originalplakats (Autor) implementiert und als Open Source bereitgestellt.

 https://github.com/tangyiming/sql-detect

Enthält Instrumentierungs-Plug-Ins, Plattform-Front-End und -Back-End, Demoanwendung, Datenbank-DDL und Datenressourcen.

Endlich: Das vollständige Video-Tutorial zum Softwaretest unten wurde zusammengestellt und hochgeladen. Freunde, die es benötigen, können es sich selbst besorgen [garantiert 100 % kostenlos]

Interviewdokument zum Softwaretest

Wir müssen lernen, um einen hochbezahlten Job zu finden. Die folgenden Interviewfragen stammen aus den neuesten Interviewmaterialien von erstklassigen Internetunternehmen wie Alibaba, Tencent, Byte usw., und einige Byte-Chefs haben maßgebliche Antworten gegeben. Nach Abschluss dieser Frage Ich glaube, dass jeder anhand der Interviewinformationen einen zufriedenstellenden Job finden kann.

おすすめ

転載: blog.csdn.net/AI_Green/article/details/132854658