bachelor-thesis/chapters/thesis/chapter03.tex
2024-04-18 00:51:19 +02:00

189 lines
12 KiB
TeX

\chapter{Konzept}
\label{ch:concept}
Das folgende Kapitel enthält die im Rahmen dieser Arbeit entstandenen Konzepte, um die aktuellen Probleme aufzuzeigen.
Hierbei sind verschiedene Vorgehen zu verwenden, da die Anwendung aktuell noch nicht als produktive Anwendung
freigegeben ist. Zum einen werden die aktuelle Mitarbeiter befragt, zu anderen wird der Produktionsserver selbst
überprüft. Danach wird die Anwendung an sich untersucht und zum Schluss wird eine Neuentwicklung mit Hilfe anderer
Frameworks diskutiert.
\section{Aufbau der Umfrage}
\label{sec:concept:poll}
Die Umfrage wird per Email an die \mytodos{XX} Personen verschickt. Als Basis für die Umfrage wird der aktuelle Prototyp
unter \href{https://briefedition.wedekind.h-da.de} verwendet. Hierbei wird die gleiche Umfrage für Bearbeiter
und Benutzer versendet.
Die erste Frage ist zur Unterscheidung ob die Antworten von einen Bearbeiter oder von einem Benutzer kommt. Dies ist
nur notwendig, um bei der Nachstellung zu unterscheiden welche Zugriffsrechte aktiv sind und diese zu unterschiedlichen
Performance-Problemen führt.
Die weiteren Fragen sind aufeinander aufgebaut. Hierbei wird zuerst überprüft, bei welchen Aktionen eine längere
Wartezeit auftritt. Zusätzlich soll noch dazu angegeben werden, wie häufig dies auftritt, also ob dies regelmässig
auftritt oder immer nur zu bestimmten Zeitpunkten. Des Weiteren wird die Information nachgefragt, ob die Probleme
immer bei der gleichen Abfolge von Aktionen auftritt, oder die vorherigen Aktionen irrelevant sind.
Die Umfrage wird im Anhang \ref{ap:opinion-poll} dargestellt.
\section{Allgemeine Betrachtung des Systems}
\label{sec:concept:viewsystem}
Für die Untersuchung des Systems wird der direkte Zugang zum Server benötigt. Hierbei werden zuerst die im Kapitel
\ref{sec:basics:services} beschriebenen Einstellungen überprüft.
Zuerst wird am PostgreSQL"=Server die Konfiguration der Speicher mit der Vorgabe für Produktivsystem abgeglichen.
Hierunter fallen die Einstellungen für die \textit{shared\_buffers}, der bei einem Arbeitsspeicher von mehr als 1 GB
ca. 25\% des Arbeitsspeicher definiert sein soll \cite{PostgresC20.4:2024}.
\mytodos{die anderen Speicher abarbeiten?}
Dann wird mit dem Systemtools, wie den Konsolenanwendungen \textit{htop} und \textit{free}, die Auslastung des Servers
überprüft. Hierbei ist die CPU-Leistung, der aktuell genutzte Arbeitsspeicher, sowie die Zugriffe auf die Festplatte
die wichtigen Faktoren zur Bewertung.
Die CPU-Leistung sollte im Schnitt nicht die 70\% überschreiten, für kurze Spitzen wäre dies zulässig. Da sonst der
Server an seiner Leistungsgrenze arbeitet und dadurch es nicht mehr schafft die gestellten Anfragen schnell genug
abzuarbeiten.
Da unter Linux der Arbeitsspeicher nicht mehr direkt freigegeben wird, ist hier die Page-Datei der wichtigere Indikator.
Wenn dieses in Verwendung ist, dann benötigt die aktuell laufenden Programme mehr Arbeitsspeicher als vorhanden ist,
wodurch der aktuell nicht verwendete in die Page-Datei ausgelagert wird. Hierdurch erhöhen sich die Zugriffszeiten auf
diese Elemente drastisch.
Die Zugriffsgeschwindigkeit, die Zugriffszeit sowie die Warteschlange an der Festplatte zeigt deren Belastungsgrenze auf.
Hierbei kann es mehrere Faktoren geben. Zum einem führt das Paging des Arbeitsspeicher zu erhöhten Zugriffen. Ein zu
klein gewählter Cache oder gar zu wenig Arbeitsspeicher erhöhen die Zugriffe auf die Festplatte, da weniger
zwischengespeichert werden kann und daher diese Daten immer wieder direkt von der Festplatte geladen werden müssen.
\section{Untersuchung der Anwendung}
\label{sec:concept:softwarestructure}
Wie im Kapitel \ref{ch:basics} dargestellt, besteht die eigentliche Anwendung aus mehreren Schichten. Die
PostgreSQL"=Schicht wurde schon im vorherigen Kapitel betrachtet. Daher gehen wir nun weiter nach in den Schichten vom
Glassfish"=Server.
Die OpenJPA Cache Schicht wird nun einzeln untersucht. Hierfür werden die zuerst die Cache"=Statistik für Object"=Cache
und Query"=Cache aktiviert \citep[315]{MüllerWehr2012}. Die somit erfassten Werte, werden über eine Webseite
bereitgestellt, um die Daten Live vom Server verfolgen zu können. Zusätzlich können diese Daten über ein Skript
zyklisch abgefragt, gespeichert und vergleichen werden.
In der \ac{JPA} Schicht sind die Anzahl der Entitäten im Persistence Context zu beobachten. Die Anzahl der verschiedenen
Klassen soll ermittelt und die Statistik"=Webseite um diese Daten erweitern. Um die Daten zu ermitteln, kann der
Quellcode aus \ref{lst:persistence-context-statistics} verwendet werden.
\begin{lstlisting}[language=Java,caption={Persistence"=Kontext Statistik},label=lst:persistence-context-statistics]
EntityManagerFactory emf = Persistence.createEntityManagerFactory(...);
EntityManager em = emf.createEntityManager();
for(EntityType<?> entityType : em.getMetaModel().getEntities())
{
Class<?> managedClass = entityType.getBindableJavaType();
System.out.println("Managing type: " + managedClass.getCanonicalName());
}
// Oder bei JPA 2.0
emf.getCache().print();
\end{lstlisting}
% \mytodos{\url{https://eclipse.dev/eclipselink/api/2.1/org/eclipse/persistence/jpa/JpaCache.html#getObject(java.lang.Class,%20java.lang.Object)}}
Die Schicht \ac{EJB} besitzt keine Möglichkeit um eine sinnvolle Messung durchzuführen, daher wird hierfür keine
weiteren Messungen eingefügt.
Bei den \ac{JSP} wird eine Zeitmessung eingefügt. Hierfür müssen die Seiten so erweitert werden, dass zum einen die
Zeit gemessen wird um die Daten zu ermitteln. Zum anderen wird die Zeit gemessen wie lange es dann noch dauert um die
Seite mit den Daten zu rendern um diese an den Client auszuliefern. Diese 2 Zeiten sollen dann im Footer direkt auf der
Seite mit dargestellt werden. Somit kann der Benutzer auch direkt sehen, wenn das laden länger gedauert hat, an welcher
Stelle die Verzögerung aufgetreten ist.
Zum Schluss soll die gesamte Anwendung noch automatisiert getestet werden. Hierfür wird ein Shell-Skript erstellt, dass
automatisiert alle URLs der Webseite mehrfach abfragt. Die Dauer der Aufrufe der Webseiten werden gemessen und
statistisch ausgewertet. Für einen späteren Vergleich werden diese Informationen gesichert und mit einem erneuten Aufruf
nach den Optimierungen verglichen. Hierdurch kann auch festgestellt werden, ob die Optimierungen erfolgreich waren.
Das zugehörige Script ist im Anhang \ref{ap:timing} angehängt.
\section{Vergleich mit anderen Technologien}
\label{sec:concept:technologiecompare}
\mytodos{Noch tiefer eingehen?}
Damit eine Umsetzung auf eine andere Technologie umgestellt werden kann, muss dies den kompletten Technologie"=Stack
besitzen, wie dies von der \ac{JSP} unterstützt wird. Daher fallen reine FrontEnd"=Bibliotheken wie VueJS oder React aus
der Betrachtung heraus, da sie zusätzlich noch einen Backend für die Anwendungslogik (englisch business logic) benötigt.
\subsection{C\# - ASP.NET Core MVC}
\label{sec:concept:technologiecompare:aspnetcore}
Beim Vergleich zu \ac{JSP} steht ASP.NET Core MVC in nichts nach. Im großen und ganzen ist der Funktionsumfang der
gleiche und mit dem EntityFramework gibt es ebenfalls einen sehr mächtigen \ac{ORM}. Hierbei wird die Programmierung anhand
des \ac{MVC}"=Entwurfsmuster implementiert \citep{AspNetCore:2024:MVC}. Dieses Muster erleichtert die Trennung der
Benutzeranforderungen, welche durch die Controller mithilfe der Modelle abgearbeitet werden, von der Bedienoberfläche,
die hier in der Standardelementen von Webseiten, wie \ac{HTML}, \ac{CSS} und Javascript definiert werden. Zusätzlich
existiert noch ein spezifischer Syntax um die Daten dynamisch in die Seiten einzufügen.
Das System selbst ist in Schichten, auch Middleware genannt, aufgebaut \citep{AspNetCore:2024:Middleware}. Hierbei
übernimmt jede Middleware ihre entsprechende Aufgabe oder gibt die Anfrage an die nächste Middleware weiter und wartet
auf deren Antwort um diese und den Client zurückzugeben.
Diese Konzept wird direkt vom Standard umgesetzt und somit sind die unterschiedlichen Verarbeitungen getrennt
implementiert worden, was zu besserer Wartbarkeit des Programmcodes führt. Und die eigene Anwendung kann dadurch
je nach Bedarf die Middleware aktivierten, die wirklich benötigt wird.
Zusätzlich können über eine Vielzahl an vorhandenen NuGet-Paketen das Programm erweitert werden. Oder Komponenten
komplett ersetzt werden, wie z.B. das EntityFramework durch eine einfachere leichtere Version eines reinen \ac{ORM}
zu ersetzt.
C\# ist wie Java durch die neue .NET Runtime, aktuell in der Version 8 verfügbar, für die meisten Betriebssystem verfügbar.
Bei der Übersetzung hat C\# einen Vorteil gegenüber von Java, da hier der Code wie bei Java zuerst in eine Zwischencode
\ac{IL} kompiliert wird und zur Laufzeit über einen \ac{JIT} Compiler dann direkt in optimierten Maschinencode übersetzt wird.
Hierbei haben die meistens Test gezeigt, dass das .NET Framework hier um einiges effizienter und schneller arbeitet als
die Java Runtime. Zusätzlich wird bei ASP.NET Core nicht noch ein zusätzlicher Server benötigt um die Anwendung aktiv
zu halten.
\subsection{Golang}
\label{sec:concept:technologiecompare:golang}
Go (auch Golang) ist eine junge Programmiersprache, die sich durch Simplizität und Multifunktionalität auszeichnet, was
eines der Ziele bei der Entwicklung ist. Weitere Ziele waren die native Unterstützung von Nebenläufigkeit und die
leichte Verwaltung von großen Codebasen in größeren Entwicklerteams und ein hohen Übersetzungsgeschwindigkeit.
Hierdurch ist es sehr einfach und effizient möglich eine Anwendung mit Go zu entwickeln \citep{Golang:2024}.
Zusätzliche überzeugt Go durch die Typsicherheit und die automatische Speicherbereinigung durch den \ac{GC}.
Die Entwicklung von Microservices mit Go wird durch die integrierten Funktionen und Bibliotheken gut Unterstützt,
wodurch die Entwicklung, Bereitstellung und Skalierung erleichtert wird.
Go wird in eine native Anwendung übersetzt, da für die großen Betriebssystem entsprechende Compiler existieren, sind
Anwendung in Go ebenfalls nahezu Plattformunabhängig. Durch den integrierten Cross-Compiler, kann die Software direkt
für andere Betriebssystem mit erstellte werden.
Für eine dynamische Webseite, reichen die Standard-Bibliotheken, wobei auch hier gibt es verschiedene Frameworks die
eine Unterstützung für \ac{MVC} einbauen. Ein direkter \ac{ORM} ist ebenfalls vorhanden, um den einfachen Zugriff
auf eine Datenbank zu ermöglichen.
\subsection{PHP}
\label{sec:concept:technologiecmopare:php}
Mit der Skriptsprache PHP ist es sehr einfach eine dynamische Webseite zu entwickeln, da diese genau für solche
Zwecke entwickelt wurde. Hierbei wird der Code nicht übersetzt, sondern immer zu Laufzeit interpretiert, was im
Gegensatz zu den anderen vorgestellten Möglichkeiten im Sinne der Performance eindeutig ein Nachteil ist.
Dafür ist eine Änderung nur mit Hilfe eines Texteditor sehr einfach und schnell umzusetzen.
Der Zugriff auf eine Datenbank, ist direkt mit integriert und muss nur durch die Bereitstellung der passenden Treiber
aktiviert werden.
Die Template-Funktion für die Webseite wird nicht direkt unterstützt, sonder hier muss zwingend eine externe Bibliothek
verwendet werden. Sonst entsteht sehr viel gleicher Code, der auf Dauer nicht mehr Wartbar bleibt.
Für PHP gibt es ebenfalls umfangreiche Frameworks für die \ac{MVC}"=Unterstützung, wie z.B. \textit{Laravel} oder
\textit{Symfony}. Um diese Webseiten aber nun wieder auf den Webserver betreiben zu können wird der \textit{composer}
benötigt, der den Quellcode zusammenpackt und für die Bereitstellung vorbereitet. Hierbei ist die Leichtigkeit der
Skriptsprache aber verloren gegangen.
\subsection{Fazit}
\label{sec:concept:technologiecompare:summary}
Den größten Vorteil würde man aktuell mit der Umsetzung in Go bekommen, da dies für seine Geschwindigkeit und einfach
bekannt und Entwickelt wurde. Zudem ist die Programmiersprache sehr jung und hat keine Altlasten mit dabei. Der
größte Nachteil darin ist aber, dass hierfür noch nicht so viele Entwickler existieren, die dann das Projekt
unterstützen können.
Meiner Einschätzung nach, wäre ein Umstieg im aktuellen Stadium nicht sehr sinnvoll, da zum einen der großteil der
Anforderung umgesetzt ist, und für jeden Änderung die Mitarbeiter sich erst in die neue Code-Basis einarbeiten müssten.
Bei Weiterentwicklungen durch Studenten, ist man mit Java im Vorteil, da dies an der Uni gelehrt wird.