3.2. Projekt

In diesem Projekt sollen die drei Webserver Apache, Caddy und NginX verglichen werden. Hierfür wurde ein docker-compose File erstellt, das eine Instanz von jedem der drei Webserver aufsetzt. Damit die drei Webserver gut vergleichbar sind, greifen sie alle auf den build Folder dieses Projektes zu und zeigen die index.html an.

3.2.1. Konfiguration

Für die drei Docker Container benötigen wir neben der docker-compose.yml noch ein Konfigurationsfile für Caddy. Mit diesem File definieren wir, welche Files von Caddy angezeigt werden sollen und wie er die Files bereitstellen soll.

http://localhost {
    root * /srv
    file_server
}

Mit dem Compose file legen wir fest unter welchem Port die Webserver jeweils erreichbar sind und mounten unser build Verzeichnis in den jeweiligen Container:

services:
  apache: #Config: /usr/local/apache2/conf/httpd.conf
    image: httpd:latest
    container_name: apache-dva 
    ports:
      - "8080:80"
    volumes:
      - ../../../build/html/:/usr/local/apache2/htdocs/
  caddy: #Config: /etc/caddy/Caddyfile <--- copy of code/Caddyfile
    image: caddy:latest
    container_name: caddy-dva
    ports:
      - "8081:80"
    volumes:
      - ../../../build/html/:/srv
      - ./Caddyfile:/etc/caddy/Caddyfile
  nginx: #Config: /etc/nginx/nginx.conf
    image: nginx:latest
    container_name: nginx-dva
    ports:
      - "8082:80"
    volumes:
      - ../../../build/html:/usr/share/nginx/html

3.2.2. Vergleich

3.2.2.1. Effizienz

Die Effizienz von Apache, Nginx und Caddy Webservern wurde anhand von Ressourcennutzung im Leerlauf und unter Last analysiert. Im Leerlauf zeigt Caddy den geringsten Speicherverbrauch mit nur 11.18 MiB, während Apache und Nginx etwas mehr Speicher benötigen. Die CPU-Auslastung für alle Server bleibt im Leerlauf minimal.

Webserver Ressourcennutzung im Leerlauf

NAME

CPU %

MEM USAGE / LIMIT

NET I/O

Apache

0.00%

24.45MiB / 31.22GiB

2.28kB / 586B

Caddy

0.00%

11.18MiB / 31.22GiB

2.11kB / 586B

Nginx

0.00%

21.7MiB / 31.22GiB

2.11kB / 586B

Unter Last steigt die CPU-Auslastung von Caddy am stärksten auf 9.45% an, mit der höchsten Netzwerkauslastung, während Nginx die geringste CPU-Belastung aufweist und seine PIDs konstant bleiben, was auf eine stabile Leistung hinweist. Apache und Caddy erhöhen die Anzahl ihrer Prozesse (PIDs), wobei Apache insgesamt 109 PIDs erreicht.

Webserver Ressourcennutzung unter Last

NAME

CPU %

MEM USAGE / LIMIT

NET I/O

Apache

6.82%

34.1MiB / 31.22GiB

1.76MB / 27.8MB

Caddy

9.45%

17.82MiB / 31.22GiB

2.88MB / 40.8MB

Nginx

3.49%

23.5MiB / 31.22GiB

2.6MB / 36.9MB

Zusammenfassend ist Caddy im Leerlauf am effizientesten in Bezug auf den Speicherverbrauch, zeigt jedoch unter Last die höchste CPU- und Netzwerkauslastung. Apache skaliert unter Belastung deutlich hinsichtlich CPU-Auslastung und PIDs, während Nginx eine ausgewogene Leistung sowohl im Leerlauf als auch unter Last bietet.

3.2.2.2. Skalierbarkeit

Apache, Caddy und NginX sind weit verbreitete Webserver, die jeweils unterschiedliche Skalierungsstrategien unterstützen.

Vergleich der Skalierbarkeit

Webserver

Skalierbarkeitsmerkmale

Skalierungsmethoden

Apache

Skaliert gut durch Multi-Prozess oder Multi-Thread Modelle. Weniger effizient unter sehr hoher Last als NginX.

Vertikal durch Hinzufügen von Ressourcen; Horizontal durch Load Balancer und Clustering.

Caddy

