Giới thiệu
Khi tôi xây dựng ứng dụng tài chính của chúng tôi trên Tomcat, tôi nhanh chóng nhận ra rằng việc đặt Tomcat trực tiếp trên Internet công cộng không phải là một ý tưởng hay. Nó hoạt động tốt lúc đầu, nhưng rất dễ bị hỏng, khó bảo mật và gần như không thể duy trì một cách mượt mà trong quá trình triển khai.
Cuối cùng, tôi quyết định đặt Nginx ở phía trước Tomcat và để Nginx xử lý mọi thứ mà Tomcat không làm tốt, đặc biệt là SSL termination, chế độ bảo trì, caching tệp tĩnh và ẩn đi các chi tiết hạ tầng nội bộ.
Bài viết này giải thích cấu hình chính xác mà tôi sử dụng trong sản xuất ngày hôm nay. Đây không phải là một hướng dẫn chung. Nó được viết cụ thể cho hệ thống tài chính mà tôi đã triển khai, và bao gồm các cấu hình thực tế cũng như lý do đằng sau mỗi quyết định.
Tại sao tôi cần Nginx ở phía trước Tomcat
1. Một trang bảo trì sạch khi Tomcat đang khởi động lại
Trong một hệ thống tài chính, chúng tôi thường phải khởi động lại Tomcat trong quá trình triển khai hoặc bảo trì. Nếu Tomcat ngừng hoạt động, người dùng không bao giờ nên thấy một trang Tomcat 503 thô sơ mà lộ thông tin máy chủ.
Với Nginx, người dùng luôn thấy một trang bảo trì thân thiện, ngay cả khi Tomcat hoàn toàn ngoại tuyến. Nginx sẽ bắt phản hồi 502 hoặc 503 và phục vụ một trang HTML tĩnh mà tôi đã chuẩn bị.
2. SSL dễ dàng hơn nhiều trên Nginx
Cấu hình SSL bên trong Tomcat là điều không cần thiết phức tạp. Bạn phải chuyển đổi chứng chỉ thành một Java keystore, quản lý connector và xử lý nhiều định dạng khác nhau.
Với Nginx, SSL rất đơn giản. Tôi chỉ cần hai tệp, một chứng chỉ và một khóa riêng. Nginx sẽ xử lý HTTPS, và Tomcat chỉ nhận HTTP thuần từ localhost. Việc gia hạn chứng chỉ và gỡ lỗi cũng dễ dàng hơn.
3. Tomcat hoàn toàn ẩn khỏi thế giới bên ngoài
Vì lý do bảo mật, tôi không muốn Tomcat lộ các cổng hoặc thông tin máy chủ cho người dùng công cộng. Tomcat chỉ lắng nghe trên 127.0.0.1:8080.
Nếu ai đó cố gắng quét máy chủ của tôi, họ sẽ không thể phát hiện rằng Tomcat tồn tại.
4. Các tiêu đề lớn cho phê duyệt tài chính
Một số thao tác phê duyệt trong hệ thống gửi một danh sách dài các ID ứng dụng tài chính trong tiêu đề hoặc chuỗi truy vấn.
Để hỗ trợ các tiêu đề lớn này, tôi đã cấu hình Nginx để cho phép các bộ đệm tiêu đề lớn hơn. Nếu không có điều này, một số yêu cầu sẽ thất bại vì kích thước tiêu đề mặc định quá nhỏ.
5. Tải lên tệp lớn
Người dùng tải lên hợp đồng, hóa đơn và tài liệu quét. Tôi đặt giới hạn kích thước tải lên sạch trong Nginx để các tệp lớn không đến được Tomcat trừ khi chúng vượt qua xác thực của Nginx trước.
6. Nội dung tĩnh nhanh hơn (CSS, JS, biểu tượng)
Mặc dù Tomcat có thể phục vụ các tệp tĩnh, nhưng Nginx nhanh hơn nhiều. Tôi đã bật caching cho các tài sản tĩnh để Nginx phục vụ chúng trực tiếp mà không làm phiền Tomcat.
7. Thời gian chờ tùy chỉnh cho các thao tác lâu dài
Một số quy trình trong hệ thống tài chính mất nhiều thời gian hơn, chẳng hạn như tạo báo cáo hoặc phê duyệt hàng loạt.
Nginx cho tôi toàn quyền kiểm soát thời gian chờ proxy để người dùng không nhận được lỗi 504 bất ngờ.
Cấu hình HTTPS Nginx mà tôi sử dụng
Tôi giữ tệp này tại:
/etc/nginx/sites-available/myapp_https
Dưới đây là cấu hình thực tế, được đơn giản hóa cho bài viết nhưng vẫn chính xác.
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;
}
}
Đây là phần cốt lõi của hệ thống. Nginx xử lý SSL, chuyển tiếp lưu lượng đến Tomcat, phục vụ trang bảo trì khi Tomcat ngoại tuyến, caching nội dung tĩnh và bảo vệ cấu trúc mạng nội bộ.
Chuyển hướng HTTP (Cổng 80)
Tôi đã thêm một cấu hình đơn giản để chuyển hướng tất cả lưu lượng HTTP sang HTTPS.
/etc/nginx/sites-available/myapp_http
server {
listen 80;
server_name finance.example.com;
return 301 https://$host$request_uri;
}
Cấu trúc thư mục
Tôi giữ các tệp liên quan đến Nginx trong một thư mục ứng dụng riêng biệt:
/opt/myapp/
keystore/
nginx/
logs/
www/
Điều này giúp dễ dàng quản lý chứng chỉ, nhật ký và các trang tĩnh.
Cấu hình Tomcat hoàn thiện thiết lập
Bên trong server.xml của Tomcat, tôi liên kết Tomcat với localhost để nó không thể được truy cập từ bên ngoài.
<Connector port="8080"
address="127.0.0.1"
maxHttpHeaderSize="65536"
protocol="HTTP/1.1"
connectionTimeout="20000"
maxThreads="150"/>
Tôi cũng làm cho Tomcat hiểu IP và giao thức của khách hàng thực sự:
<Valve className="org.apache.catalina.valves.RemoteIpValve"
remoteIpHeader="X-Forwarded-For"
protocolHeader="X-Forwarded-Proto"
protocolHeaderHttpsValue="https"/>
Điều này đảm bảo rằng hệ thống ghi lại đúng IP của khách hàng và hoạt động chính xác cho HTTPS.
Tại sao thiết lập này hoạt động tốt cho hệ thống tài chính
Đặt Nginx ở phía trước Tomcat đã làm cho toàn bộ hệ thống cảm thấy chuyên nghiệp và ổn định hơn rất nhiều. Trong quá trình triển khai hoặc khởi động lại, người dùng không bao giờ gặp phải các trang Tomcat 503 điển hình. Thay vào đó, họ luôn thấy một màn hình bảo trì sạch sẽ, điều này khiến hệ thống trông đáng tin cậy ngay cả khi công việc đang diễn ra ở phía sau.
Xử lý SSL trên Nginx cũng đơn giản hóa mọi thứ. Việc quản lý, gia hạn và gỡ lỗi chứng chỉ dễ dàng hơn, và Tomcat không còn phải xử lý HTTPS trực tiếp. Một lợi ích khác là bảo mật. Vì Tomcat chỉ lắng nghe trên localhost, nó hoàn toàn ẩn khỏi lưu lượng bên ngoài, điều này loại bỏ một loại hình quét và thăm dò hoàn toàn.
Hiệu suất cũng được cải thiện. Các tệp tĩnh như CSS và JavaScript tải nhanh hơn vì Nginx có thể cache chúng, và các tệp tải lên được kiểm tra và giới hạn trước khi chúng đến được Tomcat. Một số hoạt động tài chính của chúng tôi liên quan đến các tiêu đề lớn hoặc các thao tác lâu dài, và Nginx cho tôi toàn quyền kiểm soát kích thước bộ đệm và thời gian chờ, điều này giúp các thao tác này diễn ra mượt mà mà không gặp phải lỗi ngẫu nhiên.
Ngay cả trong những trường hợp Tomcat đi ngoại tuyến trong một khoảnh khắc, trang web vẫn phản hồi một cách dự đoán nhờ vào trang bảo trì. Qua nhiều năm, thiết lập này đã chứng minh là cực kỳ vững chắc. Nó đã giúp ứng dụng tài chính đạt được thời gian ngừng hoạt động gần như bằng không qua nhiều lần phát hành và thay đổi hạ tầng, và nó tiếp tục xử lý lưu lượng sản xuất mà không có bất ngờ.