MoSKitoAnleitungJava8 Min. Lesezeit

Der komplette MoSKito Integration Guide – Schritt 1

Schritt 1 des Integration Guides: Wir binden MoSKito-Essential per AOP in den BurgerShop ein, verbinden MoSKito Inspect, erkunden die eingebauten Producer und zeichnen unsere erste Journey auf.

Nachdem wir im vorherigen Schritt unser Versuchskaninchen erstellt haben, ist es nun an der Zeit, MoSKito-Essential in unsere Anwendung zu integrieren. Unser Plan für heute:

  • Monitoring zu den Kernbereichen unseres Codes hinzufügen.
  • MoSKito Inspect herunterladen und verbinden
  • WebFilter und Listener kennenlernen

Am Ende des Guides möchten wir:

  • die Zugriffsdaten in MoSKito Inspect sehen,
  • eine Journey aufzeichnen.

Los geht’s!

I. Klassen für das Monitoring markieren.

Zunächst möchten wir einige Klassen zum Monitoring hinzufügen. Wir wollen nicht alle Klassen hinzufügen, weil das das Monitoring nur zumüllt. Zum Beispiel diese Klasse:

public class ShopableItem {
    private int price;
    private String name;
    private Category category;

    public ShopableItem(){
    }
...
}

Sie ist ein einfaches DTO, das nicht überwacht werden muss. Wir sollten Klassen überwachen, die tatsächlich Arbeit verrichten, die eine Nutzlast haben. Im Fall einer Spring-Anwendung sollten dazu mindestens Services und Controllers gehören.

Grundsätzlich sollte alles überwacht werden, was etwas Interessantes tut, reine „Property-Holder“-Klassen dagegen nicht.

Um unsere Services und Controllers zu überwachen, verwenden wir die AOP-Integration. Wir könnten auch Proxies oder sogar Spring-AOP verwenden, aber AOP ist derzeit die beste Wahl.

Um die AOP-Integration zu aktivieren, sind 2 Schritte nötig:

  • Abhängigkeiten und Build-Plugins zur pom.xml hinzufügen.
  • Klassen annotieren.

II. Abhängigkeiten deklarieren

Im Laufe dieses Guides werden wir einige Abhängigkeiten zu MoSKito-Artefakten hinzufügen. Daher ist es sinnvoll, eine Variable für die Version zu definieren, um in allen Artefakten dieselbe Version zu verwenden und sie leicht ändern zu können. In unserem Fall ist die Version 2.8.5.

Fügen Sie diese Zeilen irgendwo in Ihre pom.xml ein, am besten oberhalb des Abschnitts dependencies, da wir sie dort verwenden werden:

<properties>
    <source-version>1.8</source-version>
    <target-version>1.8</target-version>

    <moskito.version>2.8.5-SNAPSHOT</moskito.version> 
    <aspectj.version>1.8.7</aspectj.version> 
    <aspectj-maven-plugin.version>1.10</aspectj-maven-plugin.version>
    <aspectj-maven-plugin.complianceLevel>1.8</aspectj-maven-plugin.complianceLevel> 
</properties>

Fügen Sie nun die für AOP benötigten Abhängigkeiten hinzu:

      <dependencies>         
        <dependency>
            <groupId>net.anotheria</groupId>
            <artifactId>moskito-core</artifactId>
            <version>${moskito.version}</version>
        </dependency>
        <dependency>
            <groupId>net.anotheria</groupId>
            <artifactId>moskito-aop</artifactId>
            <version>${moskito.version}</version>
         </dependency>
      </dependencies>

und das AOP-Plugin im Abschnitt build.