Effizient durch modernes, einfaches Design. Automatische Anpassungen bei Konfigurationen.

Vertikal und horizontal durch automatische Konfigurationsanpassungen und Integration mit Containertechnologien.

NginX

Ausgezeichnet für statische Inhalte und hohe Lasten durch asynchrones, ereignisgesteuertes Modell.

Vertikal; Horizontal besonders effektiv durch Load Balancing und Einsatz in Mikroservice-Architekturen.

Die Skalierung von Webservern kann auf zwei Hauptarten erfolgen: vertikale und horizontale Skalierung. Jeder der Webserver Apache, Caddy und NginX hat seine eigenen Stärken und Ansätze in diesen Skalierungsmethoden.

Vertikale Skalierung bezieht sich auf das Hinzufügen von mehr Hardware-Ressourcen wie CPU und RAM, um die Leistungsfähigkeit eines Servers zu erhöhen.

Webserver

Beschreibung

Apache

Mehr Hardware-Ressourcen (CPU, RAM) hinzufügen, um die Kapazität zu erhöhen.

Caddy

Ähnlich wie Apache, obwohl weniger Ressourcen-intensiv aufgrund seiner Effizienz.

NginX

Profitiert ebenfalls von zusätzlichen Ressourcen, seine Effizienz macht ihn jedoch weniger abhängig von dieser Art der Skalierung.

Horizontale Skalierung bezieht sich auf die Erweiterung der Kapazitäten durch Hinzufügen weiterer Server-Instanzen, die zusammenarbeiten, um die Last zu verteilen.

Webserver

Beschreibung

Apache

Mehrere Apache-Server hinter einem Load Balancer einsetzen, um die Last zu verteilen.

Caddy

Kann leicht in einer containerisierten Umgebung wie Docker skaliert werden, was das Deployment neuer Instanzen vereinfacht.

NginX

Ideal für den Einsatz in einer Microservices-Architektur und kann als Frontend-Proxy fungieren, um Anfragen an mehrere Back-End-Server zu verteilen.

3.2.2.3. Konfigurationsaufwand

Insgesamt gestaltet sich die Konfiguration dank Docker für alle Webserver relativ simpel. Es müssen lediglich die HTML-Files gemountet werden. Bei Caddy musste das Mounten zusätzlich im Caddyfile vorgenommen werden.

Zum Vergleich der Konfigurationsdateien wurde das Skript run.sh erstellt:

#!/bin/bash

docker compose up -d

docker exec -it apache-dva sh -c "cat /usr/local/apache2/conf/httpd.conf"
echo ""
read -p "====Apache configuration. Press a key.===="

docker exec -it caddy-dva sh -c "cat /etc/caddy/Caddyfile"
echo ""
read -p "====Caddy configuration. Press a key.===="

docker exec -it nginx-dva sh -c "cat /etc/nginx/nginx.conf"
echo ""
read -p "====NGINX configuration. Press a key.===="

Führt man dieses aus, erkennt man auf den ersten Blick hinsichtlich des Umfangs der Konfigurationen sofort große Unterschiede.

Geht man nun weiter in die Tiefe, lassen sich folgende Vor- und Nachteile erkennen, sobald man über die vorhandene einfache Standardkonfiguration hinausgehen möchte:

  • Apache:

    • Vorteile: Apache ist seit langem einer der am weitesten verbreiteten Webserver und bietet eine breite Palette von Funktionen und Modulen. Die Konfiguration erfolgt normalerweise über die Datei httpd.conf und zugehörige Konfigurationsdateien, was eine exakte Kontrolle über den Server ermöglicht.

    • Nachteile: Apache-Konfigurationen können manchmal umständlich sein, insbesondere für komplexe Anforderungen. Die Syntax kann für Anfänger verwirrend sein, und das Debuggen von Konfigurationsfehlern kann herausfordernd sein.

  • Caddy:

    • Vorteile: Caddy zeichnet sich durch seine Benutzerfreundlichkeit aus. Es bietet eine automatische HTTPS-Konfiguration und vereinfacht viele Aspekte der Webserververwaltung. Die Konfiguration erfolgt oft über ein einfach zu lesendes Caddyfile, das intuitiver sein kann als die Konfiguration von NGINX oder Apache.

    • Nachteile: Obwohl Caddy eine einfache Handhabung bietet, kann es für fortgeschrittenere Anforderungen möglicherweise nicht genügend Flexibilität bieten. In einigen Fällen kann die Benutzerfreundlichkeit zu einem Verlust an Feinsteuerung führen.

  • Nginx

    • Vorteile: Bietet umfangreiche Konfigurationsmöglichkeiten für Lastverteilung, Proxying und SSL/TLS-Terminierung und ist bekannt für seine Leistung und Skalierbarkeit.

    • Nachteile: Die Konfiguration von nginx erfordert manchmal ein tieferes Verständnis der Konfigurationssyntax. Es kann komplex sein, insbesondere für Anfänger, obwohl viele grundlegende Konfigurationen relativ einfach sind.

