Nginx+Tomcat負(fù)載均衡集群詳解
一、Tomcat 基礎(chǔ)與單節(jié)點(diǎn)部署
(一)Tomcat 概述
名稱由來(lái):由 Sun 公司詹姆斯?鄧肯?戴維森開(kāi)發(fā),后貢獻(xiàn)給 Apache 軟件基金會(huì)。因希望項(xiàng)目以能自我照顧的動(dòng)物命名,最終定名為 “Tomcat”(公貓),其 Logo 也設(shè)計(jì)為公貓形象。早期項(xiàng)目名為 “Catalina”,故安裝后可見(jiàn)許多相關(guān)目錄和文件。
應(yīng)用場(chǎng)景:免費(fèi)開(kāi)源的輕量級(jí) Web 應(yīng)用服務(wù)器,適用于中小型系統(tǒng)及并發(fā)用戶不多的場(chǎng)合,是開(kāi)發(fā)調(diào)試 JSP 程序的首選。雖具備處理 HTML 頁(yè)面功能,但處理靜態(tài) HTML 能力不及 Apache 或 Nginx,通常作為 Servlet 和 JSP 容器運(yùn)行于后端,與前端 Web 服務(wù)器(如 Apache、Nginx)及數(shù)據(jù)庫(kù)配合工作。
(二)單節(jié)點(diǎn)部署案例
1. 案例環(huán)境
- 主機(jī):服務(wù)器 Tomcat
- IP 地址:192.168.10.101
- 操作系統(tǒng):OpenEuler24
- 應(yīng)用:apache-tomcat-9.0.8
2. 實(shí)施準(zhǔn)備
# 關(guān)閉防火墻 systemctl stop firewalld setenforce 0
3. 安裝 JDK
JDK(Java Development Kit)是 Java 語(yǔ)言的軟件開(kāi)發(fā)工具包,包含 JVM(Java 虛擬機(jī)),用于解釋 Java 字節(jié)碼,實(shí)現(xiàn)跨平臺(tái)性。
JDK 版本需與 Tomcat 兼容,下載對(duì)應(yīng)版本的 JDK 安裝包并安裝。
4. 查看 JDK 安裝情況
java -version
若輸出 Java 版本信息(如 “java version "1.8.0_171"”),則說(shuō)明 JDK 已安裝。
5. 安裝配置 Tomcat
# 解壓Tomcat安裝包 tar xf apache-tomcat-9.0.8.tar.gz # 移動(dòng)并重命名文件夾 mv apache-tomcat-9.0.8 /usr/local/tomcat9
6. 啟動(dòng) Tomcat
/usr/local/tomcat9/bin/startup.sh
啟動(dòng)后,默認(rèn)監(jiān)聽(tīng) 8080 端口,可通過(guò)以下命令查看端口監(jiān)聽(tīng)情況:
netstat -anpt | grep 8080
7. 訪問(wèn)測(cè)試
在瀏覽器中輸入 “http://192.168.10.101:8080/”,若出現(xiàn) Tomcat 歡迎界面,則表示啟動(dòng)成功。
8. 關(guān)閉 Tomcat
/usr/local/tomcat9/bin/shutdown.sh
(三)Tomcat 目錄與配置文件說(shuō)明
主要目錄:
- bin/:存放啟動(dòng)和關(guān)閉 Tomcat 的腳本文件(如 startup.sh、shutdown.sh)。
- conf/:存放全局配置文件,重要文件包括 server.xml(主配置文件)、web.xml(Servlet 等配置)、tomcat-users.xml(管理用戶配置)。
- lib/:存放 Tomcat 運(yùn)行所需的庫(kù)文件(JAR 包)。
- logs/:存放日志文件。
- webapps/:主要 Web 發(fā)布目錄,用于部署應(yīng)用程序。
- work/:存放 JSP 編譯后生成的 class 文件。
主配置文件 server.xml:
結(jié)構(gòu)組成:由<Server>、<Service>、<Connector/>、<Engine>、<Host>、<Context>等元素構(gòu)成。
關(guān)鍵配置:
- 端口配置:<Connector port="8080" protocol="HTTP/1.1" .../> 用于配置 HTTP 訪問(wèn)端口;<Connector port="8009" protocol="AJP/1.3" .../> 用于配置 AJP 連接器端口,供其他 Web 服務(wù)器代理請(qǐng)求。
- 虛擬主機(jī)配置:<Host name="localhost"appBase="webapps" ...> 定義虛擬主機(jī),appBase 指定應(yīng)用程序基礎(chǔ)目錄,可通過(guò)<Context>元素配置具體 Web 應(yīng)用的路徑。
(四)建立 Java Web 站點(diǎn)
創(chuàng)建站點(diǎn)目錄
mkdir -pv /web/webapp1
創(chuàng)建測(cè)試頁(yè)面 index.jsp
vim /web/webapp1/index.jsp
內(nèi)容如下:
<%@page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<html>
<head>
<title>JSP test1 page</title>
</head>
<body>
<%out.println("動(dòng)態(tài)頁(yè)面1,http://www.test1.com");%>
<div>靜態(tài)頁(yè)面的圖片1</div><br><img src="logo.jpg">
</body>
</html>修改 server.xml 配置
在<Host>元素中添加<Context>配置,將站點(diǎn)路徑指向 /web/webapp1:
<Context docBase="/web/webapp1" path="" reloadable="true"/>
重啟 Tomcat
/usr/local/tomcat9/bin/shutdown.sh /usr/local/tomcat9/bin/startup.sh
訪問(wèn)測(cè)試
在瀏覽器中輸入 “http://192.168.10.101:8080/”,應(yīng)顯示自定義的 JSP 頁(yè)面內(nèi)容。
二、Nginx+Tomcat 負(fù)載均衡與動(dòng)靜分離群集搭建
(一)案例分析
需求背景:?jiǎn)闻_(tái) Tomcat 存在單點(diǎn)故障風(fēng)險(xiǎn),且處理靜態(tài)資源效率低。Nginx 具有高性能、低資源消耗的特點(diǎn),可作為反向代理和負(fù)載均衡器,與 Tomcat 結(jié)合實(shí)現(xiàn)動(dòng)靜分離,提升站點(diǎn)性能和可靠性。
拓?fù)浼軜?gòu):Nginx 作為前端負(fù)載均衡器,負(fù)責(zé)處理靜態(tài)資源請(qǐng)求和分發(fā)動(dòng)態(tài)請(qǐng)求到后端 Tomcat 服務(wù)器(Tomcat1 和 Tomcat2)。
(二)案例環(huán)境
| 主機(jī) | IP 地址 | 操作系統(tǒng) | 應(yīng)用 |
|---|---|---|---|
| Tomcat1 服務(wù)器 | 192.168.10.101 | OpenEuler24 | apache-tomcat-9.0.8 |
| Tomcat2 服務(wù)器 | 192.168.10.102 | OpenEuler24 | apache-tomcat-9.0.8 |
| Nginx 服務(wù)器 | 192.168.10.103 | OpenEuler24 | nginx-1.26.3 |
(三)Tomcat2 服務(wù)器配置
關(guān)閉防火墻(同 Tomcat1)
systemctl stop firewalld setenforce 0
安裝 JDK 和 Tomcat(版本與 Tomcat1 一致)
# 安裝JDK(若未安裝) # 解壓Tomcat安裝包 tar xf apache-tomcat-9.0.8.tar.gz # 移動(dòng)并重命名 mv apache-tomcat-9.0.8 /usr/local/tomcat9
創(chuàng)建站點(diǎn)目錄并配置
mkdir -pv /web/webapp1
修改 server.xml 中的<Context>配置,指向 /web/webapp1:
<Context docBase="/web/webapp1" path="" reloadable="true"/>
創(chuàng)建測(cè)試頁(yè)面 index.jsp
vim /web/webapp1/index.jsp
內(nèi)容如下:
<%@page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<html>
<head>
<title>JSP test2 page</title>
</head>
<body>
<%out.println("動(dòng)態(tài)頁(yè)面2,http://www.test2.com");%>
<div>動(dòng)態(tài)頁(yè)面的圖片2</div><br><img src="logo.jpg">
</body>
</html>啟動(dòng) Tomcat2 并測(cè)試
/usr/local/tomcat9/bin/startup.sh
在瀏覽器中輸入 “http://192.168.10.102:8080/”,查看頁(yè)面是否正確顯示。
(四)Nginx 服務(wù)器配置
關(guān)閉防火墻
systemctl stop firewalld setenforce 0
安裝依賴軟件包
dnf install -y gcc make pcre-devel zlib-devel openssl-devel perl-ExtUtils-MakeMaker
創(chuàng)建 Nginx 用戶
useradd -M -s /sbin/nologin nginx
解壓并安裝 Nginx
tar zxf nginx-1.26.3.tar.gz cd nginx-1.26.3 ./configure --prefix=/usr/local/nginx --user=nginx --group=nginx --with-http_ssl_module --with-http_v2_module --with-pcre make && make install
配置 nginx.conf
vim /usr/local/nginx/conf/nginx.conf
在 http {} 塊中添加負(fù)載均衡服務(wù)器列表:
upstream tomcat_server {
server 192.168.10.101:8080 weight=1;
server 192.168.10.102:8080 weight=1;
}在 server {} 塊中配置動(dòng)靜分離規(guī)則:
location ~ \.jsp$ {
proxy_set_header HOST $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Client-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://tomcat_server;
}
location ~* \.(gif|jpg|jpeg|png|bmp|swf|css|js)$ {
root /usr/local/nginx/html/img;
expires 30d;
}
location / {
root html;
index index.html index.htm;
}準(zhǔn)備靜態(tài)圖片
mkdir /usr/local/nginx/html/img cp /root/logo.jpg /usr/local/nginx/html/img
測(cè)試配置文件
/usr/local/nginx/sbin/nginx -t
啟動(dòng) Nginx 服務(wù)
/usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf
查看服務(wù)進(jìn)程和端口
ps aux | grep nginx netstat -anpt | grep nginx
(五)測(cè)試效果
- 靜態(tài)頁(yè)面測(cè)試:在瀏覽器中輸入 “http://192.168.10.103/”,應(yīng)顯示 Nginx 默認(rèn)的靜態(tài)頁(yè)面。
- 負(fù)載均衡測(cè)試:在瀏覽器中輸入 “http://192.168.10.103/index.jsp”,不斷刷新頁(yè)面,應(yīng)交替顯示 Tomcat1 和 Tomcat2 的測(cè)試頁(yè)面,表明負(fù)載均衡生效。
三、心得
通過(guò) Nginx 與 Tomcat 的結(jié)合,實(shí)現(xiàn)了動(dòng)靜分離和負(fù)載均衡,提升了 Web 站點(diǎn)的性能、可擴(kuò)展性和穩(wěn)定性。Nginx 高效處理靜態(tài)資源,減輕了 Tomcat 的壓力,使其專注于動(dòng)態(tài)請(qǐng)求處理。這種架構(gòu)是現(xiàn)代 Web 應(yīng)用優(yōu)化的重要實(shí)踐,適用于中小型網(wǎng)站及高并發(fā)場(chǎng)景的初步搭建。在實(shí)際生產(chǎn)環(huán)境中,還可進(jìn)一步結(jié)合緩存機(jī)制、安全策略等,進(jìn)一步提升系統(tǒng)的可靠性和用戶體驗(yàn)。
四、Tomcat 核心組件解析
(一)Server 與 Service
Server
- 代表整個(gè) Catalina Servlet 容器,是 Tomcat 的頂層容器,負(fù)責(zé)管理所有 Service 組件,監(jiān)聽(tīng)關(guān)閉端口(默認(rèn) 8005),通過(guò)
SHUTDOWN命令終止服務(wù)。 - 配置示例(s2erver.xml):
<Server port="8005" shutdown="SHUTDOWN"> <!-- 包含多個(gè)Service --> </Server>
Service
- 是一個(gè)或多個(gè) Connector 與一個(gè) Engine 的組合,負(fù)責(zé)接收請(qǐng)求并將其交給 Engine 處理。
- 每個(gè) Serv3ice 可定義多個(gè) Connector(如 HTTP 和 AJP 連接器),但只能有一個(gè) Engine:
<Service name="Catalina">
<Connector port="8080" protocol="HTTP/1.1" />
<Engine name="Catalina" defaultHost="localhost">
<!-- 虛擬主機(jī)配置 -->
</Engine>
</Service>(二)Connector:請(qǐng)求入口
功能與類型
- 監(jiān)聽(tīng)指定端口,接收客戶端請(qǐng)求并轉(zhuǎn)發(fā)給 Engine,同時(shí)將響應(yīng)返回給客戶端。
典型 Co4nnector:
- HTTP Connector(端口 8080):直接處理瀏覽器的 HTTP 請(qǐng)求,協(xié)議為
HTTP/1.1,用于動(dòng)態(tài)頁(yè)面訪問(wèn)。 - AJ5P Connector(端口 8009):接收其他 Web 服務(wù)器(如 Nginx)的代理請(qǐng)求,協(xié)議為
AJP/1.3,用于動(dòng)靜分離場(chǎng)景。
關(guān)鍵配置參6數(shù)
port:監(jiān)聽(tīng)端口(如 8080)。protocol:協(xié)議類型(如HTTP/1.1或AJP/1.3)。connectionTimeout:連接超時(shí)時(shí)間(單位毫秒,默認(rèn) 20000ms)。redirectPort:HTTPS 請(qǐng)求重定向端口(默認(rèn) 8443)。
(三)Eng1ine 與 Host:請(qǐng)求處理與虛擬主機(jī)
Engine
- 作為 Service 的核心組件,管理多個(gè)虛擬主機(jī)(Host),負(fù)責(zé)將請(qǐng)求匹配到對(duì)應(yīng)的 Host 處理。
- 包含一個(gè)默認(rèn)7虛擬主機(jī),當(dāng)請(qǐng)求無(wú)法匹配任何 Host 時(shí),由默認(rèn) Host 處理:
<Engine name="Catalina" defaultHost="localhost">
<Host name="localhost" appBase="webapps">
<!-- 具體Host配置 -->
</Host>
</Engine>Host(虛擬主機(jī))
- 對(duì)應(yīng)一個(gè)域名(如
localhost),通過(guò)appBase指定 Web 應(yīng)用的基礎(chǔ)目錄(默認(rèn)webapps),可部署多個(gè) Web 應(yīng)用(Context)。 - 匹配規(guī)則8:根據(jù)請(qǐng)求的域名或 IP 匹配 Host,若無(wú)法匹配則使用 Engine 的默認(rèn) Host。
示例配置:
<Host name="www.test.com" appBase="/data/webapps" unpackWARs="true" autoDeploy="true"> <Context path="/app1" docBase="/data/webapps/app1" /> </Host>
unpackWARs:是否自動(dòng)解壓 WAR 包(默認(rèn)true)。autoDeploy:是否自動(dòng)部署更新的應(yīng)用(默認(rèn)true)。
(四)Context:Web 應(yīng)用容器
功能
- 代表一個(gè) Web 應(yīng)用,對(duì)應(yīng)一個(gè)目錄或 WAR 包,包含 Servlet、JSP、配置文件等資源。
- 通過(guò)
doc{insert\_element\_8\_}Base指定物理路徑,path指定訪問(wèn)路徑(如path="/app"表示通過(guò)http://host:port/app訪問(wèn))。
關(guān)鍵配置
reloadable:是否監(jiān)聽(tīng)類文件變化并自動(dòng)重啟(開(kāi)發(fā)環(huán)境可用,生產(chǎn)環(huán)境建議關(guān)閉)。sessi{insert\_element\_9\_}onTimeout:會(huì)話超時(shí)時(shí)間(分鐘,默認(rèn) 30 分鐘)。welcome-file-list:歡迎頁(yè)面列表(如index.jsp、index.html)。
(五)組件協(xié)作流程
請(qǐng)求鏈路
客戶端請(qǐng)求 → Connector(接收) → Engine(路由) → Host(匹配虛擬主機(jī)) → Context(處理Web應(yīng)用) → 返回響應(yīng)
示例場(chǎng)景
用戶訪問(wèn)http://www.test.com/app1/index.jsp:
- Connector(8080 端口)接收 HTTP 請(qǐng)求。
- Engine 根據(jù)域名
www.test.com匹配到對(duì)應(yīng)的 Host。 - Host 根據(jù)
path="/app1"找到對(duì)應(yīng)的 Context,調(diào)用 JSP 引擎編譯并執(zhí)行index.jsp,返回動(dòng)態(tài)內(nèi)容。
五、Nginx 負(fù)載均衡策略與優(yōu)化
(一)負(fù)載均衡策略配置
輪詢(默認(rèn))
- 按順序依次將請(qǐng)求分發(fā)到后端服務(wù)器,權(quán)重相同則均勻分配,適用于服務(wù)器性能一致的場(chǎng)景。
- 配置示例(nginx.conf):
upstream tomcat_server {
server 192.168.10.101:8080;
server 192.168.10.102:8080;
}權(quán)重輪詢(weight)
- 通過(guò)
weight參數(shù)指定服務(wù)器處理請(qǐng)求的優(yōu)先級(jí),權(quán)重越高分配概率越大,適用于服務(wù)器性能不均的場(chǎng)景。 - 配置示例:
upstream tomcat_server {
server 192.168.10.101:8080 weight=2; # 處理2倍請(qǐng)求
server 192.168.10.102:8080 weight=1;
}IP 哈希(ip_hash)
- 根據(jù)客戶端 IP 地址生成哈希值,將同一 IP 的請(qǐng)求固定分發(fā)到同一服務(wù)器,用于保持會(huì)話一致性(如未使用 Session 共享時(shí))。
- 配置示例:
upstream tomcat_server {
ip_hash;
server 192.168.10.101:8080;
server 192.168.10.102:8080;
}(二)健康檢查機(jī)制
被動(dòng)檢查(默認(rèn))
- Nginx 默認(rèn)通過(guò)請(qǐng)求響應(yīng)狀態(tài)判斷服務(wù)器是否存活,若返回 5xx 錯(cuò)誤或超時(shí),則認(rèn)為服務(wù)器故障,自動(dòng)跳過(guò)(故障恢復(fù)后重新加入)。
- 配置參數(shù):
upstream tomcat_server {
server 192.168.10.101:8080 max_fails=2 fail_timeout=30s;
}max_fails:允許失敗次數(shù)(默認(rèn) 1 次)。fail_timeout:故障超時(shí)時(shí)間(默認(rèn) 10 秒,期間不再轉(zhuǎn)發(fā)請(qǐng)求)。
主動(dòng)檢查(第三方模塊)
- 使用
ngx_http_upstream_check_module等模塊,定期向服務(wù)器發(fā)送健康檢查請(qǐng)求(如/health接口),主動(dòng)檢測(cè)狀態(tài)。 - 示例配置:
upstream tomcat_server {
server 192.168.10.101:8080;
check interval=5000 rise=2 fall=3 timeout=3000 type=http;
check_http_send "GET /health HTTP/1.0\r\n\r\n";
check_http_expect_1xx any;
}(三)動(dòng)靜分離優(yōu)化實(shí)踐
靜態(tài)資源緩存配置
- 通過(guò)
expires指令設(shè)置靜態(tài)資源(如圖片、CSS、JS)的瀏覽器緩存時(shí)間,減少重復(fù)請(qǐng)求。 - 配置示例:
location ~* \.(gif|jpg|jpeg|png|bmp|swf|css|js)$ {
root /usr/local/nginx/html/img;
expires 30d; # 緩存30天
add_header Cache-Control "public";
}壓縮優(yōu)化
- 啟用 Gzip 壓縮,減少動(dòng)態(tài)頁(yè)面?zhèn)鬏斄髁浚ㄐ?Tomcat 配合設(shè)置響應(yīng)頭)。
- Nginx 配置:
http {
gzip on;
gzip_types text/plain text/css application/json application/javascript text/html;
gzip_comp_level 6; # 壓縮級(jí)別(1-9,默認(rèn)6)
}防盜鏈配置
- 通過(guò)
valid_referers阻止非法域名引用靜態(tài)資源,保護(hù)圖片、文件等資源。 - 配置示例:
location ~* \.(gif|jpg|jpeg|png)$ {
valid_referers none blocked www.test.com test.com;
if ($invalid_referer) {
return 403;
}
}六、生產(chǎn)環(huán)境部署注意事項(xiàng)
(一)安全加固
端口與防火墻
- 僅開(kāi)放必要端口(如 Nginx 的 80/443、Tomcat 的 8080/8009),關(guān)閉其他端口。
- 使用防火墻(如 Firewalld、UFW)限制 IP 訪問(wèn),僅允許可信 IP 連接后端 Tomcat。
用戶權(quán)限
- Nginx 和 Tomcat 均使用非 root 用戶運(yùn)行(如
nginx、tomcat用戶),避免權(quán)限過(guò)高導(dǎo)致安全風(fēng)險(xiǎn)。 - 修改文件權(quán)限,確保配置文件和日志目錄僅可被管理員讀寫:
chown -R nginx:nginx /usr/local/nginx chown -R tomcat:tomcat /usr/local/tomcat9
HTTPS 配置
- 為 Nginx 添加 SSL 證書,啟用 HTTPS 加密傳輸,提升數(shù)據(jù)安全性。
- 配置示例:
server {
listen 443 ssl;
server_name www.test.com;
ssl_certificate /path/to/cert.pem;
ssl_certificate_key /path/to/key.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384;
}(二)性能調(diào)優(yōu)
Nginx worker 進(jìn)程優(yōu)化
worker_processes:設(shè)置為服務(wù)器 CPU 核心數(shù),充分利用多核性能。worker_connections:?jiǎn)蝹€(gè)進(jìn)程最大連接數(shù)(需配合ulimit -n調(diào)整系統(tǒng)文件描述符限制)。
worker_processes 4; # 假設(shè)4核CPU
events {
worker_connections 10240;
}Tomcat 線程池調(diào)整
- 修改 server.xml 中的
<Connector>配置,調(diào)整線程池參數(shù):
<Connector port="8080" protocol="HTTP/1.1">
<Executor name="tomcatExecutor" namePrefix="catalina-exec-"
maxThreads="200" minSpareThreads="20" maxSpareThreads="50"
maxQueueSize="100" />
</Connector>maxThreads:最大工作線程數(shù)(默認(rèn) 200,根據(jù)并發(fā)量調(diào)整)。maxQueueSize:請(qǐng)求隊(duì)列最大長(zhǎng)度(防止內(nèi)存溢出)。
連接超時(shí)優(yōu)化
- 縮短 Nginx 和 Tomcat 的超時(shí)時(shí)間,釋放無(wú)效連接:
# Nginx配置 proxy_connect_timeout 5s; proxy_read_timeout 10s; proxy_send_timeout 10s;
# Tomcat配置(server.xml) <Connector port="8080" connectionTimeout="20000" />
(三)監(jiān)控與日志
Nginx 日志配置
開(kāi)啟訪問(wèn)日志和錯(cuò)誤日志,記錄詳細(xì)請(qǐng)求信息以便排查問(wèn)題:
http {
access_log logs/access.log main;
error_log logs/error.log error;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
}Tomcat 日志分析
主要日志文件:
catalina.out:控制臺(tái)輸出日志,包含啟動(dòng)信息和錯(cuò)誤堆棧。localhost_access_log.txt:訪問(wèn)日志,記錄請(qǐng)求路徑、響應(yīng)狀態(tài)等。
配置日志切割9,避免單文件過(guò)大:
# 使用logrotate工具
cat /etc/logrotate.d/tomcat
/usr/local/tomcat9/logs/*.log {
daily
rotate 7
compress
missingok
notifempty
}監(jiān)控工具集成
使用 Prometheus+Grafana 監(jiān)控 Nginx 和 Tomcat 的性能指標(biāo)(如請(qǐng)求量、響應(yīng)時(shí)間、服務(wù)器負(fù)載)。
Nginx 可通過(guò)ngx_http_stub_status_module暴露狀態(tài)數(shù)據(jù):
location /nginx_status {
stub_status on;
access_log off;
allow 127.0.0.1;
deny all;
}七、常見(jiàn)問(wèn)題與解決方案
(一)動(dòng)態(tài)頁(yè)面無(wú)法訪問(wèn)
排查步驟
- 檢查 Nginx 代理配置:確認(rèn)
location ~ \.jsp$規(guī)則是否正確,proxy_pass是否指向負(fù)載均衡組(如http://tomcat_server)。 - 檢查 To13mcat 服務(wù)狀態(tài):確保 Tomcat 已啟動(dòng),端口(8080)監(jiān)聽(tīng)正常,通過(guò)
curl http://localhost:8080測(cè)試本地訪問(wèn)。
查看日志:
- Nginx 錯(cuò)誤日志(
/usr/local/nginx/logs/error.log)是否有代理連接失敗信息。 - Tomcat 控制臺(tái)日志(
catalina.out)是否有 JSP 編譯錯(cuò)誤或 Servlet 異常。
常見(jiàn)原因
- Nginx 與 Tomcat 之間網(wǎng)絡(luò)不通(如防火墻攔截、IP / 端口錯(cuò)誤)。
- Tomcat 的
server.xml中未正確配置 Context 路徑,導(dǎo)致請(qǐng)求無(wú)法映射到實(shí)際文件。
(二)靜態(tài)資11源加載失敗
排查步驟
- 檢查 Nginx 路徑配置:確認(rèn)
location ~* \.(gif|jpg|png)$中的root路徑是否正確(如/usr/local/nginx/html/img),文件是否存在。 - 檢查文件14權(quán)限:確保 Nginx 用戶(如
nginx)對(duì)靜態(tài)資源目錄有讀取權(quán)限。 - 測(cè)試直接訪問(wèn):通過(guò)
http://192.168.10.103/img/logo.jpg直接訪問(wèn)圖片,查看是否返回 404 或 403 錯(cuò)誤。
解決方案
修正root或alias路徑,確保與實(shí)際文件路徑一致(root為絕對(duì)路徑,alias為自定義路徑)。
賦予目錄讀權(quán)限:
chmod -R o+r /usr/local/nginx/html/img
(三)負(fù)載均衡未生效
排查步驟
- 檢查 upstream 配置:確認(rèn)
serverIP 和端口是否正確,權(quán)重設(shè)置是否合理,是否遺漏ip_hash等策略。 - 清除瀏覽12器緩存:刷新頁(yè)面時(shí)按
Ctrl+F5強(qiáng)制清除緩存,避免瀏覽器緩存導(dǎo)致請(qǐng)求未分發(fā)到后端。 - 查看請(qǐng)求頭:通過(guò)瀏覽器開(kāi)發(fā)者工具查看
X-Forwarded-For頭,確認(rèn)是否包含后端 Tomcat 的 IP 地址。
常見(jiàn)原因
- Nginx 配置未重新加載:修改
nginx.conf后需執(zhí)行nginx -s reload使配置生效。 - 后端服務(wù)器故障:某臺(tái) Tomcat 未啟動(dòng)或端口被占用,Nginx 自動(dòng)將其從負(fù)載均衡組中剔除。
八、擴(kuò)展與高可用架構(gòu)
(一)增加 Tomcat 節(jié)點(diǎn)
步驟說(shuō)明
新增 Tomcat 服務(wù)器(如 192.168.10.104),重復(fù) “Tomcat2 服務(wù)器配置” 步驟,確保 JDK 和 Tomcat 版本一致,站點(diǎn)目錄和測(cè)試頁(yè)面配置正確。
修改 Nginx 的upstream配置,添加新節(jié)點(diǎn):
upstream tomcat_server {
server 192.168.10.101:8080 weight=1;
server 192.168.10.102:8080 weight=1;
server 192.168.10.104:8080 weight=1; # 新增節(jié)點(diǎn)
}- 執(zhí)行
nginx -s reload重新加載配置,新節(jié)點(diǎn)即可參與負(fù)載均衡。
Session 共享方案
問(wèn)題背景:負(fù)載均衡場(chǎng)景下,若客戶端請(qǐng)求被分發(fā)到不同 Tomcat 節(jié)點(diǎn),未共享的 Session 會(huì)導(dǎo)致用戶狀態(tài)丟失。
解決方案:
- Tomcat 自帶 Session 復(fù)制:在
server.xml的<Engine>或<Host>中配置Cluster元素,實(shí)現(xiàn) Session 在節(jié)點(diǎn)間同步(適用于小規(guī)模集群,但存在性能開(kāi)銷)。
<Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"/>
- 分布式緩存(如 Redis):使用
tomcat-redis-session-manager等插件,將 Session 存儲(chǔ)到 Redis 中,所有 Tomcat 節(jié)點(diǎn)共享緩存數(shù)據(jù)。
# 添加Maven依賴(Tomcat 9為例) <dependency> <groupId>com.orangefunction</groupId> <artifactId>tomcat-redis-session-manager</artifactId> <version>2.0.3</version> </dependency>
配置context.xml:
<Context>
<Manager className="com.orangefunction.tomcat.redissessions.RedisSessionHandlerValve"/>
<SessionHandler className="com.orangefunction.tomcat.redissessions.RedisSessionHandler"
host="192.168.10.105" port="6379" database="0" />
</Context>(二)Nginx 高可用(主從 / 集群)
主從模式(Keepalived)
- 架構(gòu)說(shuō)明:通過(guò) Keepalived 實(shí)現(xiàn) Nginx 主節(jié)點(diǎn)(Master)和備用節(jié)點(diǎn)(Backup),共享虛擬 IP(VIP)。當(dāng)主節(jié)點(diǎn)故障時(shí),備用節(jié)點(diǎn)自動(dòng)接管 VIP,保證服務(wù)不中斷。
- 配置步驟:
安裝 Keepalived:
dnf install -y keepalived
主節(jié)點(diǎn)配置(/etc/keepalived/keepalived.conf):
global_defs {
router_id NGINX_MASTER
}
vrrp_instance VI_1 {
state MASTER
interface eth0 # 綁定網(wǎng)卡
virtual_router_id 51 # 虛擬路由ID(主從一致)
priority 100 # 主節(jié)點(diǎn)優(yōu)先級(jí)(備用節(jié)點(diǎn)設(shè)為90)
advert_int 1 # 心跳間隔(秒)
authentication {
auth_type PASS
auth_pass 123456
}
virtual_ipaddress {
192.168.10.200 # 虛擬IP
}
}備用節(jié)點(diǎn)配置:除state改為BACKUP、priority降低外,其余與主節(jié)點(diǎn)一致。
健康檢查腳本:在 Keepalived 中配置腳本檢測(cè) Nginx 進(jìn)程,若主節(jié)點(diǎn) Nginx 停止,自動(dòng)切換至備用節(jié)點(diǎn):
- bash
script_check_nginx.sh: #!/bin/bash if [ $(ps -C nginx --no-header | wc -l) -eq 0 ]; then systemctl stop keepalived fi
vrrp_script check_nginx {
script "/etc/keepalived/script_check_nginx.sh"
interval 2
}Nginx 集群(多節(jié)點(diǎn)負(fù)載均衡)
- 架構(gòu)說(shuō)明:部署多個(gè) Nginx 節(jié)點(diǎn),前端通過(guò) DNS 輪詢或硬件負(fù)載均衡器(如 F5)分發(fā)請(qǐng)求,避免單節(jié)點(diǎn)故障。
- 適用場(chǎng)景:高并發(fā)場(chǎng)景下,通過(guò)橫向擴(kuò)展 Nginx 節(jié)點(diǎn)提升整體處理能力。
(三)日志集中管理
ELK Stack 方案
組件說(shuō)明:
- Elasticsearch:存儲(chǔ)和檢索日志數(shù)據(jù)。
- Logstash:收集、過(guò)濾 Nginx 和 Tomcat 日志,并發(fā)送至 Elasticsearch。
- Kibana:可視化展示日志統(tǒng)計(jì)信息。
Nginx 日志輸出到 Logstash:
log_format json_log '{"time":"$time_iso8601",'
'"remote_addr":"$remote_addr",'
'"request":"$request",'
'"status":"$status",'
'"body_bytes_sent":"$body_bytes_sent",'
'"http_referer":"$http_referer",'
'"http_user_agent":"$http_user_agent"}';
access_log /usr/local/nginx/logs/access.json json_log;Logstash 配置:
input {
file {
path => "/usr/local/nginx/logs/access.json"
type => "nginx"
codec => json_lines
}
}
output {
elasticsearch {
hosts => ["192.168.10.106:9200"]
index => "nginx-%{+YYYY.MM.dd}"
}
}(四)自動(dòng)化部署與監(jiān)控
CI/CD 流程
使用 Jenkins 或 GitLab CI 實(shí)現(xiàn)代碼自動(dòng)構(gòu)建、測(cè)試和部署:
- 代碼提交至 Git 倉(cāng)庫(kù)后,Jenkins 拉取代碼并編譯 Java 項(xiàng)目。
- 打包 WAR 包并分發(fā)到所有 Tomcat 節(jié)點(diǎn)的
webapps目錄。 - 觸發(fā) Nginx 重新加載配置,確保新版本應(yīng)用生效。
Prometheus+Grafana 監(jiān)控
采集指標(biāo):
- Nginx:請(qǐng)求量、錯(cuò)誤率、響應(yīng)時(shí)間(通過(guò)
stub_status模塊)。 - Tomcat:線程池狀態(tài)、內(nèi)存使用、JSP 編譯耗時(shí)(通過(guò) JMX 接口)。
Prometheus 配置:
scrape_configs:
- job_name: "nginx"
static_configs:
- targets: ["192.168.10.103:80"]
- job_name: "tomcat"
static_configs:
- targets: ["192.168.10.101:8009", "192.168.10.102:8009"] # Tomcat JMX端口- Grafana 儀表盤:展示實(shí)時(shí)請(qǐng)求趨勢(shì)、服務(wù)器負(fù)載、錯(cuò)誤分布等圖表,設(shè)置告警規(guī)則(如請(qǐng)求錯(cuò)誤率超過(guò) 5% 時(shí)發(fā)送通知)。
九、成本優(yōu)化與性能對(duì)比
(一)硬件資源規(guī)劃
| 組件 | 最低配置(開(kāi)發(fā)環(huán)境) | 推薦配置(生產(chǎn)環(huán)境) |
|---|---|---|
| Nginx 服務(wù)器 | 2 核 CPU,4GB 內(nèi)存,50GB 磁盤 | 4 核 CPU,8GB 內(nèi)存,100GB SSD |
| Tomcat 服務(wù)器 | 2 核 CPU,4GB 內(nèi)存,100GB 磁盤 | 4-8 核 CPU,16GB 內(nèi)存,200GB SSD |
| 數(shù)據(jù)庫(kù)服務(wù)器 | 4 核 CPU,8GB 內(nèi)存,200GB 磁盤 | 8 核 CPU,32GB 內(nèi)存,500GB SSD |
(二)性能對(duì)比(壓測(cè)數(shù)據(jù)參考)
| 場(chǎng)景 | 單 Tomcat 節(jié)點(diǎn) | Nginx+Tomcat 集群(2 節(jié)點(diǎn)) |
|---|---|---|
| 靜態(tài)資源請(qǐng)求(RPS) | 5000+ | 10000+ |
| 動(dòng)態(tài) JSP 請(qǐng)求(RPS) | 800-1000 | 1500-2000 |
| 內(nèi)存占用 | 800MB-1.2GB | 每 Tomcat 節(jié)點(diǎn) 800MB-1.2GB,Nginx 200MB |
說(shuō)明:
- 靜態(tài)資源處理性能提升約 100%,得益于 Nginx 的高效緩存和 IO 模型。
- 動(dòng)態(tài)請(qǐng)求性能提升約 50%-100%,通過(guò)負(fù)載均衡分?jǐn)倝毫Σp少 Tomcat 的靜態(tài)資源處理開(kāi)銷。
十、總結(jié)與最佳實(shí)踐
(一)核心價(jià)值
- 動(dòng)靜分離:Nginx 專注靜態(tài)資源處理,Tomcat 專注動(dòng)態(tài)邏輯,提升整體效率。
- 負(fù)載均衡:通過(guò)多節(jié)點(diǎn) Tomcat 分?jǐn)偭髁?,避免單點(diǎn)故障,提升可用性。
- 高可擴(kuò)展性:可靈活增加 Nginx 或 Tomcat 節(jié)點(diǎn),適應(yīng)業(yè)務(wù)增長(zhǎng)。
(二)最佳實(shí)踐清單
開(kāi)發(fā)階段
啟用 Tomcat 的reloadable=true(僅開(kāi)發(fā)環(huán)境),方便代碼修改后自動(dòng)重啟。
使用 Nginx 的proxy_next_upstream配置,實(shí)現(xiàn)故障節(jié)點(diǎn)請(qǐng)求重試:
- nginx
proxy_next_upstream error timeout http_500;
生產(chǎn)階段
- 關(guān)閉 Tomcat 的自動(dòng)部署(
autoDeploy=false)和 WAR 包解壓(unpackWARs=false),避免未授權(quán)部署。 - 為 Nginx 和 Tomcat 配置統(tǒng)一的日志格式,便于集中分析(如 JSON 格式日志)。
維護(hù)階段
- 定期備份 Nginx 和 Tomcat 配置文件(如
nginx.conf、server.xml)。 - 制定應(yīng)急預(yù)案,包含節(jié)點(diǎn)故障切換、數(shù)據(jù)恢復(fù)等流程,定期進(jìn)行容災(zāi)演練。
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
通過(guò)nginx代理攔截請(qǐng)求進(jìn)行全局訪問(wèn)限制
這篇文章主要介紹了通過(guò)nginx代理攔截請(qǐng)求進(jìn)行全局訪問(wèn)限制,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-06-06
生產(chǎn)環(huán)境部署Nginx服務(wù)器雙機(jī)熱備部署keepalived的步驟(多種模式教程)
今天演示下生產(chǎn)環(huán)境keepalived的部署方式,安裝模式有很多,比如說(shuō)主備模型和雙主模型,主備分:搶占模式 和 非搶占模式,對(duì)Nginx keepalived 雙機(jī)熱備部署相關(guān)知識(shí)感興趣的朋友跟隨小編一起看看吧2024-07-07
使用nginx+tomcat實(shí)現(xiàn)靜態(tài)和動(dòng)態(tài)頁(yè)面的分離
這篇文章主要介紹了使用nginx+tomcat實(shí)現(xiàn)靜態(tài)和動(dòng)態(tài)頁(yè)面的分離,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧。2017-01-01
nginx php-fpm環(huán)境中chroot功能的配置使用方法
這篇文章主要介紹了nginx php-fpm環(huán)境中chroot功能的配置使用方法,此方法是比禁用PHP敏感函數(shù)更好的一個(gè)安全防護(hù)手手段,需要的朋友可以參考下2014-05-05
Nginx下支持Thinkphp URL Rewrite的配置示例
這篇文章主要介紹了Nginx下支持Thinkphp URL Rewrite的配置示例,本文直接給出配置示例,需要的朋友可以參考下2015-07-07
詳解nginx實(shí)現(xiàn)https網(wǎng)站設(shè)置
這篇文章主要介紹了詳解nginx實(shí)現(xiàn)https網(wǎng)站設(shè)置,詳細(xì)的介紹了HTTPS簡(jiǎn)介和證書生成等,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-06-06
利用nginx解決跨域問(wèn)題的方法(以flask為例)
這篇文章主要介紹了利用nginx解決跨域問(wèn)題的方法,文中以flask為例給大家介紹的很詳細(xì),需要的朋友可以參考學(xué)習(xí),下面來(lái)一起看看吧。2017-02-02

