Daily CheckIn
This commit is contained in:
parent
94600c6f2a
commit
a795b3a43c
12 changed files with 79 additions and 60 deletions
11
.vscode/settings.json
vendored
11
.vscode/settings.json
vendored
|
@ -12,7 +12,6 @@
|
||||||
"Fouine",
|
"Fouine",
|
||||||
"freigeschalten",
|
"freigeschalten",
|
||||||
"Galster",
|
"Galster",
|
||||||
"Glassfish",
|
|
||||||
"JPQL",
|
"JPQL",
|
||||||
"Konsolenanwendungen",
|
"Konsolenanwendungen",
|
||||||
"lesbarere",
|
"lesbarere",
|
||||||
|
@ -41,12 +40,14 @@
|
||||||
"Backmatter",
|
"Backmatter",
|
||||||
"Classname",
|
"Classname",
|
||||||
"Datasource",
|
"Datasource",
|
||||||
|
"Deployen",
|
||||||
"Frontmatter",
|
"Frontmatter",
|
||||||
"IntelliJ",
|
"IntelliJ",
|
||||||
"JNDI",
|
"JNDI",
|
||||||
"Laravel",
|
"Laravel",
|
||||||
"Latexmk",
|
"Latexmk",
|
||||||
"Mainmatter",
|
"Mainmatter",
|
||||||
|
"Mindest",
|
||||||
"Nautsch",
|
"Nautsch",
|
||||||
"Payara",
|
"Payara",
|
||||||
"Poolname",
|
"Poolname",
|
||||||
|
@ -56,6 +57,7 @@
|
||||||
"Servlet",
|
"Servlet",
|
||||||
"Symfony",
|
"Symfony",
|
||||||
"addresseeperson",
|
"addresseeperson",
|
||||||
|
"adminpack",
|
||||||
"adressee",
|
"adressee",
|
||||||
"ajax",
|
"ajax",
|
||||||
"american",
|
"american",
|
||||||
|
@ -88,6 +90,7 @@
|
||||||
"ferniunithesis",
|
"ferniunithesis",
|
||||||
"firstname",
|
"firstname",
|
||||||
"fmtutil",
|
"fmtutil",
|
||||||
|
"glassfish",
|
||||||
"gpasswd",
|
"gpasswd",
|
||||||
"hcap",
|
"hcap",
|
||||||
"heapsort",
|
"heapsort",
|
||||||
|
@ -95,18 +98,23 @@
|
||||||
"ispublishedindb",
|
"ispublishedindb",
|
||||||
"javax",
|
"javax",
|
||||||
"jdbc",
|
"jdbc",
|
||||||
|
"jdbcdriver",
|
||||||
"jsonlog",
|
"jsonlog",
|
||||||
"maxint",
|
"maxint",
|
||||||
"modifiedat",
|
"modifiedat",
|
||||||
"ngerman",
|
"ngerman",
|
||||||
|
"onlineed",
|
||||||
"openjpa",
|
"openjpa",
|
||||||
"pacman",
|
"pacman",
|
||||||
"payara",
|
"payara",
|
||||||
"payra",
|
"payra",
|
||||||
"perfstat",
|
"perfstat",
|
||||||
"personid",
|
"personid",
|
||||||
|
"postgres",
|
||||||
"postgresql",
|
"postgresql",
|
||||||
"println",
|
"println",
|
||||||
|
"psql",
|
||||||
|
"rzungsverzeichnis",
|
||||||
"searchdocument",
|
"searchdocument",
|
||||||
"searchfulltext",
|
"searchfulltext",
|
||||||
"searchreference",
|
"searchreference",
|
||||||
|
@ -123,6 +131,7 @@
|
||||||
"typeof",
|
"typeof",
|
||||||
"validuntil",
|
"validuntil",
|
||||||
"wedekind",
|
"wedekind",
|
||||||
|
"wedeojpa",
|
||||||
"xsep"
|
"xsep"
|
||||||
],
|
],
|
||||||
}
|
}
|
|
@ -10,7 +10,7 @@
|
||||||
|
|
||||||
Für die Protokollierung der Abläufe im \ac{JSF} werden zwei Klassen benötigt. Über die Factory \ref{lst:logger_factory},
|
Für die Protokollierung der Abläufe im \ac{JSF} werden zwei Klassen benötigt. Über die Factory \ref{lst:logger_factory},
|
||||||
wird die Wrapper"=Klasse in die Bearbeitungsschicht eingeschleust. Diese Wrapper"=Klasse \ref{lst:logger} beinhaltet
|
wird die Wrapper"=Klasse in die Bearbeitungsschicht eingeschleust. Diese Wrapper"=Klasse \ref{lst:logger} beinhaltet
|
||||||
dann die eigentliche Performance"=Messung, inklusive der Ausgabe in die Log"=Datei des \textit{Glassfish}"=Servers.
|
dann die eigentliche Performance"=Messung, inklusive der Ausgabe in die Log"=Datei des \textit{GlassFish}"=Servers.
|
||||||
Zusätzlich muss in der Konfiguration \texttt{faces-config.xml} noch angepasst werden, wie in
|
Zusätzlich muss in der Konfiguration \texttt{faces-config.xml} noch angepasst werden, wie in
|
||||||
\ref{lst:logger_factory_activate}, um die Factory durch das System aufrufen zu lassen.
|
\ref{lst:logger_factory_activate}, um die Factory durch das System aufrufen zu lassen.
|
||||||
|
|
||||||
|
|
|
@ -30,7 +30,7 @@ Die folgende Übersicht hierzu ist eine Anlehnung an \citep{EffwFrankWedekind}.
|
||||||
Die Editions"= und Forschungsstelle Frank Wedekind (EFFW) wurde 1987 in der Hochschule Darmstadt gegründet. Ihre Intention
|
Die Editions"= und Forschungsstelle Frank Wedekind (EFFW) wurde 1987 in der Hochschule Darmstadt gegründet. Ihre Intention
|
||||||
ist es, den lange vernachlässigten Autor der europäischen Moderne in die öffentliche Aufmerksamkeit zu bringen. Die
|
ist es, den lange vernachlässigten Autor der europäischen Moderne in die öffentliche Aufmerksamkeit zu bringen. Die
|
||||||
Publikation der >>Kritischen Studienausgabe der Werke Frank Wedekinds. Darmstädter Ausgabe<<
|
Publikation der >>Kritischen Studienausgabe der Werke Frank Wedekinds. Darmstädter Ausgabe<<
|
||||||
wurde direkt nach der Erschließung der Wedekind-Nachlässe in Aarau, Lenzburg und München begonnen und im Jahre
|
wurde direkt nach der Erschließung der Wedekind"=Nachlässe in Aarau, Lenzburg und München begonnen und im Jahre
|
||||||
2013 abgeschlossen.
|
2013 abgeschlossen.
|
||||||
|
|
||||||
Da der 1864 geborene Frank Wedekind heute zu einen der bahnbrechenden Autoren der literarischen Moderne zählt, aber bisher sehr
|
Da der 1864 geborene Frank Wedekind heute zu einen der bahnbrechenden Autoren der literarischen Moderne zählt, aber bisher sehr
|
||||||
|
|
|
@ -8,13 +8,13 @@ dass jeder Wechsel einer Seite oder eine Suchanfrage als Web"=Request an den Ser
|
||||||
geht durch mehrere Schichten des Server"=System bis die Antwort an den Client zurückgesendet wird, wie in
|
geht durch mehrere Schichten des Server"=System bis die Antwort an den Client zurückgesendet wird, wie in
|
||||||
\autoref{fig:webrequest} dargestellt.
|
\autoref{fig:webrequest} dargestellt.
|
||||||
|
|
||||||
Es wird ab hier von einem \textit{Glassfish}"=Server die Rede sein. In der Praxis wird ein \textit{Payara}"=Server
|
Es wird ab hier von einem \textit{GlassFish}"=Server die Rede sein. In der Praxis wird ein \textit{Payara}"=Server
|
||||||
verwendet. Der \textit{Glassfish}"=Server ist die Referenz"=Implementierung von Oracle, welche für Entwickler
|
verwendet. Der \textit{GlassFish}"=Server ist die Referenz"=Implementierung von Oracle, welche für Entwickler
|
||||||
bereitgestellt wird und die neuesten Features unterstützt. Der \textit{Payara}"=Server ist aus dessen Quellcode entstanden
|
bereitgestellt wird und die neuesten Features unterstützt. Der \textit{Payara}"=Server ist aus dessen Quellcode entstanden
|
||||||
und ist für Produktivumgebungen gedacht, da dieser mit regelmäßigen Aktualisierungen versorgt wird. Im folgenden Text
|
und ist für Produktivumgebungen gedacht, da dieser mit regelmäßigen Aktualisierungen versorgt wird. Im folgenden Text
|
||||||
wird der Begriff \textit{Glassfish} verwendet.
|
wird für beide Anwendungen der Begriff \textit{GlassFish} verwendet.
|
||||||
|
|
||||||
Angefangen bei der Anfrage die über den Webbrowser an den Server gestellt wird und vom \textit{Glassfish}"=Server
|
Angefangen bei der Anfrage die über den Webbrowser an den Server gestellt wird und vom \textit{GlassFish}"=Server
|
||||||
empfangen wird. In diesem wird anhand des definierten Routing entschieden, an welchen \textit{Controller} im \textit{\ac{JSF}}
|
empfangen wird. In diesem wird anhand des definierten Routing entschieden, an welchen \textit{Controller} im \textit{\ac{JSF}}
|
||||||
die Anfrage weitergeleitet und verarbeitet wird. In diesem wird die Darstellung der Webseite geladen und die Anfragen
|
die Anfrage weitergeleitet und verarbeitet wird. In diesem wird die Darstellung der Webseite geladen und die Anfragen
|
||||||
für den darzustellenden Datenbestand abgeschickt.
|
für den darzustellenden Datenbestand abgeschickt.
|
||||||
|
@ -29,7 +29,7 @@ sind die \textit{Memory Buffers} notwendig, um den Zugriff auf die Festplatte zu
|
||||||
zu verringern. Um Anfragen, die den Zugriff auf die Festplatte benötigen effizienter zu gestalten, bereiten die
|
zu verringern. Um Anfragen, die den Zugriff auf die Festplatte benötigen effizienter zu gestalten, bereiten die
|
||||||
\textit{Services} die Datenstrukturen auf.
|
\textit{Services} die Datenstrukturen auf.
|
||||||
|
|
||||||
\begin{figure}[!ht]
|
\begin{figure}[H]
|
||||||
\begin{tikzpicture}[node distance=5em,
|
\begin{tikzpicture}[node distance=5em,
|
||||||
block/.style={rectangle, rounded corners,minimum width=3cm,minimum height=1cm,text centered, draw=black,fill=green!30},
|
block/.style={rectangle, rounded corners,minimum width=3cm,minimum height=1cm,text centered, draw=black,fill=green!30},
|
||||||
lineArrow/.style={arrows={-Latex[length=5pt 3 0]}},
|
lineArrow/.style={arrows={-Latex[length=5pt 3 0]}},
|
||||||
|
@ -44,8 +44,8 @@ zu verringern. Um Anfragen, die den Zugriff auf die Festplatte benötigen effizi
|
||||||
\node (EJB) [block,below of=JSF] {Enterprise Java Beans};
|
\node (EJB) [block,below of=JSF] {Enterprise Java Beans};
|
||||||
\node (JPA) [block,below of=EJB] {Java Persistance API};
|
\node (JPA) [block,below of=EJB] {Java Persistance API};
|
||||||
\node (openJPA) [block, below of=JPA] {OpenJPA Cache};
|
\node (openJPA) [block, below of=JPA] {OpenJPA Cache};
|
||||||
\node (fitGlassfish) [fit=(JSF) (EJB) (JPA) (openJPA)] {};
|
\node (fitGlassFish) [fit=(JSF) (EJB) (JPA) (openJPA)] {};
|
||||||
\node [left] at (fitGlassfish.west) {Glassfish};
|
\node [left] at (fitGlassFish.west) {GlassFish};
|
||||||
|
|
||||||
\node (memoryBuffers) [block, below of=openJPA] {Memory Buffers};
|
\node (memoryBuffers) [block, below of=openJPA] {Memory Buffers};
|
||||||
\node (services) [block, right of=memoryBuffers, xshift=2cm] {Services};
|
\node (services) [block, right of=memoryBuffers, xshift=2cm] {Services};
|
||||||
|
@ -53,7 +53,7 @@ zu verringern. Um Anfragen, die den Zugriff auf die Festplatte benötigen effizi
|
||||||
\node (fitPostgreSQL) [fit=(memoryBuffers) (services) (database)] {};
|
\node (fitPostgreSQL) [fit=(memoryBuffers) (services) (database)] {};
|
||||||
\node [left] at (fitPostgreSQL.west) {PostgreSQL};
|
\node [left] at (fitPostgreSQL.west) {PostgreSQL};
|
||||||
|
|
||||||
\node (fitServer) [fit=(fitGlassfish) (fitPostgreSQL),inner xsep=5em] {};
|
\node (fitServer) [fit=(fitGlassFish) (fitPostgreSQL),inner xsep=5em] {};
|
||||||
\node [left] at (fitServer.west) {Server};
|
\node [left] at (fitServer.west) {Server};
|
||||||
|
|
||||||
\draw[lineArrow] (browser)--(JSF);
|
\draw[lineArrow] (browser)--(JSF);
|
||||||
|
@ -68,11 +68,11 @@ zu verringern. Um Anfragen, die den Zugriff auf die Festplatte benötigen effizi
|
||||||
\label{fig:webrequest}
|
\label{fig:webrequest}
|
||||||
\end{figure}
|
\end{figure}
|
||||||
|
|
||||||
\section{Glassfish - Enterprise Java Beans}
|
\section{GlassFish - Enterprise Java Beans}
|
||||||
\label{sec:basics:ejb}
|
\label{sec:basics:ejb}
|
||||||
|
|
||||||
In den Java"=EE"=Anwendungen wird der \textit{Persistenzkontext} für die Anfragen vom \textit{Application"=Server}
|
In den Java"=EE"=Anwendungen wird der \textit{Persistenzkontext} für die Anfragen vom \textit{Application"=Server}
|
||||||
bereitgestellt. Hierfür werden \textit{Application"=Server} wie \textit{GlassFish} genutzt, um die Verwendung eines Pools
|
bereitgestellt. Hierfür werden \textit{Application"=Server} wie \textit{GlassFish} genutzt, um die Verwendung eines Pools % nicht eher die EJB innerhalb von glassfish
|
||||||
von Datenbankverbindungen zu definieren \citep[68]{MüllerWehr2012}. Dadurch kann die Anzahl der Verbindungen geringer
|
von Datenbankverbindungen zu definieren \citep[68]{MüllerWehr2012}. Dadurch kann die Anzahl der Verbindungen geringer
|
||||||
gehalten werden als die Anzahl der Benutzer, die an der Anwendung arbeiten. Zusätzlich werden die Transaktionen über
|
gehalten werden als die Anzahl der Benutzer, die an der Anwendung arbeiten. Zusätzlich werden die Transaktionen über
|
||||||
\textit{\ac{SFSB}} gehandhabt, welche automatisch vor dem Aufruf erzeugt und danach wieder gelöscht
|
\textit{\ac{SFSB}} gehandhabt, welche automatisch vor dem Aufruf erzeugt und danach wieder gelöscht
|
||||||
|
@ -81,7 +81,7 @@ Entities in den \textit{Persistenzkontext} geladen werden. Da dies häufig zu Sp
|
||||||
\citep[79]{MüllerWehr2012} führen kann, muss hier darauf geachtet werden, nicht mehr benötigte Entities aus dem
|
\citep[79]{MüllerWehr2012} führen kann, muss hier darauf geachtet werden, nicht mehr benötigte Entities aus dem
|
||||||
\textit{Persistenzkontext} zu lösen.
|
\textit{Persistenzkontext} zu lösen.
|
||||||
|
|
||||||
\section{Glassfish - Java Persistance API}
|
\section{GlassFish - Java Persistance API}
|
||||||
\label{sec:basics:jpa}
|
\label{sec:basics:jpa}
|
||||||
|
|
||||||
Die \textit{\ac{JPA}} wird als First"=Level"=Cache in Java"=EE"=Anwendung verwendet, hier nehmen die
|
Die \textit{\ac{JPA}} wird als First"=Level"=Cache in Java"=EE"=Anwendung verwendet, hier nehmen die
|
||||||
|
@ -96,7 +96,7 @@ Eine Menge von Objekten wird als \textit{Persistenzkontext} bezeichnet. Solange
|
||||||
überwacht, um diese am Abschluss mit der Datenbank zu synchronisieren. In der Literatur wird hierzu der Begriff
|
überwacht, um diese am Abschluss mit der Datenbank zu synchronisieren. In der Literatur wird hierzu der Begriff
|
||||||
\textit{Automatic Dirty Checking} verwendet \citep[61]{MüllerWehr2012}.
|
\textit{Automatic Dirty Checking} verwendet \citep[61]{MüllerWehr2012}.
|
||||||
|
|
||||||
\section{Glassfish - OpenJPA Cache}
|
\section{GlassFish - OpenJPA Cache}
|
||||||
\label{sec:basics:ojpac}
|
\label{sec:basics:ojpac}
|
||||||
|
|
||||||
Zusätzlich kann im \textit{\ac{JPA}} ebenfalls noch der \textit{Second Level Cache} (L2-Cache) aktiviert werden. Dieser steht
|
Zusätzlich kann im \textit{\ac{JPA}} ebenfalls noch der \textit{Second Level Cache} (L2-Cache) aktiviert werden. Dieser steht
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
\chapter{Konzept}
|
\chapter{Konzept}
|
||||||
\label{ch:concept}
|
\label{ch:concept}
|
||||||
|
|
||||||
Das folgende Kapitel enthält die im Rahmen dieser Arbeit entstandenen Konzepte, um die vorhanden Probleme zu
|
Das folgende Kapitel enthält die im Rahmen dieser Arbeit entstandenen Konzepte, um die vorhandenen Probleme zu
|
||||||
identifizieren und mit entsprechenden Maßnahmen entgegenzusteuern. Hierbei werden zum einen die Konfigurationen
|
identifizieren und mit entsprechenden Maßnahmen entgegenzusteuern. Hierbei werden zum einen die Konfigurationen
|
||||||
der eingesetzten Software überprüft. Zum anderen werden die verschiedenen Schichten der entwickelten Software
|
der eingesetzten Software überprüft. Zum anderen werden die verschiedenen Schichten der entwickelten Software
|
||||||
auf mögliche Optimierungen untersucht und bewertet.
|
auf mögliche Optimierungen untersucht und bewertet.
|
||||||
|
@ -16,7 +16,7 @@ Für die Untersuchung des Systems wird der direkte Zugang zum Server benötigt.
|
||||||
|
|
||||||
Zuerst wird am PostgreSQL"=Server die Konfiguration der Speicher mit der Vorgabe für Produktivsysteme abgeglichen.
|
Zuerst wird am PostgreSQL"=Server die Konfiguration der Speicher mit der Vorgabe für Produktivsysteme abgeglichen.
|
||||||
Hierunter fallen die Einstellungen für die \texttt{shared\_buffers}, der bei einem Arbeitsspeicher von mehr als 1 GB
|
Hierunter fallen die Einstellungen für die \texttt{shared\_buffers}, der bei einem Arbeitsspeicher von mehr als 1 GB
|
||||||
circa 25\% des Arbeitsspeicher besitzen sollte \cite{PostgresC20.4:2024}.
|
circa 25\% des Arbeitsspeichers besitzen sollte \cite{PostgresC20.4:2024}.
|
||||||
|
|
||||||
Bei der Einstellung \texttt{temp\_buffers} geht es um den Zwischenspeicher für jede Verbindung, die bei der Verwendung
|
Bei der Einstellung \texttt{temp\_buffers} geht es um den Zwischenspeicher für jede Verbindung, die bei der Verwendung
|
||||||
von temporären Tabellen verwendet wird. Dieser Wert sollte auf dem Standardwert von 8 MB belassen werden und lediglich
|
von temporären Tabellen verwendet wird. Dieser Wert sollte auf dem Standardwert von 8 MB belassen werden und lediglich
|
||||||
|
@ -24,9 +24,9 @@ bei der Verwendung von großen temporären Tabellen verändert werden.
|
||||||
|
|
||||||
Der Speicher, der für eine Abfrage verwendet werden darf, wird über die Konfiguration \texttt{work\_mem} gesteuert.
|
Der Speicher, der für eine Abfrage verwendet werden darf, wird über die Konfiguration \texttt{work\_mem} gesteuert.
|
||||||
Wenn der Speicher zu gering wird, werden die Zwischenergebnisse in temporäre Dateien ausgelagert. Der empfohlene Wert
|
Wenn der Speicher zu gering wird, werden die Zwischenergebnisse in temporäre Dateien ausgelagert. Der empfohlene Wert
|
||||||
berechnet sich aus \texttt{shared\_buffers} dividiert durch \texttt{max\_connections} \citep{ConfigTo12:online}.
|
berechnet sich aus \texttt{shared""\_buffers} dividiert durch \texttt{max\_connections} \citep{ConfigTo12:online}.
|
||||||
Sollte die Berechnung außerhalb der Grenzwerte von 1 MB und 256 MB liegen, ist der jeweilige Grenzwert zu verwenden.
|
Sollte die Berechnung außerhalb der Grenzwerte von 1 MB und 256 MB liegen, ist der jeweilige Grenzwert zu verwenden.
|
||||||
Um zu ermitteln, ob die Konfiguration richtig ist, muss im PostgreSQL die Einstellung \texttt{log\_temp\_files} auf 0 %TODO: log_temp_files überschreitet den Rand
|
Um zu ermitteln, ob die Konfiguration richtig ist, muss im PostgreSQL die Einstellung \texttt{log\_""temp\_""files} auf 0
|
||||||
gesetzt werden. Mit dieser kann ermittelt, ob temporäre Dateien verwendet werden sowie deren Größe. Bei vielen kleineren
|
gesetzt werden. Mit dieser kann ermittelt, ob temporäre Dateien verwendet werden sowie deren Größe. Bei vielen kleineren
|
||||||
Dateien sollte der Grenzwert erhöht werden. Bei wenigen großen Dateien ist es ist sinnvoll den Wert so zu belassen.
|
Dateien sollte der Grenzwert erhöht werden. Bei wenigen großen Dateien ist es ist sinnvoll den Wert so zu belassen.
|
||||||
|
|
||||||
|
@ -84,7 +84,7 @@ Speicherplatz. Dadurch kommt die Datenbank aktuell auf circa 3,8 GB.
|
||||||
|
|
||||||
Wie in \autoref{ch:basics} dargestellt, besteht die eigentliche Anwendung aus mehreren Schichten. Die
|
Wie in \autoref{ch:basics} dargestellt, besteht die eigentliche Anwendung aus mehreren Schichten. Die
|
||||||
PostgreSQL"=Schicht wurde schon im vorherigen Kapitel betrachtet. Daher werden nun die weiteren Schichten des
|
PostgreSQL"=Schicht wurde schon im vorherigen Kapitel betrachtet. Daher werden nun die weiteren Schichten des
|
||||||
Glassfish"=Server in aufsteigender Reihenfolge betrachtet.
|
GlassFish"=Server in aufsteigender Reihenfolge betrachtet.
|
||||||
|
|
||||||
Die OpenJPA Cache Schicht wird nun einzeln untersucht. Hierfür werden zuerst die Cache"=Statistik für Object"=Cache
|
Die OpenJPA Cache Schicht wird nun einzeln untersucht. Hierfür werden zuerst die Cache"=Statistik für Object"=Cache
|
||||||
und Query"=Cache aktiviert \citep[315]{MüllerWehr2012}. Die somit erfassten Werte werden über eine Webseite
|
und Query"=Cache aktiviert \citep[315]{MüllerWehr2012}. Die somit erfassten Werte werden über eine Webseite
|
||||||
|
@ -115,7 +115,7 @@ welchen Umfang die Umstellungen eine Veränderung im Verhalten der Webseite bewi
|
||||||
Bei den \ac{JSF} wird eine Zeitmessung einfügt, wofür eine \textit{Factory} benötigt wird. Diese wird in den Pipeline
|
Bei den \ac{JSF} wird eine Zeitmessung einfügt, wofür eine \textit{Factory} benötigt wird. Diese wird in den Pipeline
|
||||||
Prozess, der die Verarbeitung der Seiten steuert, eingebunden und erstellt die Klasse für die Messung.
|
Prozess, der die Verarbeitung der Seiten steuert, eingebunden und erstellt die Klasse für die Messung.
|
||||||
In dieser werden die Zeiten zum Ermitteln der Daten, das Zusammensetzen und das Rendern
|
In dieser werden die Zeiten zum Ermitteln der Daten, das Zusammensetzen und das Rendern
|
||||||
der Sicht ermittelt. Die Zeiten werden in die Log"=Datei des \textit{Glassfish}"=Servers hinterlegt und durch das
|
der Sicht ermittelt. Die Zeiten werden in die Log"=Datei des \textit{GlassFish}"=Servers hinterlegt und durch das
|
||||||
Skript ausgewertet. Somit ist es relativ leicht aufzuzeigen, an welcher Stelle die größte Verzögerung auftritt.
|
Skript ausgewertet. Somit ist es relativ leicht aufzuzeigen, an welcher Stelle die größte Verzögerung auftritt.
|
||||||
|
|
||||||
Die Abfragen werden ebenfalls untersucht und mit verschiedenen Methoden optimiert. Hierfür werden zum einen auf native
|
Die Abfragen werden ebenfalls untersucht und mit verschiedenen Methoden optimiert. Hierfür werden zum einen auf native
|
||||||
|
@ -132,7 +132,7 @@ Wichtig hierbei ist, dass die Webseite immer vollständig gerendert vom Server a
|
||||||
Somit kann die clientseitige Performance ignoriert werden, da alle Daten bereits direkt in diesem einem Aufruf bereitgestellt
|
Somit kann die clientseitige Performance ignoriert werden, da alle Daten bereits direkt in diesem einem Aufruf bereitgestellt
|
||||||
werden. In dem Skript werden zum einen die Laufzeiten der Webanfragen ermittelt, zum anderen die kürzeste, die längste und die
|
werden. In dem Skript werden zum einen die Laufzeiten der Webanfragen ermittelt, zum anderen die kürzeste, die längste und die
|
||||||
durchschnittliche Laufzeit ermittelt. Auf Grund der Speicherprobleme werden auch die Speicherbenutzung des
|
durchschnittliche Laufzeit ermittelt. Auf Grund der Speicherprobleme werden auch die Speicherbenutzung des
|
||||||
\textit{Glassfish}"=Servers vor und nach den Aufrufen ermittelt. Zum Schluss werden noch die Log"=Dateien des
|
\textit{GlassFish}"=Servers vor und nach den Aufrufen ermittelt. Zum Schluss werden noch die Log"=Dateien des
|
||||||
\textit{PostgreSQL}"=Servers über das Tool \textit{pgBadger} analysiert und als Bericht aufbereitet.
|
\textit{PostgreSQL}"=Servers über das Tool \textit{pgBadger} analysiert und als Bericht aufbereitet.
|
||||||
|
|
||||||
Um die Netzwerklatenz ignorieren zu können, wird das Skript auf dem gleichen Computer aufgerufen, auf dem der Webserver
|
Um die Netzwerklatenz ignorieren zu können, wird das Skript auf dem gleichen Computer aufgerufen, auf dem der Webserver
|
||||||
|
|
|
@ -150,7 +150,7 @@ durch das \texttt{ANALYZE} beziehungsweise \texttt{VACUUM ANALYZE} Kommando die
|
||||||
weitere gesammelt und für die Erstellung der Abfragepläne verwendet \citep{PostgreS39:online}. Diese Information
|
weitere gesammelt und für die Erstellung der Abfragepläne verwendet \citep{PostgreS39:online}. Diese Information
|
||||||
sollte vor dem erstellen eines Index betrachtet werden.
|
sollte vor dem erstellen eines Index betrachtet werden.
|
||||||
|
|
||||||
Diese Informationen können noch durch das Kommando \texttt{CREATE STATISTICS} erweitert werden, für einen besseren %TODO texttt zeigt über den Rand
|
Diese Informationen können noch durch das Kommando \linebreak\texttt{CREATE STATISTICS} erweitert werden, für einen besseren
|
||||||
Abfrageplan. Das Aktivieren der zusätzlichen Statistiken sollte immer in Verbindung mit der Überprüfung des
|
Abfrageplan. Das Aktivieren der zusätzlichen Statistiken sollte immer in Verbindung mit der Überprüfung des
|
||||||
Abfrageplans durchgeführt werden, um zu ermitteln inwieweit die Anpassung zu einer Optimierung und keiner
|
Abfrageplans durchgeführt werden, um zu ermitteln inwieweit die Anpassung zu einer Optimierung und keiner
|
||||||
Verschlechterung führt.
|
Verschlechterung führt.
|
||||||
|
|
|
@ -32,7 +32,7 @@ Aufrufe steuert. Die Ergebnisse werden in eine Tabelle überführt, wie in \auto
|
||||||
Hierbei werden die Aufrufzeiten der Webseite aus dem Skript für die Zeitmessung mit Mindest"~, Durchschnitt"~ und
|
Hierbei werden die Aufrufzeiten der Webseite aus dem Skript für die Zeitmessung mit Mindest"~, Durchschnitt"~ und
|
||||||
Maximalzeit aufgenommen, hierbei ist eine kürzere Zeit besser. Zusätzlich wird die Anzahl der aufgerufenen \ac{SQL} Abfragen
|
Maximalzeit aufgenommen, hierbei ist eine kürzere Zeit besser. Zusätzlich wird die Anzahl der aufgerufenen \ac{SQL} Abfragen
|
||||||
ermittelt, auch hier gilt, je weniger Aufrufe desto besser. Als letztes wird noch der verwendete Arbeitsspeicher
|
ermittelt, auch hier gilt, je weniger Aufrufe desto besser. Als letztes wird noch der verwendete Arbeitsspeicher
|
||||||
vom \textit{Glassfish}"=Server vor und nach dem Aufruf ermittelt und die Differenz gebildet, hierbei sollte im idealen
|
vom \textit{GlassFish}"=Server vor und nach dem Aufruf ermittelt und die Differenz gebildet, hierbei sollte im idealen
|
||||||
Fall die Differenz bei 0 liegen. Dieser Aufbau gilt für alle weiteren Messungen. Zusätzlich werden noch die Laufzeiten
|
Fall die Differenz bei 0 liegen. Dieser Aufbau gilt für alle weiteren Messungen. Zusätzlich werden noch die Laufzeiten
|
||||||
der \ac{JSF} ermittelt und die durchschnittlichen Zeiten mit in der Tabelle dargestellt, und auch hier ist es besser,
|
der \ac{JSF} ermittelt und die durchschnittlichen Zeiten mit in der Tabelle dargestellt, und auch hier ist es besser,
|
||||||
wenn die Zeiten kürzer sind.
|
wenn die Zeiten kürzer sind.
|
||||||
|
@ -44,7 +44,7 @@ Ebenfalls sieht man eindeutig, dass die Anzahl der Anfragen nach dem ersten Aufr
|
||||||
Der Speicherbedarf steigt relativ gleichmässig, was nicht recht ins Bild passt, da hier keine Objekte im Cache
|
Der Speicherbedarf steigt relativ gleichmässig, was nicht recht ins Bild passt, da hier keine Objekte im Cache
|
||||||
gehalten werden sollten.
|
gehalten werden sollten.
|
||||||
|
|
||||||
\begin{table}[!h]
|
\begin{table}[H]
|
||||||
\centering
|
\centering
|
||||||
\begin{tabular}{|r|r|r|r|r|r|r|r|}
|
\begin{tabular}{|r|r|r|r|r|r|r|r|}
|
||||||
\hline
|
\hline
|
||||||
|
@ -88,7 +88,7 @@ Zusätzlich wird die Zeit des Rendern der Sicht gemessen. Die erste Messung erfa
|
||||||
notwendig benötigt wird. Diese Zeit wird unterteilt in die Messungen für das Laden der Daten aus der Datenbank und das Erstellen
|
notwendig benötigt wird. Diese Zeit wird unterteilt in die Messungen für das Laden der Daten aus der Datenbank und das Erstellen
|
||||||
der Java"=Objekte inklusive dem Befüllen mit den geladenen Daten.
|
der Java"=Objekte inklusive dem Befüllen mit den geladenen Daten.
|
||||||
|
|
||||||
\begin{table}[h]
|
\begin{table}[H]
|
||||||
\centering
|
\centering
|
||||||
\resizebox{\textwidth}{!}{
|
\resizebox{\textwidth}{!}{
|
||||||
\begin{tabular}{|r|r|r|r|r|r|r|r|r|r|r|r|r|r|r|}
|
\begin{tabular}{|r|r|r|r|r|r|r|r|r|r|r|r|r|r|r|}
|
||||||
|
@ -132,7 +132,7 @@ Cache. Alle nachfolgenden Aufrufe wiederrum sind um 100ms schneller in der Verar
|
||||||
Anfragen an die Datenbank kann der Rückgang der Anfragen sehr gut gesehen werden. Aktuell kann die Verringerung des
|
Anfragen an die Datenbank kann der Rückgang der Anfragen sehr gut gesehen werden. Aktuell kann die Verringerung des
|
||||||
wachsenden Speicherbedarfs nur nicht erklärt werden.
|
wachsenden Speicherbedarfs nur nicht erklärt werden.
|
||||||
|
|
||||||
\begin{table}[h!]
|
\begin{table}[H]
|
||||||
\centering
|
\centering
|
||||||
\resizebox{\textwidth}{!}{
|
\resizebox{\textwidth}{!}{
|
||||||
\begin{tabular}{|r|r|r|r|r|r|r|r|r|r|r|r|r|r|r|}
|
\begin{tabular}{|r|r|r|r|r|r|r|r|r|r|r|r|r|r|r|}
|
||||||
|
@ -159,7 +159,7 @@ Cache"=Größe, aber schon die Anfragen an die Datenbank gehen drastisch zurück
|
||||||
Schnitt nun nur noch 6 Anfragen pro Seitenaufruf an die Datenbank gestellt, wodurch die Laufzeit im Schnitt nochmal
|
Schnitt nun nur noch 6 Anfragen pro Seitenaufruf an die Datenbank gestellt, wodurch die Laufzeit im Schnitt nochmal
|
||||||
um 100 ms beschleunigt werden konnte.
|
um 100 ms beschleunigt werden konnte.
|
||||||
|
|
||||||
\begin{table}[!ht]
|
\begin{table}[H]
|
||||||
\centering
|
\centering
|
||||||
\resizebox{\textwidth}{!}{
|
\resizebox{\textwidth}{!}{
|
||||||
\begin{tabular}{|r|r|r|r|r|r|r|r|r|r|r|r|r|r|r|}
|
\begin{tabular}{|r|r|r|r|r|r|r|r|r|r|r|r|r|r|r|}
|
||||||
|
@ -185,7 +185,7 @@ die \textit{SoftReference} nicht das Problem für den steigenden Arbeitsspeicher
|
||||||
\autoref{tbl:measure-ojpa-active-bigger-no-softref} ersichtlich.
|
\autoref{tbl:measure-ojpa-active-bigger-no-softref} ersichtlich.
|
||||||
|
|
||||||
% document, documentaddresseeperson, first/last, documentcoauthorperson, count und documentfacsimile
|
% document, documentaddresseeperson, first/last, documentcoauthorperson, count und documentfacsimile
|
||||||
\begin{table}[h!]
|
\begin{table}[H]
|
||||||
\centering
|
\centering
|
||||||
\resizebox{\textwidth}{!}{
|
\resizebox{\textwidth}{!}{
|
||||||
\begin{tabular}{|r|r|r|r|r|r|r|r|r|r|r|r|r|r|r|}
|
\begin{tabular}{|r|r|r|r|r|r|r|r|r|r|r|r|r|r|r|}
|
||||||
|
@ -220,7 +220,7 @@ die keine Parameter verwenden. Das sieht man auch entsprechend der Auswertung de
|
||||||
mit \ac{JPQL} oder Criteria API abfragt wird.
|
mit \ac{JPQL} oder Criteria API abfragt wird.
|
||||||
|
|
||||||
% document, documentaddresseeperson, first/last, documentcoauthorperson, count und documentfacsimile
|
% document, documentaddresseeperson, first/last, documentcoauthorperson, count und documentfacsimile
|
||||||
\begin{table}[h!]
|
\begin{table}[H]
|
||||||
\centering
|
\centering
|
||||||
\resizebox{\textwidth}{!}{
|
\resizebox{\textwidth}{!}{
|
||||||
\begin{tabular}{|r|r|r|r|r|r|r|r|r|r|r|r|r|r|r|}
|
\begin{tabular}{|r|r|r|r|r|r|r|r|r|r|r|r|r|r|r|}
|
||||||
|
@ -263,7 +263,7 @@ verbessert hat. Dies lässt auch hier den Schluss zu, dass die Erstellung der Ob
|
||||||
benötigt.
|
benötigt.
|
||||||
|
|
||||||
% document, documentaddresseeperson, first/last, documentcoauthorperson, count und documentfacsimile
|
% document, documentaddresseeperson, first/last, documentcoauthorperson, count und documentfacsimile
|
||||||
\begin{table}[h!]
|
\begin{table}[H]
|
||||||
\centering
|
\centering
|
||||||
\resizebox{\textwidth}{!}{
|
\resizebox{\textwidth}{!}{
|
||||||
\begin{tabular}{|r|r|r|r|r|r|r|r|r|r|r|r|r|r|r|}
|
\begin{tabular}{|r|r|r|r|r|r|r|r|r|r|r|r|r|r|r|}
|
||||||
|
@ -299,7 +299,7 @@ wurde. Dies ist dadurch zu erklären, dass im \ac{EJB} die Provider gelagert wer
|
||||||
dem Controller bereitgestellt werden. Die Objekte selbst werden nicht im \ac{EJB}"=Cache hinterlegt.
|
dem Controller bereitgestellt werden. Die Objekte selbst werden nicht im \ac{EJB}"=Cache hinterlegt.
|
||||||
|
|
||||||
% document, documentaddresseeperson, first/last, documentcoauthorperson, count und documentfacsimile
|
% document, documentaddresseeperson, first/last, documentcoauthorperson, count und documentfacsimile
|
||||||
\begin{table}[h!]
|
\begin{table}[H]
|
||||||
\centering
|
\centering
|
||||||
\resizebox{\textwidth}{!}{
|
\resizebox{\textwidth}{!}{
|
||||||
\begin{tabular}{|r|r|r|r|r|r|r|r|r|r|r|r|r|r|r|}
|
\begin{tabular}{|r|r|r|r|r|r|r|r|r|r|r|r|r|r|r|}
|
||||||
|
@ -430,7 +430,7 @@ Wie in der Messung in \autoref{tbl:measure-criteria-api} zu sehen, unterscheiden
|
||||||
von denen mit \ac{JPQL}. Wenn man sich den Code im Debugger betrachtet, lässt sich erkennen, dass die zusammengesetzten
|
von denen mit \ac{JPQL}. Wenn man sich den Code im Debugger betrachtet, lässt sich erkennen, dass die zusammengesetzten
|
||||||
Abfragen in den Java-Objekten fast identisch sind. In der Datenbank sind die Anfragen identisch zu denen über JPQL.
|
Abfragen in den Java-Objekten fast identisch sind. In der Datenbank sind die Anfragen identisch zu denen über JPQL.
|
||||||
|
|
||||||
\begin{table}[h!]
|
\begin{table}[H]
|
||||||
\centering
|
\centering
|
||||||
\resizebox{\textwidth}{!}{
|
\resizebox{\textwidth}{!}{
|
||||||
\begin{tabular}{|r|r|r|r|r|r|r|r|r|r|r|r|r|r|r|}
|
\begin{tabular}{|r|r|r|r|r|r|r|r|r|r|r|r|r|r|r|}
|
||||||
|
@ -590,7 +590,7 @@ vorhanden Elemente, welche die Liste der Dokumente anzeigt, kopiert und auf die
|
||||||
|
|
||||||
% document, first/last, documentaddresseeperson, documentcoauthorperson, documentfacsimile und count
|
% document, first/last, documentaddresseeperson, documentcoauthorperson, documentfacsimile und count
|
||||||
% document, count, first/last
|
% document, count, first/last
|
||||||
\begin{table}[h!]
|
\begin{table}[H]
|
||||||
\centering
|
\centering
|
||||||
\resizebox{\textwidth}{!}{
|
\resizebox{\textwidth}{!}{
|
||||||
\begin{tabular}{|r|r|r|r|r|r|r|r|r|r|r|r|r|r|r|}
|
\begin{tabular}{|r|r|r|r|r|r|r|r|r|r|r|r|r|r|r|}
|
||||||
|
@ -630,7 +630,7 @@ AND d.ispublishedindb = true;
|
||||||
Nach dem Anpassungen haben sich dann die Werte aus \autoref{tbl:measure-materialized-view-ext} ergeben. Diese Werte
|
Nach dem Anpassungen haben sich dann die Werte aus \autoref{tbl:measure-materialized-view-ext} ergeben. Diese Werte
|
||||||
zeigen nur minimale Unterschiede in den Zeiten, diese sind auf Messtoleranzen zurückzuführen.
|
zeigen nur minimale Unterschiede in den Zeiten, diese sind auf Messtoleranzen zurückzuführen.
|
||||||
|
|
||||||
\begin{table}[h!]
|
\begin{table}[H]
|
||||||
\centering
|
\centering
|
||||||
\resizebox{\textwidth}{!}{
|
\resizebox{\textwidth}{!}{
|
||||||
\begin{tabular}{|r|r|r|r|r|r|r|r|r|r|r|r|r|r|r|}
|
\begin{tabular}{|r|r|r|r|r|r|r|r|r|r|r|r|r|r|r|}
|
||||||
|
@ -667,7 +667,7 @@ dieser Wert zu klein oder groß definiert ist, wird die Laufzeit verschlechtert.
|
||||||
Laufzeit der Datenbankanfrage auf circa 20 ms verlängert. Wenn der Wert zu gering gewählt ist, dann wird zwar die
|
Laufzeit der Datenbankanfrage auf circa 20 ms verlängert. Wenn der Wert zu gering gewählt ist, dann wird zwar die
|
||||||
Laufzeit der Datenbankanfrage minimal verkürzt, aber die \texttt{map}"=Funktion wird dadurch verlängert.
|
Laufzeit der Datenbankanfrage minimal verkürzt, aber die \texttt{map}"=Funktion wird dadurch verlängert.
|
||||||
|
|
||||||
Das Aktivieren der Cache"=Optionen wie in \autoref{sec:performance-investigation-application:caching-openjpa} oder in %TODO schreibt in den Rand
|
Das Aktivieren der Cache"=Optionen wie in \autoref{sec:performance-investigation-application:caching-openjpa} oder in
|
||||||
\autoref{sec:performance-investigation-application:cached-query} dargestellt, haben keine Auswirkung auf die Performance.
|
\autoref{sec:performance-investigation-application:cached-query} dargestellt, haben keine Auswirkung auf die Performance.
|
||||||
Dies ist dadurch erklärbar, dass keine Objekte durch das OpenJPA"=Framework erstellt werden, sondern erst in der
|
Dies ist dadurch erklärbar, dass keine Objekte durch das OpenJPA"=Framework erstellt werden, sondern erst in der
|
||||||
\texttt{map}"=Funktion des eigenen Codes und daher wird der Cache nicht genutzt.
|
\texttt{map}"=Funktion des eigenen Codes und daher wird der Cache nicht genutzt.
|
||||||
|
@ -678,7 +678,7 @@ wurde die übernommene \texttt{SearchDocument}"=Klasse abermals genauer betracht
|
||||||
Seite nochmals aufgerufen. Durch diese Umstellung fällt die Laufzeit der Datenermittlung auf circa 4 ms ab. Nun muss
|
Seite nochmals aufgerufen. Durch diese Umstellung fällt die Laufzeit der Datenermittlung auf circa 4 ms ab. Nun muss
|
||||||
noch überprüft werden, welche Zeit nun der Client zum parsen der \textit{Json}"=Daten benötigt. Hierfür werden die
|
noch überprüft werden, welche Zeit nun der Client zum parsen der \textit{Json}"=Daten benötigt. Hierfür werden die
|
||||||
Daten in einem versteckten \texttt{span}"=Element hinterlegt, wie es im \autoref{lst:jsf-datatable-json} zu sehen ist.
|
Daten in einem versteckten \texttt{span}"=Element hinterlegt, wie es im \autoref{lst:jsf-datatable-json} zu sehen ist.
|
||||||
Die hinterlegte \textit{\acs{CSS}}"=Klasse ist zum Auffinden der Elemente für den späteren Javascript. Das
|
Die hinterlegte \textit{\ac{CSS}}"=Klasse ist zum Auffinden der Elemente für den späteren Javascript. Das
|
||||||
\textit{ajax}"=Element im Beispiel ist notwendig, damit bei einem Seitenwechsel die gleiche Interpreter"=Funktion für
|
\textit{ajax}"=Element im Beispiel ist notwendig, damit bei einem Seitenwechsel die gleiche Interpreter"=Funktion für
|
||||||
die \textit{Json}"=Daten aufgerufen wird, wie beim Laden der Webseite.
|
die \textit{Json}"=Daten aufgerufen wird, wie beim Laden der Webseite.
|
||||||
|
|
||||||
|
@ -776,7 +776,7 @@ Die erstellte Visualisierung der Abfrage ist in \autoref{fig:explain-visualize}
|
||||||
die Darstellung der Kosten gewählt, da ein Vergleich auf Basis der Zeit sehr schwierig ist und von äußeren Faktoren
|
die Darstellung der Kosten gewählt, da ein Vergleich auf Basis der Zeit sehr schwierig ist und von äußeren Faktoren
|
||||||
abhängt, wie zum Beispiel dem Cache. Die Kosten sind stabiler und hängen in erster Linie von der Art des Datenbestandes ab.
|
abhängt, wie zum Beispiel dem Cache. Die Kosten sind stabiler und hängen in erster Linie von der Art des Datenbestandes ab.
|
||||||
|
|
||||||
\begin{figure}[h!]
|
\begin{figure}[H]
|
||||||
\includegraphics[width=\linewidth]{gfx/chapter05_ExplainVisualize.png}
|
\includegraphics[width=\linewidth]{gfx/chapter05_ExplainVisualize.png}
|
||||||
\caption{Visualisierung EXPLAIN}
|
\caption{Visualisierung EXPLAIN}
|
||||||
\label{fig:explain-visualize}
|
\label{fig:explain-visualize}
|
||||||
|
@ -828,7 +828,7 @@ an den dünneren Verbindungslinien zwischen den Knoten und der Umstellung von ei
|
||||||
\textit{Index Scan} ersichtlich. Zeitgleich ist auch der teure \textit{HashAggregate} nicht mehr im Abfrageplan
|
\textit{Index Scan} ersichtlich. Zeitgleich ist auch der teure \textit{HashAggregate} nicht mehr im Abfrageplan
|
||||||
vorhanden.
|
vorhanden.
|
||||||
|
|
||||||
\begin{figure}[h!]
|
\begin{figure}[H]
|
||||||
\includegraphics[width=\linewidth]{gfx/chapter05_ExplainVisualize_with.png}
|
\includegraphics[width=\linewidth]{gfx/chapter05_ExplainVisualize_with.png}
|
||||||
\caption{Visualisierung EXPLAIN with}
|
\caption{Visualisierung EXPLAIN with}
|
||||||
\label{fig:explain-visualize-with}
|
\label{fig:explain-visualize-with}
|
||||||
|
|
|
@ -9,7 +9,7 @@ der Effektivität mit beachtet.
|
||||||
|
|
||||||
Es wurden die Konfigurationen der Caches von OpenJPA, \ac{JPA} und \ac{EJB} aktiviert und deren Auswirkung betrachtet. Bei den
|
Es wurden die Konfigurationen der Caches von OpenJPA, \ac{JPA} und \ac{EJB} aktiviert und deren Auswirkung betrachtet. Bei den
|
||||||
Caches, bei denen eine Größe angebbar ist, wurde zusätzlich mit der Anzahl variiert, um zu ermitteln, in welchem Umfang
|
Caches, bei denen eine Größe angebbar ist, wurde zusätzlich mit der Anzahl variiert, um zu ermitteln, in welchem Umfang
|
||||||
sich diese auswirkt. Des Weiteren wird die Art der Programmierung für die Abfragen betrachtet, ob signifikante
|
sich diese auswirken. Des Weiteren wird die Art der Programmierung für die Abfragen betrachtet, ob signifikante
|
||||||
Unterschiede in der Performance und der Abarbeitung erkennbar sind. Als weiteren Punkt werden die Abfragen an die
|
Unterschiede in der Performance und der Abarbeitung erkennbar sind. Als weiteren Punkt werden die Abfragen an die
|
||||||
Datenbank untersucht, um zu ermitteln, ob diese durch Umstellung verbessert werden können. Abschließend werden die
|
Datenbank untersucht, um zu ermitteln, ob diese durch Umstellung verbessert werden können. Abschließend werden die
|
||||||
\textit{Materialized View} verwendet, um zu ermitteln, ob durch einen vorverdichteten und aufbereiteten Datenbestand
|
\textit{Materialized View} verwendet, um zu ermitteln, ob durch einen vorverdichteten und aufbereiteten Datenbestand
|
||||||
|
@ -18,7 +18,7 @@ die Abfragen beschleunigt werden können.
|
||||||
\section{Nutzerumfrage}
|
\section{Nutzerumfrage}
|
||||||
\label{sec:evaluation:user-survey}
|
\label{sec:evaluation:user-survey}
|
||||||
|
|
||||||
Zusätzlich war noch eine Befragung unter den Benutzer und den Entwicklern geplant. Auf Grund dessen, dass nur fünf
|
Zusätzlich war noch eine Befragung unter den Benutzern und den Entwicklern geplant. Auf Grund dessen, dass nur fünf
|
||||||
Personen zur Verfügung stehen, ist dies nicht zielführend. Daher ist die einzig sinnvolle Alternative, welche gewählt
|
Personen zur Verfügung stehen, ist dies nicht zielführend. Daher ist die einzig sinnvolle Alternative, welche gewählt
|
||||||
wurde, ein rein technischer Ansatz.
|
wurde, ein rein technischer Ansatz.
|
||||||
|
|
||||||
|
@ -26,25 +26,24 @@ wurde, ein rein technischer Ansatz.
|
||||||
\label{sec:evaluation:new-table}
|
\label{sec:evaluation:new-table}
|
||||||
|
|
||||||
Hierfür wurde die aktuelle Datenstruktur untersucht, um zu überprüfen, ob eine Umgestaltung der Tabelle eine Verbesserung
|
Hierfür wurde die aktuelle Datenstruktur untersucht, um zu überprüfen, ob eine Umgestaltung der Tabelle eine Verbesserung
|
||||||
bringen würde. Die typische Optimierung ist die Normalisierung der Tabellenstruktur. Die Tabellenstruktur ist aktuell
|
bringt. Die typische Optimierung ist die Normalisierung der Tabellenstruktur. Die Tabellenstruktur ist aktuell
|
||||||
schon normalisiert, daher kann hier nichts weiter optimiert werden.
|
schon normalisiert, daher kann hier nichts weiter optimiert werden.
|
||||||
|
|
||||||
Eine weitere Optimierungsstrategie besteht in der Denormalisierung, um sich die Verknüpfungen der Tabellen zu sparen.
|
Eine weitere Optimierungsstrategie besteht in der Denormalisierung, um sich die Verknüpfungen der Tabellen zu sparen.
|
||||||
Dies ist in diesem Fall nicht anwendbar, da nicht nur 1:n Beziehungen vorhanden sind, sondern auch auch n:m Beziehungen.
|
Dies ist in diesem Fall nicht anwendbar, da nicht nur 1:n Beziehungen vorhanden sind, sondern auch auch n:m Beziehungen.
|
||||||
Dadurch würde sich die Anzahl der Dokumentenliste erhöhen. Eine weitere Möglichkeit wäre es, die Duplikate auf der
|
Dadurch würde sich die Anzahl der Dokumentenliste erhöhen.
|
||||||
Serverseite zusammenzuführen.
|
|
||||||
|
|
||||||
\section{Statische Webseiten}
|
\section{Statische Webseiten}
|
||||||
\label{sec:evaluation:static-website}
|
\label{sec:evaluation:static-website}
|
||||||
|
|
||||||
Eine Umstellung der Dokumentenliste in statische Webseite würde die Zugriffszeiten sehr verkürzen. Darüber hinaus
|
Eine Umstellung der Dokumentenliste in eine statische Webseite würde die Zugriffszeiten sehr verkürzen. Darüber hinaus
|
||||||
funktionieren in statischen Webseiten aber keine Suchen oder Sortierungen. Die Sortierung könnte durch das Erstellen
|
funktionieren in statischen Webseiten aber keine Suchen oder Sortierungen. Die Sortierung könnte durch das Erstellen
|
||||||
von statischen Seiten aller Möglichkeiten der Sortierung emuliert werden, diese würde den notwendigen Speicherbedarf der
|
von statischen Seiten aller Möglichkeiten der Sortierung emuliert werden, diese würde den notwendigen Speicherbedarf der
|
||||||
Webseite vervielfachen. Für die Suchanfragen ist dies nicht mehr möglich, da nicht alle Suchanfragen vorher definiert
|
Webseite vervielfachen. Für die Suchanfragen ist dies nicht mehr möglich, da nicht alle Suchanfragen vorher definiert
|
||||||
werden können.
|
werden können.
|
||||||
|
|
||||||
Die Umstellung der Suche auf Client"=Basis wäre noch eine Möglichkeit, dafür benötigen die Clients entsprechend
|
Die Umstellung der Suche auf Client"=Basis wäre noch eine Möglichkeit, dafür benötigen die Clients entsprechende
|
||||||
Leistung und es muss eine Referenzdatei erstellt werden, die alle Informationen über die Dokumente beinhaltet, nach
|
Leistung und es muss eine Referenzdatei erstellt werden, welche alle Informationen über die Dokumente beinhaltet, nach
|
||||||
welcher gesucht werden kann.
|
welcher gesucht werden kann.
|
||||||
|
|
||||||
Daher ist eine Umstellung auf statische Webseiten nicht sinnvoll.
|
Daher ist eine Umstellung auf statische Webseiten nicht sinnvoll.
|
||||||
|
@ -82,7 +81,7 @@ hoch aus. Sobald bei den Anfragen aber häufig die zu ermittelnden Objekte sich
|
||||||
aus dem Cache entfernt werden, fällt die Performance"=Verbesserung immer geringer aus.
|
aus dem Cache entfernt werden, fällt die Performance"=Verbesserung immer geringer aus.
|
||||||
|
|
||||||
Das Entfernen der Objekte kann zwar umgangen werden, indem die häufig abgefragten Objekte gepinnt werden, was aber
|
Das Entfernen der Objekte kann zwar umgangen werden, indem die häufig abgefragten Objekte gepinnt werden, was aber
|
||||||
den Speicherbedarf noch weiter erhöht, da diese Objekte nicht in die Zählung der Cache"=Objekte beachtet werden.
|
den Speicherbedarf noch weiter erhöht, da diese Objekte nicht in die Zählung der Cache"=Objekte betrachtet werden.
|
||||||
Als größten Nachteil des Caches ist zu nennen, dass die notwendige Speichermenge ständig zur Verfügung gestellt
|
Als größten Nachteil des Caches ist zu nennen, dass die notwendige Speichermenge ständig zur Verfügung gestellt
|
||||||
werden muss. Damit ist immer ein gewisser Grundbedarf notwendig, da sich der Speicher bis zum eingestellten
|
werden muss. Damit ist immer ein gewisser Grundbedarf notwendig, da sich der Speicher bis zum eingestellten
|
||||||
Grenzwert aufbaut und dann nicht mehr entleert wird. Gerade bei kleiner dimensionierten Servern stellt dies ein
|
Grenzwert aufbaut und dann nicht mehr entleert wird. Gerade bei kleiner dimensionierten Servern stellt dies ein
|
||||||
|
@ -91,7 +90,7 @@ zur Verfügung steht.
|
||||||
|
|
||||||
Hierbei ist aber noch zu beachten, dass die Optimierung durch den Cache nicht die Laufzeit der Abfragen in der Datenbank
|
Hierbei ist aber noch zu beachten, dass die Optimierung durch den Cache nicht die Laufzeit der Abfragen in der Datenbank
|
||||||
enorm verringert hat, sondern die Laufzeit beim Erstellen der Objekte im \textit{OpenJPA}"=Framework. Dies sieht man
|
enorm verringert hat, sondern die Laufzeit beim Erstellen der Objekte im \textit{OpenJPA}"=Framework. Dies sieht man
|
||||||
sehr gut schon bei der ersten Messung, wie in \autoref{tbl:measure-ojpa-active}. Hierbei werden die Laufzeit in der
|
sehr gut schon bei der ersten Messung, wie in \autoref{tbl:measure-ojpa-active}. Hierbei wird die Laufzeit in der
|
||||||
Datenbank im Schnitt um circa 5 ms reduziert, allerdings wird die komplette Webseite fast 100 ms schneller an den Client
|
Datenbank im Schnitt um circa 5 ms reduziert, allerdings wird die komplette Webseite fast 100 ms schneller an den Client
|
||||||
ausgeliefert. Dies ist nur dadurch erklärbar, dass das Erstellen und mit den Datenwerte zu befüllen mehr Zeit kostet,
|
ausgeliefert. Dies ist nur dadurch erklärbar, dass das Erstellen und mit den Datenwerte zu befüllen mehr Zeit kostet,
|
||||||
als das Objekt aus dem Cache zu ermitteln und zurückzugeben.
|
als das Objekt aus dem Cache zu ermitteln und zurückzugeben.
|
||||||
|
@ -103,7 +102,7 @@ explizit im Cache aufgenommen und angepinnt werden.
|
||||||
\section{Cached Queries}
|
\section{Cached Queries}
|
||||||
\label{sec:evaluation:cached-queries}
|
\label{sec:evaluation:cached-queries}
|
||||||
|
|
||||||
Die Optimierung über die gespeicherten Anfragen brachte keine Verbesserung hervor. Dies ist dadurch erklärbar, dass
|
Die Optimierung über die gespeicherten Anfragen brachte keine Verbesserung hervor. Dies ist dadurch erklärbar, dass %TODO Der Satz ist schwer zu lesen, hat sie gesagt
|
||||||
für die diese Art nur Anfragen verwendet werden, die keinerlei Bedingungen besitzen. In diesem Fall sind in der Tabelle
|
für die diese Art nur Anfragen verwendet werden, die keinerlei Bedingungen besitzen. In diesem Fall sind in der Tabelle
|
||||||
noch nicht freigegebene und ungültige Datensätze gespeichert, daher müssen diese vor dem Übertragen herausgefiltert
|
noch nicht freigegebene und ungültige Datensätze gespeichert, daher müssen diese vor dem Übertragen herausgefiltert
|
||||||
werden. Aus diesem Grund werden die Anfragen in diesem Cache nicht gespeichert.
|
werden. Aus diesem Grund werden die Anfragen in diesem Cache nicht gespeichert.
|
||||||
|
@ -113,7 +112,7 @@ Dadurch ist dieser Cache für eine Performance"=Verbesserung in dem Fall der Dok
|
||||||
\section{Caching mit Ehcache}
|
\section{Caching mit Ehcache}
|
||||||
\label{sec:evaluation:ehcache}
|
\label{sec:evaluation:ehcache}
|
||||||
|
|
||||||
Mit dem Ehcache konnte eine Verbesserung in der Performance erzielt werden. Im Vergleich zum Cache von OpenJPA sind
|
Mit dem Ehcache konnte eine Verbesserung in der Performance erzielt werden. Im Vergleich zum Cache von OpenJPA ist
|
||||||
die Verbesserung sehr ähnlich. Die Standardwerte dieses Caches sind gut vordefiniert, es wird für den aktuellen Fall
|
die Verbesserung sehr ähnlich. Die Standardwerte dieses Caches sind gut vordefiniert, es wird für den aktuellen Fall
|
||||||
keine Anpassung benötigt, um eine gute Performance zu bekommen. Hierbei ist natürlich das gleiche Problem wie in anderen
|
keine Anpassung benötigt, um eine gute Performance zu bekommen. Hierbei ist natürlich das gleiche Problem wie in anderen
|
||||||
Caches, dass beim Erreichen der Grenzen alte Objekte entfernt werden müssen.
|
Caches, dass beim Erreichen der Grenzen alte Objekte entfernt werden müssen.
|
||||||
|
@ -145,7 +144,7 @@ Auf Grund dessen ist der \ac{EJB}"=Cache nicht für eine Performance"=Verbesseru
|
||||||
|
|
||||||
Bei dem Vergleich zwischen den zwei Abfragemöglichkeiten der \ac{JPQL} und der Criteria API konnte in der Art der
|
Bei dem Vergleich zwischen den zwei Abfragemöglichkeiten der \ac{JPQL} und der Criteria API konnte in der Art der
|
||||||
Abfragen kein Unterschied festgestellt werden. Die Abfragen der beiden Systeme sind auf Datenbankseite komplett
|
Abfragen kein Unterschied festgestellt werden. Die Abfragen der beiden Systeme sind auf Datenbankseite komplett
|
||||||
identisch. Auch in der Übertragung der Daten aus der Datenbank in die Java"=Objekte konnte keine Unterschied in der
|
identisch. Auch in der Übertragung der Daten aus der Datenbank in die Java"=Objekte konnte kein Unterschied in der
|
||||||
Art und Geschwindigkeit festgestellt werden.
|
Art und Geschwindigkeit festgestellt werden.
|
||||||
|
|
||||||
Ebenfalls sind die Möglichkeiten über der Optimierung über Hints identisch. In beiden Fällen haben die meisten Hints
|
Ebenfalls sind die Möglichkeiten über der Optimierung über Hints identisch. In beiden Fällen haben die meisten Hints
|
||||||
|
@ -165,7 +164,8 @@ jeweiligen Einsatzzweck besser beziehungsweise einfacher zu programmieren ist. D
|
||||||
ist in beiden Fällen äußerst wichtig. Explizit bei der EagerFetchMode muss vorher darüber nachgedacht werden, wie viele
|
ist in beiden Fällen äußerst wichtig. Explizit bei der EagerFetchMode muss vorher darüber nachgedacht werden, wie viele
|
||||||
abhängige Objekttypen es zu dieser Klasse gibt, welche dazu geladen werden sollen und von welcher Anzahl an Objekte
|
abhängige Objekttypen es zu dieser Klasse gibt, welche dazu geladen werden sollen und von welcher Anzahl an Objekte
|
||||||
ausgegangen werden kann. Gerade bei einer größeren Anzahl lohnt es sich den Hint auf \textit{parallel} zu setzen.
|
ausgegangen werden kann. Gerade bei einer größeren Anzahl lohnt es sich den Hint auf \textit{parallel} zu setzen.
|
||||||
Gleiches gilt dem Hint SubclassFetchMode, dieser steuert dimensionierte Abfragen im Falle von abgeleiteten Klassen.
|
Gleiches gilt bei dem Hint \texttt{SubclassFetchMode}, dieser steuert dimensionierte Abfragen im Falle von
|
||||||
|
abgeleiteten Klassen.
|
||||||
|
|
||||||
\section{Materialized View}
|
\section{Materialized View}
|
||||||
\label{sec:evaluation:materialized-view}
|
\label{sec:evaluation:materialized-view}
|
||||||
|
@ -233,7 +233,7 @@ ermittelt, dieser mit der Haupttabelle verknüpft und nun die anderen Tabellen d
|
||||||
Zeilenanzahl während der Verarbeitung enorm verringert werden, wodurch einige der Verknüpfungen auf Indexzugriffe
|
Zeilenanzahl während der Verarbeitung enorm verringert werden, wodurch einige der Verknüpfungen auf Indexzugriffe
|
||||||
umgestellt wurden. Durch die Umstellung konnte die Abfragezeit um mehr als das dreifache reduziert werden.
|
umgestellt wurden. Durch die Umstellung konnte die Abfragezeit um mehr als das dreifache reduziert werden.
|
||||||
|
|
||||||
Mit dieser Art der Umstellung können Abfragen optimiert werden, die fürs Paging verwendet werden und die Abfrage aus
|
Mit dieser Art der Umstellung können Abfragen optimiert werden, die für das Paging verwendet werden und die Abfrage aus
|
||||||
mehrere Tabellen besteht. Das Wichtigste hierbei ist, dass die Bedingungen und die Sortierkriterien auf der
|
mehrere Tabellen besteht. Das Wichtigste hierbei ist, dass die Bedingungen und die Sortierkriterien auf der
|
||||||
Haupttabelle arbeiten. Wenn dem nicht so ist, müssen Joins in die \textit{Common Table Expression} mit aufgenommen
|
Haupttabelle arbeiten. Wenn dem nicht so ist, müssen Joins in die \textit{Common Table Expression} mit aufgenommen
|
||||||
werden und damit funktioniert die Reduzierung der Datensätze nicht mehr. Bei der Selektion einer Tabelle hat diese Art
|
werden und damit funktioniert die Reduzierung der Datensätze nicht mehr. Bei der Selektion einer Tabelle hat diese Art
|
||||||
|
|
|
@ -17,9 +17,9 @@ Durch die Ausgangsmessungen war erkennbar, dass der größte Teil der Verarbeitu
|
||||||
liegt. Die Messung der Abfragen auf der Datenbank wiederum konnte die hohe Verarbeitungszeit nicht bestätigen,
|
liegt. Die Messung der Abfragen auf der Datenbank wiederum konnte die hohe Verarbeitungszeit nicht bestätigen,
|
||||||
daher lag hier die Vermutung nahe, dass der Großteil der Zeit im \ac{ORM} verloren geht.
|
daher lag hier die Vermutung nahe, dass der Großteil der Zeit im \ac{ORM} verloren geht.
|
||||||
|
|
||||||
Die Methode der Nutzerumfrage wurde nicht weiterverfolgt, da diese auf Grund zu wenigen Bedienern nicht zielführend war.
|
Die Methode der Nutzerumfrage wurde nicht weiterverfolgt, da diese auf Grund von zu wenigen Bedienern nicht zielführend war.
|
||||||
Bei der Untersuchung der Datenbank wurde festgestellt, dass die Struktur aktuell für die Anwendung optimal ist und
|
Bei der Untersuchung der Datenbank wurde festgestellt, dass die Struktur aktuell für die Anwendung optimal ist und
|
||||||
daher eine Restrukturierung keine Vorteile entstehen lässt. Die statische Webseite und die komplett Client basierte
|
daher eine Restrukturierung keine Vorteile entstehen lässt. Die statische Webseite und die komplett client basierte
|
||||||
Webseite wurden auf Grund von technischen Einschränkungen nicht weiterverfolgt.
|
Webseite wurden auf Grund von technischen Einschränkungen nicht weiterverfolgt.
|
||||||
|
|
||||||
Bei den Caches sind der Query"=Cache und der \ac{EJB}"=Cache nicht für die Optimierung verwendbar. Der Query"=Cache wird
|
Bei den Caches sind der Query"=Cache und der \ac{EJB}"=Cache nicht für die Optimierung verwendbar. Der Query"=Cache wird
|
||||||
|
@ -47,7 +47,7 @@ durch die Umstellung der Ermittlung der unterlagerten Daten durch Hints eine Opt
|
||||||
bezweckt, dass die unterlagerten Daten nicht einzeln für jede Zeile ermittelt werden, sondern alle Daten auf einmal
|
bezweckt, dass die unterlagerten Daten nicht einzeln für jede Zeile ermittelt werden, sondern alle Daten auf einmal
|
||||||
geladen werden und die Zuordnung der Datensätze im OpenJPA"=Framework durchgeführt wird.
|
geladen werden und die Zuordnung der Datensätze im OpenJPA"=Framework durchgeführt wird.
|
||||||
|
|
||||||
Mit der Übernahme der \textit{Materialized View} aus dem Wedekind"=Projekt konnte erstmalig ein gute Optimierung
|
Mit der Übernahme der \textit{Materialized View} aus dem Wedekind"=Projekt konnte erstmalig eine gute Optimierung
|
||||||
beobachtet werden. Dies ist auf die einfachere Abfrage, die Reduzierung der Abfrage an den Datenbankserver und dass
|
beobachtet werden. Dies ist auf die einfachere Abfrage, die Reduzierung der Abfrage an den Datenbankserver und dass
|
||||||
die Objekte im eigenen Code erstellt werden zurückzuführen und nicht auf das OpenJPA"=Framework. Hierbei konnte noch nachgewiesen
|
die Objekte im eigenen Code erstellt werden zurückzuführen und nicht auf das OpenJPA"=Framework. Hierbei konnte noch nachgewiesen
|
||||||
werden, dass das Parsen der Json"=Daten, die die unterlagerten Objekte enthalten, den größten Teil der Zeit benötigen.
|
werden, dass das Parsen der Json"=Daten, die die unterlagerten Objekte enthalten, den größten Teil der Zeit benötigen.
|
||||||
|
@ -60,7 +60,7 @@ für die weiteren Verlinkungen enorm reduziert wurde. Somit konnte der Datenbank
|
||||||
zugreifen und damit die Abfragen zusätzlich beschleunigen.
|
zugreifen und damit die Abfragen zusätzlich beschleunigen.
|
||||||
|
|
||||||
Die Untersuchungen zeigen, dass mehrere Möglichkeiten zur Optimierung existierten, um die Zugriffe auf die
|
Die Untersuchungen zeigen, dass mehrere Möglichkeiten zur Optimierung existierten, um die Zugriffe auf die
|
||||||
Briefeditionen zu beschleunigen und das das größte Optimierungspotential in dem \ac{ORM} liegt. Welche der
|
Briefeditionen zu beschleunigen und dass das größte Optimierungspotential in dem \ac{ORM} liegt. Welche der %dass oder das
|
||||||
Optimierungen verwendet werden, liegt an der Komplexität der Abfrage und der bereitgestellten Ressourcen
|
Optimierungen verwendet werden, liegt an der Komplexität der Abfrage und der bereitgestellten Ressourcen
|
||||||
des Servers.
|
des Servers.
|
||||||
|
|
||||||
|
|
|
@ -66,3 +66,5 @@
|
||||||
\usepackage{soul}
|
\usepackage{soul}
|
||||||
% ToDos erstellen mit \todo{...}
|
% ToDos erstellen mit \todo{...}
|
||||||
\usepackage{todonotes}
|
\usepackage{todonotes}
|
||||||
|
% für bessere Positionierung von Graphiken mit dem Kürzel H
|
||||||
|
\usepackage{float}
|
||||||
|
|
BIN
thesis.pdf
BIN
thesis.pdf
Binary file not shown.
12
thesis.tex
12
thesis.tex
|
@ -17,6 +17,14 @@
|
||||||
%\renewcommand{\myTime}{22. Juli 2024\xspace}
|
%\renewcommand{\myTime}{22. Juli 2024\xspace}
|
||||||
\renewcommand{\myVersion}{version 1.0\xspace}
|
\renewcommand{\myVersion}{version 1.0\xspace}
|
||||||
|
|
||||||
|
\makeatletter
|
||||||
|
\addto\extrasngerman{
|
||||||
|
% Definition, um Umbrüche innerhalb von Text und Nr zu erlauben, damit kein
|
||||||
|
% überschreiben des Randes auftritt
|
||||||
|
\def\sectionautorefname{Abschnitt\hskip\z@skip}
|
||||||
|
}
|
||||||
|
\makeatother
|
||||||
|
|
||||||
% https://en.wikibooks.org/wiki/LaTeX/Source_Code_Listings
|
% https://en.wikibooks.org/wiki/LaTeX/Source_Code_Listings
|
||||||
%\lstinputlisting[frame=tb,language=SQL,caption={ein sql beispiel},label=lst:tester]{chapters/thesis/chapter05_example.sql}
|
%\lstinputlisting[frame=tb,language=SQL,caption={ein sql beispiel},label=lst:tester]{chapters/thesis/chapter05_example.sql}
|
||||||
\newcommand{\includecode}[4][c]{\lstinputlisting[caption=#4,label=#3,language=#1]{#2}}
|
\newcommand{\includecode}[4][c]{\lstinputlisting[caption=#4,label=#3,language=#1]{#2}}
|
||||||
|
@ -164,9 +172,9 @@
|
||||||
% 2. Bei Before Lunch "Build artifact" hinzufügen und "WedekindJSF.war" auswählen
|
% 2. Bei Before Lunch "Build artifact" hinzufügen und "WedekindJSF.war" auswählen
|
||||||
% 3. Unter Deployment "Artifact" "WedekindJSF.war" hinzufügen
|
% 3. Unter Deployment "Artifact" "WedekindJSF.war" hinzufügen
|
||||||
% 4. Sollte es Probleme mit dem Deployment geben, ala "kann ...Servlet-class nof found" einfach alle target-Verzeichnis löschen
|
% 4. Sollte es Probleme mit dem Deployment geben, ala "kann ...Servlet-class nof found" einfach alle target-Verzeichnis löschen
|
||||||
% und erneut deployen oder vielleicht ein Rebuild auf dem Projekt probieren
|
% und erneut Deployen oder vielleicht ein Rebuild auf dem Projekt probieren
|
||||||
|
|
||||||
% Konfiguration Glassfish/Payara (Muss scheinbar nach jedem neustart des Rechners gemacht werden)
|
% Konfiguration GlassFish/Payara (Muss scheinbar nach jedem neustart des Rechners gemacht werden)
|
||||||
% 1. Payara-Server starten, damit man an die Admin-Oberfläche kommt unter http://localhost:4848/
|
% 1. Payara-Server starten, damit man an die Admin-Oberfläche kommt unter http://localhost:4848/
|
||||||
% > /opt/payara/bin/asadmin start-domain domain1
|
% > /opt/payara/bin/asadmin start-domain domain1
|
||||||
% 2. Unter Ressources\JDBC\JDBC Connection Pools einen neuen Anlegen:
|
% 2. Unter Ressources\JDBC\JDBC Connection Pools einen neuen Anlegen:
|
||||||
|
|
Loading…
Reference in a new issue