3.2.2.4. Emulation x86 Linux auf ARM

Apple stellt zur Emulation die Translation Engine Rosetta bereit um x86 Applikationen auf ARM zu emulieren.

Zum Betreiben einer virtuellen Maschine nutzten wir UTM. Dabei gab es zunächst erhebliche Performance Probleme.

Nach einer kurzen Recherche entdeckten wir, dass folgende Einstellungen wichtig sind um eine annehmbare Performance zu erzielen:

../_images/UTM_Linux_01.png ../_images/UTM_Linux_02.png

Auch mussten wir die Emulation von UTM anstelle von der nativen Emulation Rosetta verwenden verwenden, da sonst der Bootloader von Ubuntu nicht funktioniert, siehe Warnung hier: https://docs.getutm.app/guides/debian/#installing-rosetta

3.2.2.5. Performance

Um die Leistung der drei verschiedenen Webserver - Apache, Caddy und NGINX - miteinander zu vergleichen, verwenden wir ein Skript, das CURL-Anfragen an jeden einzelnen sendet. Ziel ist es, die Gesamtdauer für die Ausführung einer festgelegten Anzahl von Anfragen an jeden Webserver zu messen.

Das Skript führt eine festgelegte Anzahl von Anfragen an jeden Webserver aus und misst die Gesamtdauer.

#!/bin/bash

# Set the variables
APACHE_URL="http://localhost:8080/"
CADDY_URL="http://localhost:8081/"
NGINX_URL="http://localhost:8082/"
REQUESTS=1000
TIME_COMMAND="gdate"

if ! command -v $TIME_COMMAND &> /dev/null; then
	TIME_COMMAND="date"
fi

function test(){
    # Perform the test using gdate for nanosecond precision
    START=$($TIME_COMMAND +%s%N) # Get current time in nanoseconds
    for ((i=1; i<=$REQUESTS; i++)); do
        curl -s -o /dev/null -w "%{http_code} %{time_total}\n" $1 &> /dev/null
    done
    END=$($TIME_COMMAND +%s%N) # Get current time in nanoseconds
    DURATION=$((END - START))
    echo "Performed ${REQUESTS} requests in ${DURATION} Ns"
}

echo "Starting Apache Test"
test $APACHE_URL
echo "Starting Caddy Test"
test $CADDY_URL
echo "Starting NGINX Test"
test $NGINX_URL

Performance x86_64:

Performance x86

Für eine x86-Architektur dauert es etwa 5,6 Sekunden für den Apache-Webserver, ungefähr 6,4 Sekunden für den Caddy-Webserver und etwa 6,1 Sekunden für den NGINX-Webserver, um 1000 CURL-Requests zu verarbeiten.

Performance ARM (Apple M1 Pro):

Performance ARM

Auf einer ARM-Architektur benötigen der Apache-Webserver etwa 7,9 Sekunden, der Caddy-Webserver ungefähr 7,4 Sekunden und der NGINX-Webserver etwa 7,8 Sekunden, um die Bearbeitung von 1000 CURL-Requests abzuschließen.

Ein Ubuntu, emuliert auf einem ARM Chip (Apple M1 Pro):

Performance ARM emuliert

Im Vergleich zu dem Test ohne virtuelle Maschine ist die Performance auf einem ARM Chip (Apple M1 Pro) deutlich schlechter. Der Apache-Webserver benötigt etwa 52 Sekunden, der Caddy-Webserver ungefähr 44 Sekunden und der NGINX-Webserver etwa 43 Sekunden, um die Bearbeitung von 1000 CURL-Requests abzuschließen.