Einführung
Als ich unsere Finanzanwendung auf Tomcat entwickelte, lernte ich schnell, dass es keine gute Idee war, Tomcat direkt im öffentlichen Internet zu betreiben. Es funktionierte anfangs, war aber fragil, schwer abzusichern und fast unmöglich, während der Bereitstellungen reibungslos zu warten.
Schließlich entschied ich mich, Nginx vor Tomcat zu setzen und Nginx alles erledigen zu lassen, was Tomcat nicht gut kann, insbesondere SSL-Terminierung, Wartungsmodus, Caching von statischen Dateien und das Verbergen interner Infrastrukturdetails.
Dieser Artikel erklärt die genaue Konfiguration, die ich heute in der Produktion verwende. Es ist kein allgemeiner Leitfaden. Er ist speziell für das Finanzsystem geschrieben, das ich bereitgestellt habe, und enthält echte Konfigurationen sowie die Gründe für jede Entscheidung.
Warum ich Nginx vor Tomcat benötigte
1. Eine saubere Wartungsseite, wenn Tomcat neu gestartet wird
In einem Finanzsystem müssen wir Tomcat häufig während der Bereitstellungen oder Wartungsarbeiten neu starten. Wenn Tomcat nicht verfügbar ist, sollte der Benutzer niemals eine rohe Tomcat 503-Seite sehen, die Serverinformationen preisgibt.
Mit Nginx sehen die Benutzer immer eine freundliche Wartungsseite, selbst wenn Tomcat komplett offline ist. Nginx fängt die 502- oder 503-Antwort ab und liefert eine statische HTML-Seite, die ich vorbereitet habe.
2. SSL ist auf Nginx viel einfacher
Die Konfiguration von SSL innerhalb von Tomcat ist unnötig kompliziert. Sie müssen Zertifikate in einen Java-Keystore umwandeln, den Connector verwalten und mit mehreren Formaten umgehen.
Mit Nginx ist SSL einfach. Ich benötige nur zwei Dateien, ein Zertifikat und einen privaten Schlüssel. Nginx beendet HTTPS, und Tomcat erhält nur unverschlüsseltes HTTP von localhost. Auch die Erneuerung von Zertifikaten und das Debuggen sind einfacher.
3. Tomcat ist von der Außenwelt vollständig verborgen
Aus Sicherheitsgründen möchte ich nicht, dass Tomcat seine Ports oder Serverinformationen an öffentliche Benutzer preisgibt. Tomcat hört nur auf 127.0.0.1:8080.
Wenn jemand versucht, meinen Server zu scannen, kann er nicht einmal erkennen, dass Tomcat existiert.
4. Große Header für Finanzgenehmigungen
Einige Genehmigungsoperationen im System senden eine lange Liste von Finanzanwendungs-IDs im Header oder in der Abfragezeichenfolge.
Um diese großen Header zu unterstützen, habe ich Nginx so konfiguriert, dass es größere Header-Puffer zulässt. Ohne dies würden einige Anfragen fehlschlagen, da die Standardgröße der Header zu klein ist.
5. Große Datei-Uploads
Benutzer laden Verträge, Rechnungen und gescannte Dokumente hoch. Ich habe ein sauberes Upload-Größenlimit in Nginx festgelegt, sodass große Dateien Tomcat nicht erreichen, es sei denn, sie bestehen zuerst die Nginx-Validierung.
6. Schnellere statische Inhalte (CSS, JS, Icons)
Obwohl Tomcat statische Dateien bedienen kann, ist Nginx viel schneller. Ich habe das Caching für statische Assets aktiviert, sodass Nginx sie direkt bedient, ohne Tomcat zu belästigen.
7. Benutzerdefinierte Timeouts für lang laufende Operationen
Einige Prozesse in einem Finanzsystem dauern länger, wie z.B. die Erstellung von Berichten oder die Batchgenehmigung.
Nginx gibt mir die volle Kontrolle über Proxy-Timeouts, sodass Benutzer keine unerwarteten 504-Fehler erhalten.
Die Nginx HTTPS-Konfiguration, die ich verwende
Ich halte diese Datei unter:
/etc/nginx/sites-available/myapp_https
Hier ist die tatsächliche Konfiguration, vereinfacht für den Artikel, aber dennoch genau.
server {
listen 443 ssl;
server_name finance.example.com;
ssl_certificate /opt/myapp/keystore/app.crt;
ssl_certificate_key /opt/myapp/keystore/app.key;
ssl_session_cache shared:SSL:1m;
ssl_session_timeout 5m;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_protocols TLSv1.2;
ssl_prefer_server_ciphers on;
large_client_header_buffers 4 65k;
client_max_body_size 100m;
error_page 502 503 = @maintenance;
error_page 404 = @errors;
access_log /opt/myapp/nginx/logs/access.log;
error_log /opt/myapp/nginx/logs/error.log;
location / {
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Server $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto https;
proxy_pass http://127.0.0.1:8080;
proxy_buffering off;
proxy_buffer_size 128k;
proxy_buffers 100 128k;
proxy_connect_timeout 180;
proxy_send_timeout 180;
proxy_read_timeout 180;
send_timeout 180;
location ~* \.(css|js|jpg|gif|ico)$ {
proxy_cache cache;
proxy_cache_key $host$uri$is_args$args;
proxy_cache_valid 200 301 302 30m;
expires 30m;
proxy_pass http://127.0.0.1:8080;
}
}
location = / {
return 301 /myapp/;
}
location @maintenance {
root /opt/myapp/nginx/www;
rewrite ^ /maintenance.html break;
}
location @errors {
root /opt/myapp/nginx/www;
rewrite ^ /404.html break;
}
}
Das ist der Kern des Systems. Nginx kümmert sich um SSL, leitet den Verkehr an Tomcat weiter, bedient die Wartungsseite, wenn Tomcat offline ist, cached statische Inhalte und schützt das interne Netzwerklayout.
HTTP-Weiterleitung (Port 80)
Ich habe eine einfache Konfiguration hinzugefügt, die gesamten HTTP-Verkehr zu HTTPS umleitet.
/etc/nginx/sites-available/myapp_http
server {
listen 80;
server_name finance.example.com;
return 301 https://$host$request_uri;
}
Ordnerstruktur
Ich halte die Nginx-bezogenen Dateien in einem speziellen Anwendungsordner:
/opt/myapp/
keystore/
nginx/
logs/
www/
Das macht es einfach, Zertifikate, Protokolle und statische Seiten zu verwalten.
Tomcat-Konfiguration, die die Einrichtung vervollständigt
Innerhalb von Tomcats server.xml binde ich Tomcat an localhost, sodass er nicht von außen zugänglich ist.
<Connector port="8080"
address="127.0.0.1"
maxHttpHeaderSize="65536"
protocol="HTTP/1.1"
connectionTimeout="20000"
maxThreads="150"/>
Ich lasse Tomcat auch die echte Client-IP und das Protokoll verstehen:
<Valve className="org.apache.catalina.valves.RemoteIpValve"
remoteIpHeader="X-Forwarded-For"
protocolHeader="X-Forwarded-Proto"
protocolHeaderHttpsValue="https"/>
Das stellt sicher, dass das System die korrekte Client-IP protokolliert und sich korrekt für HTTPS verhält.
Warum diese Einrichtung gut für ein Finanzsystem funktioniert
Nginx vor Tomcat zu setzen, hat das gesamte System viel professioneller und stabiler gemacht. Während der Bereitstellungen oder Neustarts stoßen die Benutzer niemals auf die typischen Tomcat 503-Seiten. Stattdessen sehen sie immer einen sauberen Wartungsbildschirm, was das System auch dann zuverlässig erscheinen lässt, wenn im Hintergrund gearbeitet wird.
Die Handhabung von SSL auf Nginx vereinfacht ebenfalls alles. Zertifikate sind einfacher zu verwalten, zu erneuern und zu debuggen, und Tomcat muss sich nicht mehr direkt mit HTTPS befassen. Ein weiterer Vorteil ist die Sicherheit. Da Tomcat nur auf localhost hört, ist es vollständig vor externem Verkehr verborgen, was eine ganze Kategorie von Scan- und Probeversuchen eliminiert.
Die Leistung verbessert sich ebenfalls. Statische Dateien wie CSS und JavaScript laden schneller, da Nginx sie cachen kann, und Uploads werden überprüft und begrenzt, bevor sie Tomcat überhaupt erreichen. Einige unserer Finanzoperationen beinhalten große Header oder lang laufende Aktionen, und Nginx gibt mir die volle Kontrolle über Puffergrößen und Timeouts, was diese Operationen reibungslos ablaufen lässt, ohne zufällige Fehler.
Selbst in Fällen, in denen Tomcat für einen Moment offline geht, reagiert die Seite dank der Wartungsseite weiterhin vorhersehbar. Im Laufe der Jahre hat sich diese Einrichtung als äußerst stabil erwiesen. Sie hat der Finanzanwendung geholfen, nahezu null Ausfallzeiten über viele Releases und Infrastrukturänderungen hinweg zu erreichen, und sie bewältigt weiterhin den Produktionsverkehr ohne Überraschungen.