บทนำ
เมื่อฉันสร้างแอปพลิเคชันการเงินของเราบน Tomcat, ฉันได้เรียนรู้เร็วว่า การวาง Tomcat ไว้บนอินเทอร์เน็ตสาธารณะโดยตรงไม่ใช่ความคิดที่ดี. มันทำงานได้ในตอนแรก แต่ก็เปราะบาง, ยากที่จะรักษาความปลอดภัย, และแทบจะเป็นไปไม่ได้ที่จะบำรุงรักษาได้อย่างราบรื่นในระหว่างการปรับใช้.
ในที่สุด, ฉันตัดสินใจที่จะวาง Nginx ไว้ข้างหน้า Tomcat และให้ Nginx จัดการทุกอย่างที่ Tomcat ไม่เก่ง, โดยเฉพาะการสิ้นสุด SSL, โหมดบำรุงรักษา, การแคชไฟล์สถิต และการซ่อนรายละเอียดโครงสร้างพื้นฐานภายใน.
บทความนี้อธิบายการตั้งค่าที่ฉันใช้ในผลิตภัณฑ์ในปัจจุบัน. มันไม่ใช่คู่มือทั่วไป. มันถูกเขียนขึ้นเฉพาะสำหรับระบบการเงินที่ฉันปรับใช้, และรวมถึงการกำหนดค่าจริงและเหตุผลเบื้องหลังการตัดสินใจแต่ละอย่าง.
ทำไมฉันถึงต้องการ Nginx ข้างหน้า Tomcat
1. หน้าเมนเทนแนนซ์ที่สะอาดเมื่อ Tomcat กำลังรีสตาร์ท
ในระบบการเงิน, เรามักจะต้องรีสตาร์ท Tomcat ในระหว่างการปรับใช้หรือบำรุงรักษา. หาก Tomcat หยุดทำงาน, ผู้ใช้ไม่ควรเห็นหน้า Tomcat 503 ที่ดิบซึ่งเปิดเผยข้อมูลเซิร์ฟเวอร์.
ด้วย Nginx, ผู้ใช้จะเห็นหน้าเมนเทนแนนซ์ที่เป็นมิตรเสมอ แม้ว่า Tomcat จะออฟไลน์โดยสิ้นเชิง. Nginx จะจับการตอบสนอง 502 หรือ 503 และให้บริการหน้า HTML สถิตที่ฉันจัดเตรียมไว้.
2. SSL ง่ายกว่ามากบน Nginx
การตั้งค่า SSL ภายใน Tomcat นั้นซับซ้อนเกินไป. คุณต้องแปลงใบรับรองเป็น Java keystore, จัดการกับตัวเชื่อมต่อและจัดการกับหลายรูปแบบ.
ด้วย Nginx, SSL ง่ายมาก. ฉันต้องการเพียงไฟล์สองไฟล์, ใบรับรองและคีย์ส่วนตัว. Nginx จะสิ้นสุด HTTPS, และ Tomcat จะได้รับเพียง HTTP ปกติจาก localhost. การต่ออายุใบรับรองและการดีบักก็ง่ายขึ้นเช่นกัน.
3. Tomcat ถูกซ่อนจากโลกภายนอกโดยสิ้นเชิง
ด้วยเหตุผลด้านความปลอดภัย, ฉันไม่ต้องการให้ Tomcat เปิดเผยพอร์ตหรือข้อมูลเซิร์ฟเวอร์ให้กับผู้ใช้สาธารณะ. Tomcat จะฟังเฉพาะที่ 127.0.0.1:8080.
หากมีใครพยายามสแกนเซิร์ฟเวอร์ของฉัน, พวกเขาจะไม่สามารถตรวจจับได้ว่า Tomcat มีอยู่เลย.
4. หัวข้อขนาดใหญ่สำหรับการอนุมัติทางการเงิน
บางการดำเนินการอนุมัติในระบบส่งรายการยาวของ ID แอปพลิเคชันการเงินในหัวข้อหรือสตริงคำถาม.
เพื่อรองรับหัวข้อขนาดใหญ่เหล่านี้, ฉันตั้งค่า Nginx ให้อนุญาตบัฟเฟอร์หัวข้อที่ใหญ่ขึ้น. หากไม่มีสิ่งนี้, คำขอบางอย่างอาจล้มเหลวเพราะขนาดหัวข้อเริ่มต้นเล็กเกินไป.
5. การอัปโหลดไฟล์ขนาดใหญ่
ผู้ใช้จะอัปโหลดสัญญา, ใบแจ้งหนี้ และเอกสารที่สแกน. ฉันตั้งขีดจำกัดขนาดการอัปโหลดที่ชัดเจนใน Nginx เพื่อให้ไฟล์ขนาดใหญ่ไม่ถึง Tomcat จนกว่าพวกมันจะผ่านการตรวจสอบของ Nginx ก่อน.
6. เนื้อหาสถิตที่เร็วขึ้น (CSS, JS, ไอคอน)
แม้ว่า Tomcat จะสามารถให้บริการไฟล์สถิติได้, Nginx ก็เร็วกว่า. ฉันเปิดใช้งานการแคชสำหรับสินทรัพย์สถิติ ดังนั้น Nginx จะให้บริการพวกเขาโดยตรงโดยไม่รบกวน Tomcat.
7. การหมดเวลาแบบกำหนดเองสำหรับการดำเนินการที่ใช้เวลานาน
บางกระบวนการในระบบการเงินใช้เวลานานขึ้น เช่น การสร้างรายงานหรือการอนุมัติแบบกลุ่ม.
Nginx ให้ฉันควบคุมการหมดเวลา proxy ได้อย่างเต็มที่ ดังนั้นผู้ใช้จึงไม่ต้องเผชิญกับข้อผิดพลาด 504 ที่ไม่คาดคิด.
การตั้งค่า HTTPS ของ Nginx ที่ฉันใช้
ฉันเก็บไฟล์นี้ไว้ที่:
/etc/nginx/sites-available/myapp_https
นี่คือการกำหนดค่าจริงที่ถูกทำให้เรียบง่ายสำหรับบทความ แต่ยังคงถูกต้อง.
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;
}
}
นี่คือแกนหลักของระบบ. Nginx จัดการ SSL, ส่งต่อการจราจรไปยัง Tomcat, ให้บริการหน้าเมนเทนแนนซ์เมื่อ Tomcat ออฟไลน์, แคชเนื้อหาสถิติ และปกป้องโครงสร้างเครือข่ายภายใน.
HTTP Redirect (พอร์ต 80)
ฉันได้เพิ่มการกำหนดค่าที่เรียบง่ายที่เปลี่ยนเส้นทางการจราจร HTTP ทั้งหมดไปยัง HTTPS.
/etc/nginx/sites-available/myapp_http
server {
listen 80;
server_name finance.example.com;
return 301 https://$host$request_uri;
}
โครงสร้างโฟลเดอร์
ฉันเก็บไฟล์ที่เกี่ยวข้องกับ Nginx ไว้ในโฟลเดอร์แอปพลิเคชันที่จัดสรรไว้:
/opt/myapp/
keystore/
nginx/
logs/
www/
นี่ทำให้การจัดการใบรับรอง, บันทึก และหน้าเว็บสถิตทำได้ง่าย.
การกำหนดค่า Tomcat ที่ทำให้การตั้งค่าเสร็จสมบูรณ์
ภายใน server.xml ของ Tomcat, ฉันผูก Tomcat กับ localhost เพื่อไม่ให้เข้าถึงจากภายนอก.
<Connector port="8080"
address="127.0.0.1"
maxHttpHeaderSize="65536"
protocol="HTTP/1.1"
connectionTimeout="20000"
maxThreads="150"/>
ฉันยังทำให้ Tomcat เข้าใจ IP ของลูกค้าจริงและโปรโตคอล:
<Valve className="org.apache.catalina.valves.RemoteIpValve"
remoteIpHeader="X-Forwarded-For"
protocolHeader="X-Forwarded-Proto"
protocolHeaderHttpsValue="https"/>
นี่ทำให้ระบบบันทึก IP ของลูกค้าได้อย่างถูกต้องและทำงานได้อย่างถูกต้องสำหรับ HTTPS.
ทำไมการตั้งค่านี้จึงทำงานได้ดีสำหรับระบบการเงิน
การวาง Nginx ไว้ข้างหน้า Tomcat ทำให้ทั้งระบบรู้สึกเป็นมืออาชีพและเสถียรมากขึ้น. ในระหว่างการปรับใช้หรือรีสตาร์ท, ผู้ใช้จะไม่พบกับหน้า Tomcat 503 ที่เป็นปกติ. แทนที่จะเป็นเช่นนั้น, พวกเขาจะเห็นหน้าจอเมนเทนแนนซ์ที่สะอาดเสมอ, ซึ่งทำให้ระบบดูเชื่อถือได้แม้ในขณะที่มีการทำงานอยู่เบื้องหลัง.
การจัดการ SSL บน Nginx ยังทำให้ทุกอย่างง่ายขึ้น. ใบรับรองจัดการได้ง่ายขึ้น, ต่ออายุและดีบักได้ง่ายขึ้น, และ Tomcat ไม่ต้องจัดการกับ HTTPS โดยตรงอีกต่อไป. อีกหนึ่งประโยชน์คือความปลอดภัย. เนื่องจาก Tomcat จะฟังเฉพาะที่ localhost, มันจึงถูกซ่อนจากการจราจรภายนอกโดยสิ้นเชิง, ซึ่งกำจัดความพยายามในการสแกนและตรวจสอบทั้งหมด.
ประสิทธิภาพก็เพิ่มขึ้นเช่นกัน. ไฟล์สถิตเช่น CSS และ JavaScript โหลดได้เร็วขึ้นเพราะ Nginx สามารถแคชพวกเขาได้, และการอัปโหลดจะถูกตรวจสอบและจำกัดก่อนที่จะถึง Tomcat. บางการดำเนินการทางการเงินของเรามีหัวข้อขนาดใหญ่หรือการกระทำที่ใช้เวลานาน, และ Nginx ให้ฉันควบคุมขนาดบัฟเฟอร์และการหมดเวลาได้อย่างเต็มที่, ซึ่งทำให้การดำเนินการเหล่านี้ทำงานได้อย่างราบรื่นโดยไม่มีข้อผิดพลาดสุ่ม.
แม้ในกรณีที่ Tomcat ออฟไลน์ชั่วขณะ, เว็บไซต์ยังคงตอบสนองได้อย่างคาดเดาได้ ขอบคุณหน้าเมนเทนแนนซ์. ตลอดหลายปีที่ผ่านมา, การตั้งค่านี้ได้พิสูจน์แล้วว่ามีความแข็งแกร่งอย่างมาก. มันช่วยให้แอปพลิเคชันการเงินบรรลุการหยุดทำงานเกือบเป็นศูนย์ในหลายการปล่อยและการเปลี่ยนแปลงโครงสร้างพื้นฐาน, และมันยังคงจัดการกับการจราจรในผลิตภัณฑ์โดยไม่มีความประหลาดใจ.