<plugins>
    <plugin>
        <groupId>org.codehaus.mojo</groupId>
        <artifactId>aspectj-maven-plugin</artifactId>
        <version>${aspectj-maven-plugin.version}</version>
        <configuration>
            <complianceLevel>${aspectj-maven-plugin.complianceLevel}</complianceLevel>
            <source>${source-version}</source>
            <target>${target-version}</target>
            <aspectLibraries>
                <aspectLibrary>
                    <groupId>net.anotheria</groupId>
                    <artifactId>moskito-aop</artifactId>
                </aspectLibrary>
            </aspectLibraries>
        </configuration>
        <dependencies>
            <dependency>
                <groupId>org.aspectj</groupId>
                <artifactId>aspectjrt</artifactId>
                <version>${aspectj.version}</version>
            </dependency>
            <dependency>
                <groupId>org.aspectj</groupId>
                <artifactId>aspectjtools</artifactId>
                <version>${aspectj.version}</version>
            </dependency>
        </dependencies>
        <executions>
            <execution>
                <goals>
                    <goal>compile</goal>
                    <goal>test-compile</goal>
                </goals>
                <configuration>
                    <source>${source-version}</source>
                    <target>${target-version}</target>
                </configuration>
            </execution>
        </executions>
    </plugin>
</plugins>

Hinweis: Dieser Guide wurde für 2.8.5. aktualisiert. Sie müssen also die MoSKito-Version in der pom.xml anpassen.

Bisher haben wir allerdings noch nicht viel erreicht. Jetzt müssen wir die Klassen annotieren. Dazu öffnen wir die Klassen ShopController, OrderController, HomeController und ShopServiceImpl und fügen @Monitor oberhalb der Klassendeklarationen hinzu, etwa so:

