nbw-bt/Thesis/LaTeX/chapter3.tex
2014-09-26 15:45:57 +02:00

77 lines
No EOL
13 KiB
TeX

\epigraph{\textit{Neo, sooner or later you're going to realize just as I did that there's a difference between knowing the path and walking the path.}}{--- Morpheus, \textit{The Matrix}}
\noindent Vor der Entwicklung von Perl-Modulen mussten zunächst einige Abwägungen zur Integrationsweise getroffen werden. Es bieten sich verschiedene Möglichkeiten zur Überbrückung der Grenze zwischen Perl und \gls{kieker} an, die einleitend in \autoref{sec:perlMoeglich} diskutiert werden. Die gewählte Möglichkeit wird anschließend in \autoref{sec:perlImpl} detaillierter vorgestellt und schließlich in \autoref{sec:perlDataBridge} die Anbindung der Module an das vorhandene \gls{kieker} Framework beschrieben.
\section{Möglichkeiten der Integration}\label{sec:perlMoeglich}
Zur Verwendung des \gls{kieker} Frameworks mit neuen Programmiersprachen muss die Grenze zwischen den Sprachen überwunden werden. In früheren Arbeiten \citep{cau15486,cau15489} wurden hierzu bereits Überlegungen angestellt, die zu unterschiedlichen Ergebnissen gekommen sind. Auf dieses Projekt angewendet ergeben sich primär zwei Optionen, der Einsatz einer Perl-Java-Brücke oder eine Client/Server-basierte Lösung. Die ebenfalls mögliche Neuimplementierung von \gls{kieker} in Perl wurde nicht weiter berücksichtig, da neben erheblichem Aufwand in der Portierung die Pflege zweier funktional identischer Systeme nicht anzustreben ist.
\subsection{Verwendung einer Perl-Java-Brücke}
Für die Anbindung von .NET Anwendungen wurde in \citep{cau15486} eine kommerzielle .NET-Java-Bridge verwendet. Zur Zeit sind allerdings keine entsprechenden Brücken in ausreichender Stabilität für Perl verfügbar. Eine umfangreiche Implementierung, die Java-Perl Library von O'Reilly wird seit 1998 nicht mehr weiter gepflegt\citep{PRKUnix} und mehrere Open-Source Projekte\footnote{z.B. Java::Bridge: http://blogs.perl.org/users/theorbtwo/javabridge/ (Zuletzt aufgerufen 2013-03-20)} haben nicht die nötige Stabilität erreicht. Das Paket Inline::Java würde einige benötigte Funktionen bereitstellen, allerdings ist auch hier, aufgrund des hohen Alters der Bibliothek, ein problemloser Einsatz mit neueren Java Versionen zweifelhaft. Ebenso bestehen Probleme bei der Ausführung der Bibliothek im Rahmen eines Webdienstes. In Folge dieser Probleme wurde die Verwendung einer Brücke nicht weiter verfolgt.
\subsection{Entwicklung einer Client/Server-Architektur}
Als zweiter Ansatz ist eine Client/Server-Architektur zu verfolgen. Hierbei kommuniziert ein zu implementierender \gls{kieker} Perl-Client mit einem Java-basierten Server. Diese Prinzip ist in \autoref{fig:CommunicationDiagramClientServer} exemplarisch für diesen Fall dargestellt. Zur Kommunikation zwischen den Komponenten bieten sich verschiedene Protokolle wie TCP oder \gls{jms} an.
\begin{figure}
\centering
\includegraphics{images/Deployment-Diagram-Client-Server-Model}
\caption{Kommunikationsmodell im Client/Server System}
\label{fig:CommunicationDiagramClientServer}
\end{figure}
Es ist abzuwägen wieviele Kontrollmechanismen aus bestehenden \gls{kieker}-Komponenten übernommen werden können. Wird der bestehende Monitoring-Controller weiterverwendet müssen zusätzliche Nachrichten zur Trace-Verwaltung zwischen Client und Server versendet werden, die potentiell einen großen Einfluss auf die Laufzeit der Anwendung haben können. Andererseits steigt natürlich der Implementierungs- und Pflegeaufwand mit jedem zusätzlich neu in Perl realisierten Modul an und es können leichter Inkonsistenzen zwischen den verschiedenen \gls{kieker}-Implementierungen auftreten.
Für dieses Projekt wurde ein verhältnismäßig schwergewichtiger Perl-Client gewählt, der neben eigenen Methoden zur Zeitmessung auch die Traceverwaltung übernimmt. Die erhaltenen Daten können dann zur weiteren Aufbereitung an \gls{kieker} übergeben werden. Hierfür wird die Kieker-Data-Bridge verwendet, welche genauer in \autoref{sec:perlDataBridge} beschrieben wird.
\section{Implementierung}\label{sec:perlImpl}
Für das Monitoring von Perl-Anwendungen wurde ein Perl-Modul entwickelt, welche sich um die Erzeugung von \emph{\glspl{record}}, die Verwaltung und das Controlling sowie um die Kommunikation mit der Data-Bridge kümmert. Aufgrund der engen Zielsetzung wurde zunächst nur ein eingeschränkter Funktionsumfang des \gls{kieker} Frameworks umgesetzt. Die Module und ihre Verbindungen untereinander sind in \autoref{fig:ClassDiagramKiekerPerl} zu erkennen. Die zentralen Funktionen finden sich hier in dem Modul \textsf{Kieker.pm} wieder. Auf die einzelnen Komponenten und die Funktionsweise wird im folgenden eingegangen. Die Dokumentation der Pakete findet sich in \autoref{app:PerlDoc}.
\begin{figure}
\centering
\includegraphics[width=\textwidth]{images/Classdiagram-Kieker.Perl}
\caption{Klassendiagramm für Kieker.Perl}
\label{fig:ClassDiagramKiekerPerl}
\end{figure}
\subsection{Kieker}
Das Modul \gls{kieker} stellt eine schmale Schnittstelle zur einfachen Benutzung bereit. In diesem Modul werden die Controlling- und Writing-Komponenten verwaltet und Methoden für die verschiedenen Events bereitgestellt. In diesen Methoden werden die Optionen zur Zeitmessung und zum Schreiben der \emph{\glspl{record}} gekapselt. Somit bietet sich hier auch die Möglichkeit der Konfiguration an, um andere Writer-Module zu verwenden oder um andere Komponenten ersetzen zu können.
\subsection{Kieker::Controlling}
Das Controlling Modul verwaltet die Trace-Ids sowie die laufenden Zähler der Traces. Da im EPrints-Web-Kontext ein einzelner Request nur schwierig identifizierbar ist, wurde hier auf eine Notlösung zurückgegriffen und die Thread-Id des Perl-Interpreters als Trace-Id verwendet. Hierbei wird dann in der Apache-Konfiguration dafür gesorgt, dass jeder Request in einem eigenen Thread gestartet wird. Als bessere Lösung bietet es sich hier im Web-Kontext an, die angeforderte URL in Kombination mit einem Zeitstempel und eventuell einer IP-Adresse des Benutzers zu verwenden. Diese Informationen können allerdings nicht aus Umgebungsvariablen erzeugt werden, sondern erfordern z.B. ein Apache Request Object\footnote{Dokumentation unter http://perl.apache.org/docs/2.0/api/Apache2/RequestRec.html (Zuletzt aufgerufen 2013-03-24)}, welches allerdings von EPrints blockiert wird und somit hier nicht zur Verfügung steht.
Für die Zähler der Traces wird ein Hash verwendet, in dem die aktuellen Zählerstände verwaltet werden. Wird ein Zähler zu einem unbekannten, also neu angelegten, Trace angefordert wird automatisch der entsprechende Trace-Record erzeugt und an den Writer übergeben.
\subsection{Kieker::Util}
Im Util Modul werden Hilfsfunktionen zur einfacheren Verwendung der Module verwaltet. Im aktuellen Status wird hier nur die Zeitmessung gekapselt. Perl stellt keine Funktionen zur Messung von Nanosekunden, sondern lediglich das Paket Time::HiRes zur Messung in einem Paar (Sekunden,Mikrosekunden) bereit. Zur Kompatibilität mit der \gls{kieker} Zeitmessung wird eine Anpassung auf ein flaches Nanosekunden-Format durchgeführt. Hierbei wird natürlich keine Steigerung der Genauigkeit erreicht sondern lediglich ein Mikrosekunden-Zeitstempel in Nanosekunden ausgegeben.
\subsection{Kieker::Writer}
Unter Kieker::Writer wurden zwei verschiedene Ausgabemodule erstellt. In einer frühen Phase wurde zunächst Kieker::Writer::FileWriter verwendet, der automatisch zeilenweise in eine Datei schreibt, die bei der Initialisierung des Moduls erstellt wird. Dieser FileWriter wurde primär für frühe Entwicklungen und Tests verwendet.
Der später eingesetzte Writer ist Kieker::Writer::JMSWriter. Dieses Modul baut beim Start eine Verbindung zu einem laufenden JMS-Provider auf \citep[Zur Funktionsweise von JMS vgl.][]{OracleJMSSpecs}. Über diese Verbindung werden dann die \emph{\glspl{record}} in serialisierter Form an eine Message-Queue gesendet. Zur Verbindung mit dem JMS-Provider wird das Modul Net::Stomp verwendet, das die Nachrichten in Textform überträgt. Dieses Protokoll wird noch nicht von allen JMS-Providern unterstützt, bietet aber leichte Implementierbarkeit und ist somit auch in vielen anderen Sprachen verfügbar.
\subsection{Kieker::Record}
Die drei zur Zeit implementierten \emph{\glspl{record}} sind Trace, OperationEntryEvent und OperationExitEvent. Der Trace wird, wie bereits erwähnt, automatisch durch den Controller erzeugt sobald ein neuer Trace gestartet wird. Die beiden OperationEvents verfügen über die selben Attribute wie die entsprechenden \gls{kieker} Events und können nach Bedarf erzeugt werden. Zusätzlich verfügen die \emph{\glspl{record}} noch jeweils über eine Methode zur Serialisierung der Ausgabe. Hierbei werden den Events eindeutige Kennnummern zugewiesen, die später bei der Deserialisierung zur Identifizierung genutzt werden. Nach der Serialisierung sieht z.B. ein OperationEntryEven wie folgt aus:
\begin{verbatim}
1;1362747533540734000;6889;5;EPrints.current_repository;EPrints
\end{verbatim}
Dieses Nachrichtenformat wurde für die weitere Verwendung mit der Kieker-Data-Bridge entworfen.
\section{Übernahme der Daten in Kieker}\label{sec:perlDataBridge}
Zur Übernahme der Monitoringdaten in das bestehende \gls{kieker} System musste eine Methode geschaffen werden die serialisierten \emph{\glspl{record}} zu importieren. In den bisherigen Arbeiten wurde dies auf unterschiedliche Arten getan, so wurde in \citep{cau15489} das Programm \emph{Seq2Kieker} verwendet, welches sich an Stelle einer \gls{kieker} Probe in der bisherigen Struktur einbettet (vgl. dazu \autoref{fig:KiekerComponentDiagram}) und die erzeugten Protokolldaten in \gls{kieker} \emph{\glspl{record}} transformiert.
Damit nicht für jede neue Programmiersprache erneut eine Schnittstelle entwickelt werden muss, wurde begonnen eine einheitliche Schnittstelle bereitzustellen. Aus dem MENGES-Projekt \citep{Jung:2012} heraus wurde daraufhin von Reiner Jung begonnen die Kieker-Data-Bridge zu entwickeln. Um bereits zur Entwicklungszeit mit der Data-Bridge arbeiten zu können, habe ich zunächst Teile der Data-Bridge übernommen und um die Option zur Verwendung eines JMS-Providers sowie um die Verwendung von Textnachrichten statt Binärdaten erweitert. Diese Komponenten sind dann ebenfalls in die Data-Bridge migriert worden, so dass für die späteren Tests die fertige Data-Bridge verwendet werden konnte.
\begin{figure}
\centering
\includegraphics[width=0.9\textwidth]{images/kieker-data-bridge}
\caption[Komponentendiagramm Kieker-Data-Bridge]{Komponentendiagramm-Kieker-Data-Bridge\footnotemark}
\label{fig:KiekerDataBridge}
\end{figure}
\footnotetext{Grafik freundlicherweise zur Verfügung gestellt von Reiner Jung}
Die Data-Bridge kennt verschiedene Konnektoren, die durch die \emph{Service Connectors} realisiert werden. Zusätzliche Konnektoren für neue Kommunikationsarten können somit bei Bedarf ergänzt werden, indem ein neuer Service Connector erstellt wird. Zur Zeit kann die Bridge Daten direkt per TCP oder \gls{jms} entgegennehmen. Auch für den Verbindungsaufbau existieren verschiedene Verfahren, in denen die Kieker-Data-Bridge entweder als Server auf eingehende Verbindungen lauscht oder sich als Client an einem wartenden Monitoring Prozess anmeldet. Im JMS-Modus kann sich die Data-Bridge entweder an einem JMS-Provider anmelden oder einen eigenen JMS-Provider im eingebetteten Modus starten.
In dieser Arbeit werden die Nachrichten in Textform, wie in \autoref{sec:perlImpl} beschrieben, übertragen. Das Format wurde möglichst einfach gewählt um eine leichte Implementierbarkeit auch für zukünftige Projekte zu gewährleisten. Die Nachrichten beginnen mit einer Id, auf die, mit Semikolons getrennt, die Attribute folgen. Sollte ein Semikolon in den Datenfeldern auftreten, muss dieses maskiert werden. Dies sollte sich aber als unkritisch erweisen, da als Nutzdaten in den \emph{\glspl{record}} nur Zahlen oder Funktionsnamen übertragen werden, die in den meisten Programmiersprachen nur aus einem eingeschränkten Zeichensatz bestehen. Das Ende der Nachricht wird mit dem betriebssystemspezifischen Zeilenende signalisiert.
Die Identifizierung der \emph{\glspl{record}} erfolgt durch eine Mapping-Datei, in der für jeden Record Typen die eindeutige Id angegeben wird. Das von mir verwendete Mapping ist in \autoref{lst:recordMapping} angegeben.
\begin{lstlisting}[caption=Record Mapping der Kieker-Data-Bridge,label=lst:recordMapping]{}
1=kieker.common.record.flow.trace.operation.BeforeOperationEvent
2=kieker.common.record.flow.trace.operation.AfterOperationEvent
3=kieker.common.record.flow.trace.Trace
\end{lstlisting}
Nach der Auswahl des passenden Records werden die jeweiligen Attribute entsprechend dem TYPES Attribut der Records ausgewertet.
Neben den hier verwendeten Textnachrichten können die Nachrichten auch in einem binärem Modus übergeben werden. Außerdem kann die Data-Bridge nicht nur auf der Kommandozeile ausgeführt werden, sondern auch als Eclipse-Plugin verwendet werden. Diese Optionen wurden allerdings für diese Arbeit nicht verwendet.