\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{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} Bei der Performance-Untersuchung der Anwendung, wird sich im ersten Schritt auf die Dokumentenliste beschränkt. Anhand dieser können die Optimierungen getestet und überprüft werden. Im Nachgang können die daraus gewonnen Kenntnisse auf die anderen Abfragen übertragen werden. Die Dokumentenliste zeigt direkte und indirekte Informationen zu einem Dokument an. Hierzu gehört die Kennung des Dokumentes, das Schreibdatum, der Autor, der Adressat, der Schreibort und die Korrespondenzform. Nach jeder dieser Information kann der Bediener die Liste auf"= oder absteigend sortieren lassen. Zusätzlich wird die Liste immer nach dem Schreibdatum sortiert, um die Ergebnisse bei gleichen Werten der zu sortierenden Informationen, wie dem Schreibort, immer in einer chronologisch aufsteigenden Form zu darzustellen. Aktuell verwenden die Editoren die Dokumentenliste um die Briefe eines Adressaten zu filtern und diese in chronologische Reihenfolge aufzulisten und zu untersuchen wie Kommunikation zwischen den Wedekind und dem Adressat abgelaufen ist. Ebenso wird nach Standorten sortiert, um zu prüfen mit welchen Personen sich an den ... \mytodos{Hier noch mehr INfos dazu, für was genau die Editoren diese tun} Da die Daten in der 3. Normalform in der Datenbank gespeichert werden, sind einige Relationen für die Abfragen notwendig. Dies wird durch die generische Abfrage in \autoref{lst:documentlist} gezeigt. Zusätzlich wird für jedes dargestellte Dokument eine zusätzliche Abfrage durchgeführt, die in \autoref{lst:documentlist_sub} zeigt, dass auch hier weitere Relationen notwendig sind. \includecode[SQL]{chapters/thesis/chapter03_documentlist.sql}{lst:documentlist}{Generische Abfrage der Dokumentenliste} \includecode[SQL]{chapters/thesis/chapter03_documentlist_sub.sql}{lst:documentlist_sub}{Sub-Abfrage pro Dokument} Nach aktuellem Stand beinhaltet die Datenbank ca. 5400 Briefe, für die jeweils 2-7 eingescannte Faksimile gespeichert werden. Diese Graphik-Dateien werden im TIFF-Format abgespeichert und benötigen zwischen 1 und 80 MB Speicherplatz. Dadurch kommt die Datenbank aktuell auf ca. 3,8 GB. \mytodos{Die unteren Punkte nochmal untergliedern in Performance-messen und Statistiken prüfen, dann kann mit den Performance-messen die unterschiedlichen Aktionen durchgeführt werden in Kapitel 4} 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 oben 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 direkte Messungen eingefügt. Bei den \ac{JSF} 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. Um die Netzwerklatenz ignorieren zu können, wird das Skript auf dem gleichen Computer aufgerufen, auf dem die Webseite gestartet wurde. 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{JSF} 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{JSF} 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.