@Monitor
public class ShopServiceImpl implements ShopService {

Ihre IDE sollte den richtigen Import für die Annotation @Monitor vorschlagen können. Falls nicht, lautet er: net.anotheria.moskito.aop.annotation.Monitor.

Nachdem wir sichergestellt haben, dass der Build weiterhin funktioniert, können wir versuchen, die gebaute Anwendung zu starten. Wir werden sehen, ob sie noch läuft. Das einzig Neue, nachdem wir http://localhost:8080/burgershop/ öffnen, sind einige neue Ausgabezeilen in den Logs, zum Beispiel diese:

00:43:33.864 [http-bio-8080-exec-8] INFO  n.a.m.c.r.ProducerRegistryImpl - Registry register producer: ShopController / OnDemandProducer (unlimited): ShopController:default:annotated

Prima, wir haben MoSKito jetzt also in unsere Anwendung integriert, können aber noch nichts sehen. Das ändern wir, indem wir Inspect verbinden.

III. Inspect verbinden

Um Inspect zu verbinden, sind zwei Schritte nötig: einen Connector in unserer App aktivieren und Inspect tatsächlich herunterladen und starten.

Damit sich MoSKito Inspect mit Ihrer Anwendung verbinden kann, müssen wir in Ihrer Anwendung (in diesem Fall burgershop) einen Endpoint starten. Dazu fügen wir der pom eine Abhängigkeit und der catalina.sh eine Zeile hinzu:

<dependency>
  <groupId>net.anotheria</groupId>
  <artifactId>moskito-inspect-remote</artifactId>
  <version>${moskito.version}</version>
</dependency>

Suchen Sie nun bitte Ihre catalina.sh (bzw. .bat) und fügen Sie ganz oben folgende Zeile hinzu:

export JAVA_OPTS="$JAVA_OPTS -DlocalRmiRegistryPort=9401"

Damit wird der MoSKito-Inspect-Endpoint angewiesen, eingehende RMI-Verbindungen auf Port 9401 anzunehmen. Sie können natürlich auch einen anderen Port angeben.

Bauen Sie Ihre App nun bitte neu und starten Sie sie neu.

Jetzt müssen wir nur noch Inspect herunterladen, und zwar hier: http://www.moskito.org/download.html oder direkt über diesen Link. Übrigens können Sie sich jederzeit Ihr eigenes MoSKito Inspect bauen, indem Sie einfach die WAR-Datei moskito-inspect-standalone in einen Servlet-Container Ihrer Wahl legen, sei es Resin, Tomcat oder Jetty. Denken Sie nur daran, dass Sie einen Servlet-3.0-kompatiblen Container benötigen; Tomcat 5 oder 6 funktionieren also nicht. Für den Moment bleiben wir aber bei unserem vorbereiteten Download.

Nachdem Sie das MoSKito-Inspect-Archiv heruntergeladen haben, entpacken Sie es an einem beliebigen Ort. Ich habe es zum Beispiel unter /opt entpackt:

cd /opt
tar -xzf ~/Downloads/moskito-inspect.tgz
cd moskito-inspect/

Der MoSKito-Inspect-Download ist im Grunde ein Tomcat mit einer WAR-Datei, Sie können ihn also wie einen normalen Tomcat starten:

cd tomcat/
bin/startup.sh

Der Standardport für MoSKito Inspect ist 8088, einfach weil es damit weniger Konflikte zu geben schien als mit 8080. Sie erreichen es also unter http://localhost:8088/moskito/

Wenn Sie alles richtig gemacht haben, sehen Sie diese Seite – ein laufendes MoSKito Inspect.

Sie können ein wenig herumklicken und feiern 😉 Aber bevor Sie sich zu sehr freuen: Was Sie jetzt sehen, sind Daten vom Tomcat von MoSKito Inspect selbst, nicht von Ihrer Burger-Verkaufs-App. Um das zu ändern, müssen Sie Inspect anweisen, sich mit dem burgershop zu verbinden. Klicken Sie auf den Reiter Producers (oder einen beliebigen anderen Reiter). Im unteren linken Bereich des Bildschirms sehen Sie eine „QuickConnect“-Box:

Geben Sie localhost als Host und 9401 als Port ein und klicken Sie auf Connect:

Der Bildschirm sollte neu laden, und nun sehen Sie Daten aus Ihrer Anwendung. Sie können das überprüfen, indem Sie diese URL anklicken: http://localhost:8088/moskito/moskito-inspect/mskShowProducersByCategory?pCategory=controller

Sie zeigt Ihnen die zuvor annotierten Controller und die Requests an sie:

Sie können jetzt einige Bestellungen im Shop aufgeben und zusehen, wie die Zahlen in der Controller-Übersicht steigen.

Für den ShopService selbst haben wir keine Kategorie angegeben, daher landet er in der Standardkategorie für annotierte Klassen, und die lautet … annotated: http://localhost:8088/moskito/moskito-inspect/mskShowProducersByCategory?pCategory=annotated

Die Bedienung von MoSKito Inspect beschreibe ich hier nicht, Sie finden sie im MoSKito Inspect User Guide. (Achtung: Zum Zeitpunkt der Erstellung dieses Guides bezieht sich der User Guide noch auf Version 2.4.x)

IV. Eingebaute Funktionen.

Indem wir den MoSKito-Inspect-Connector zu unserer Anwendung hinzugefügt haben, haben wir tatsächlich einige zusätzliche Features hinzugefügt, die ich hier kurz beschreiben möchte.

Die eingebauten Producer liefern einige nützliche Informationen darüber, was in Ihrer App passiert:

Ich nenne kurz einige davon:

Memory Pools

Memory Pools sammeln Informationen über die Speichernutzung in den verschiedenen Speicherbereichen, sei es Old Generation oder Young Generation. Das ist sehr hilfreich, um potenzielle Speicherprobleme zu erkennen.

ThreadStates und ThreadCount

Diese liefern Ihnen Informationen über die verschiedenen Zustände, in denen sich Ihre Threads befinden, und die Anzahl der Threads in jedem Zustand. Typischerweise möchten Sie Threads im Zustand „blocked“ vermeiden.

HttpSession

Die aktuelle Anzahl der Sessions sowie die Anzahl der im Zeitverlauf erzeugten und gelöschten Sessions.

Accumulators

Sie erhalten aber auch einige sofort einsatzbereite Accumulators:

So lässt sich zum Beispiel die Entwicklung Ihrer Threads direkt visualisieren:

URLs

MoSKito erfasst außerdem alle aufgerufenen URLs in Ihrer Anwendung und vieles mehr.

Das eigentliche Juwel sind aber die Journeys:

V. Unsere erste Journey aufzeichnen.

Eine Journey ist eine Aufzeichnung von Benutzeraktionen in Form der tatsächlichen Aufrufe/Schritte, die innerhalb einer Anwendung stattfinden. Mehr erfahren …

Es gibt mehrere Möglichkeiten, eine Journey zu starten. Eine der einfachsten ist, zusammen mit Ihrem Request einen speziellen Parameter mitzusenden. MoSKito prüft, ob dieser Parameter vorhanden ist, und zeichnet alles auf, was in dieser Benutzersession passiert.

Um unsere erste Journey zu starten, rufen wir die Startseite des Burgershops mit dem speziellen Parameter auf: http://localhost:8081/burgershop/home.html?mskJourney=start&mskJourneyName=GUIDE

Die Journey GUIDE erscheint sofort in MoSKito Inspect (Reiter Journeys):

Jetzt kann ich in einem Fenster durch die Anwendung klicken und in einem anderen nachverfolgen, was sie tatsächlich tut. Und das Beste daran: Der Overhead dieses Production Profiling ist so gering, dass Sie es tatsächlich ohne Nachteile für Ihre Nutzer einsetzen können – etwas, das ein normaler Profiler nicht könnte (von nicht genannten kommerziellen Produkten einmal abgesehen).

Nachdem ich einen vollständigen Bestellvorgang durchlaufen habe (nun ja, im burgershop besteht der gesamte Vorgang aus drei Requests ;-)), sehe ich ihn sofort:

Ich kann auf einen Schritt klicken und alle Aufrufe durch alle meine Messstationen (also alle mit @Monitor annotierten, per AOP oder CDI konfigurierten Klassen, Filter, SQL-Interceptors usw.) einschließlich Parametern und Rückgabewerten sehen:

Jetzt sehen wir, was in unserer Anwendung passiert, wenn die Bestellung aufgegeben wird: welcher Controller welchen Service aufruft, was der Service tut. Und wie lange es dauert. Und welche Parameter übergeben werden. Und die Fehler (falls vorhanden).

Der Burger Shop ist eine ziemlich einfache Anwendung, daher gibt es in der obigen Journey nicht viel zu sehen. Ich habe aber schon Anwendungen mit Journeys von bis zu 10000 Schritten Länge gesehen, und glauben Sie mir: Bei der Analyse solch langer Aufrufe gibt es viele Überraschungen.

Das Obige sollte Ihnen eine erste Vorstellung davon vermitteln, was Journeys leisten können. Wir werden in späteren Schritten auf die Journeys zurückkommen, insbesondere wenn wir über die Analyze-Funktion sprechen.

Was haben wir also heute gemacht?

  • Wir haben MoSKito in unsere Anwendung integriert.
  • Wir haben MoSKito Inspect installiert und verbunden.
  • Wir haben Monitoring für die zentralen Klassen unserer Anwendung hinzugefügt.
  • Wir haben eine Journey aufgezeichnet.

Im nächsten Kapitel fügen wir einen Counter, einen Producer mit eigenem Stats-Objekt, Thresholds und Accumulators hinzu. Danach fügen wir einen weiteren Server hinzu und nehmen beide Server mit MoSKito-Control ins Live-Monitoring. Und zu guter Letzt richten wir MoSKito-Central ein.

Viel Spaß und bis bald!

Nächster Schritt.

HINWEIS: Vielen Dank für Ihr Interesse an MoSKito! Dieser Blog ist jedoch kein Support-Forum. Wenn Sie ein Problem haben, schreiben Sie an support@moskito.org oder in unseren Olark-Kanal (auf www.moskito.org), oder eröffnen Sie ein GitHub-Issue: https://github.com/anotheria/moskito/issues bzw. ein Jira-Issue: https://jira.opensource.anotheria.net/projects/MSK (Jira erfordert eine Registrierung, die aber kostenlos ist).

Haben Sie ein System, das Sie ausbremst, oder eine Idee, die bisher niemand günstig genug bauen konnte?

Lassen Sie uns reden. 30 Minuten, ohne Pitch-Deck.

Worum geht es?