Nginx+tomcat集群
一、Nginx 簡介
1.1 定義
Nginx 是一個高性能的 HTTP 和反向代理 web 服務器,同時支持 IMAP/POP3/SMTP 服務。由俄羅斯工程師伊戈爾?賽索耶夫開發,于 2004 年首次公開發布,基于 BSD-like 協議,代碼開源且免費使用 。
1.2 核心功能
-
反向代理:作為反向代理服務器,接收客戶端請求,轉發至后端 Tomcat 服務器集群,并將響應返回客戶端,隱藏后端服務器真實 IP,提升安全性。
-
負載均衡:后端存在多臺服務器時,依據輪詢、加權輪詢、IP 哈希等算法,將請求均勻分配,避免單臺服務器負載過高,增強系統性能與可用性。
-
靜態資源處理:高效處理 HTML、CSS、JavaScript、圖片等靜態資源,直接返回客戶端,減輕后端服務器壓力。
-
緩存:支持靜態資源與動態內容緩存,緩存命中時直接返回,降低后端處理壓力,加快響應速度。
-
高并發處理:采用異步非阻塞的事件驅動架構,能在低資源消耗下支持大量并發連接,從容應對高流量場景。
1.3 應用場景
常用于 Web 服務器、反向代理服務器、負載均衡器,廣泛應用于高并發網站、API 網關、微服務架構。如電商大促時,保障大量用戶請求的穩定處理 。
二、Tomcat 簡介
2.1 定義
Tomcat 是 Apache 軟件基金會 Jakarta 項目的核心,由 Apache、Sun 等多方共同開發,是免費開源的 Web 應用服務器,屬于輕量級服務器,適用于中小型系統及并發用戶較少的場景,是開發調試 JSP 程序的首選。
2.2 核心功能
-
Servlet 容器:實現 Servlet 規范,運行 Java 編寫的 Servlet 程序,處理客戶端請求并生成動態響應。
-
JSP 引擎:支持 JSP 技術,將嵌入 HTML 的 Java 代碼編譯成 Servlet 執行,生成動態網頁。
-
Web 應用部署:支持將 Web 應用打包為 WAR 文件,部署后自動解壓運行。
-
會話管理:跟蹤用戶在 Web 應用中的會話狀態,如保存登錄信息、購物車內容,實現用戶個性化功能。
2.3 應用場景
主要用于運行基于 Java 的 Web 應用程序,如企業級 Web 應用、Java Web 開發測試環境。常見于企業內部管理系統、在線教育平臺后端服務。
三、Nginx+Tomcat 集群的作用
3.1 提升系統性能和可用性
Nginx 通過負載均衡將請求分配到多臺 Tomcat 服務器,充分利用資源,防止單臺服務器性能下降或崩潰。部分 Tomcat 故障時,Nginx 將請求轉發至正常服務器,保障系統可用。
3.2 實現高并發處理
Nginx 的高并發處理能力與 Tomcat 的動態內容處理能力結合,應對大規模并發請求。Nginx 處理靜態資源請求與分發動態請求,Tomcat 處理動態業務邏輯,提升高并發場景下的響應與處理能力。
3.3 便于系統擴展和維護
業務增長時,可輕松添加 Tomcat 服務器到集群,Nginx 自動分配請求。維護、升級單臺 Tomcat 時,將其從負載均衡列表移除,不影響系統運行,降低維護難度與風險。
四、Nginx+Tomcat 集群配置示例
環境準備
-
安裝 Nginx:根據操作系統,使用包管理器(如 Linux 系統的 apt、yum)安裝。
-
安裝 Tomcat:下載 Tomcat 安裝包,解壓到指定目錄,配置 Java 環境變量,啟動測試。
主機 | 描述 |
---|---|
192.168.10.101 | tomcat |
192.168.10.102 | tomcat |
192.168.10.103 | nginx |
同網段 | 客戶端 |
tomcat安裝和使用
Tomcat 是基于 Java 語言開發的 Web 應用服務器,它的運行和功能實現高度依賴 Java 環境,所以安裝 Tomcat 前必須先安裝 Java
###在兩臺tomcat主機上操作
[root@tomcat ~]# dnf -y install java
###把我們的tomcat文件上傳到主機上進行解壓縮
[root@tomcat ~]# ls
anaconda-ks.cfg apache-tomcat-9.0.8.tar.gz
[root@tomcat ~]# tar xf apache-tomcat-9.0.8
[root@tomcat ~]# mv apache-tomcat-9.0.8 /usr/local/tomcat ###將tomcat移動到/usr/local/tomcat下
[root@tomcat ~]# cd /usr/local/tomcat/
[root@tomcat tomcat]# ls
bin conf lib LICENSE logs NOTICE RELEASE-NOTES RUNNING.txt temp webapps work
Tomcat 目錄結構及功能解析
一、核心執行目錄:bin
- 功能:存放 Tomcat 的可執行腳本和批處理文件
- 關鍵文件
startup.sh
(Linux/Mac)/startup.bat
(Windows):啟動 Tomcat 服務shutdown.sh
(Linux/Mac)/shutdown.bat
(Windows):關閉 Tomcat 服務catalina.sh
:核心腳本,封裝 Tomcat 啟動、停止的底層邏輯version.sh
:查看 Tomcat 版本信息configtest.sh
:驗證配置文件是否正確
二、配置文件目錄:conf
- 功能:存放 Tomcat 的核心配置文件,決定服務器運行行為
- 關鍵文件
server.xml
:Tomcat 主配置文件,定義服務器組件(如 Connector、Service、Engine)、端口號、虛擬主機等web.xml
:全局 Web 應用配置文件,定義 MIME 類型、會話超時、安全約束等標準配置tomcat-users.xml
:用戶認證配置文件,定義管理后臺的用戶名、密碼和角色權限context.xml
:全局上下文配置文件,定義數據源(DataSource)、資源鏈接等server-status.xml
:狀態監控配置(部分版本存在)logging.properties
:日志配置文件,定義日志級別、輸出格式和存儲位置
三、依賴庫目錄:lib
- 功能:存放 Tomcat 運行所需的核心 jar 包及依賴庫
- 關鍵文件
catalina.jar
:Tomcat 核心框架,包含服務器啟動和組件管理的類tomcat-coyote.jar
:實現 HTTP 通信協議的組件tomcat-jasper.jar
:JSP 引擎,負責將 JSP 編譯為 Servletservlet-api.jar
:Servlet 規范接口定義(Tomcat 10 + 為 jakarta.servlet-api.jar)el-api.jar
:表達式語言(EL)接口定義jasper-el.jar
:JSP 表達式語言實現- 其他依賴:如日志庫(log4j、juli)、JDBC 驅動等
四、許可證與說明文件
LICENSE
:Tomcat 開源許可證(Apache License 2.0)NOTICE
:版權聲明和貢獻者信息RELEASE-NOTES
:版本更新說明,記錄各版本新增功能和修復內容RUNNING.txt
:快速啟動指南,包含基本啟動命令和常見問題提示
五、運行時數據目錄:logs
- 功能:存放 Tomcat 運行時產生的日志文件
- 關鍵文件
catalina.out
(Linux/Mac)/catalina.log
(Windows):主日志文件,記錄服務器啟動、錯誤和運行狀態localhost_access_log.*.txt
:HTTP 訪問日志,記錄客戶端請求的 URL、IP、響應狀態等manager.log
:管理后臺操作日志host-manager.log
:主機管理后臺操作日志stderr.log
:標準錯誤輸出日志stdout.log
:標準輸出日志
六、臨時文件目錄:temp
- 功能:存放 Tomcat 運行時產生的臨時文件
- 特點
- 內容可定期清理,不影響服務器運行
- 包含 JSP 編譯臨時文件、緩存數據等
七、Web 應用部署目錄:webapps
- 功能:存放部署的 Web 應用程序
- 使用方式
- 直接放置 WAR 包(如
app.war
),Tomcat 啟動時自動解壓 - 放置解壓后的應用目錄(如
app/WEB-INF/
結構)
- 直接放置 WAR 包(如
- 默認應用
docs/
:Tomcat 官方文檔examples/
:Web 應用示例(包含 Servlet、JSP 演示)host-manager/
:主機管理后臺(需配置權限)manager/
:應用管理后臺(需配置權限)ROOT/
:默認根應用(訪問域名時直接指向此應用)
八、工作目錄:work
-
功能:存放 Tomcat 運行時生成的編譯文件和緩存數據
-
關鍵內容
-
Catalina/
:存儲與虛擬主機相關的編譯結果
localhost/
:存放localhost主機的 JSP 編譯后的 Servlet 類- 其他虛擬主機目錄(如根據
server.xml
配置生成)
-
JSP 編譯文件:如
HelloWorld_jsp.class
,由 JSP 動態編譯生成 -
緩存數據:如 Session 序列化數據(若啟用分布式會話)
-
啟動tomcat
[root@tomcat2 bin]# . startup.sh ###啟動tomcat
Using CATALINA_BASE: /usr/local/tomcat
Using CATALINA_HOME: /usr/local/tomcat
Using CATALINA_TMPDIR: /usr/local/tomcat/temp
Using JRE_HOME: /usr
Using CLASSPATH: /usr/local/tomcat/bin/bootstrap.jar:/usr/local/tomcat/bin/tomcat-juli.jar
Tomcat started.
[root@localhost ~]# curl -I 192.168.10.102:8080 ###curl方式訪問并返回狀態碼200為ok 可以使用windows頁面訪問看的更加直觀
HTTP/1.1 200
Content-Type: text/html;charset=UTF-8
Transfer-Encoding: chunked
Date: Mon, 07 Apr 2025 07:33:47 GMT
搭建自己的web
在兩臺tomcat上操在
[root@tomcat1 ~]# mkdir -p /web/webapp1
[root@tomcat1 ~]# cd /web/webapp1/
[root@tomcat1 webapp1]# vim index.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<html>
<head><title>JSP test1 page</title>
</head>
<body><% out.println("動態頁面 1,http://www.test2.com");%>
</body>
<body><div>動態頁面的圖片 1</div><br>< img src="logo.png"> ####這個會在nginx上顯示這個圖片并沒有放在tomcat服務上
</body>
</html>
[root@tomcat1 webapp1]# /usr/local/tomcat/bin/startup.sh
編輯tomcat的配置文件
root@tomcat1 webapp1]# vim /usr/local/tomcat/conf/server.xml ###在150行找到這行添加我們自己的網站<Host name="localhost" appBase="webapps"unpackWARs="true" autoDeploy="true"><Context docBase="/web/webapp1" path="" />
###重啟服務
客戶端訪問兩臺tomcat
root@localhost ~]# curl -I 192.168.10.101:8080
HTTP/1.1 200
Set-Cookie: JSESSIONID=4381D25585CEEDCE4C9C2335E13BA6C0; Path=/; HttpOnly
Content-Type: text/html;charset=UTF-8
Transfer-Encoding: chunked
Date: Mon, 07 Apr 2025 08:19:01 GMT
配置nginx反向代理負載均衡動靜分離
[root@nginx ~]# dnf -y install gcc pcre-devel zlib-devel
###安裝依賴環境
[root@nginx ~]# tar xf nginx-1.26.3.tar.gz ###解壓縮安裝包
[root@nginx nginx-1.26.3]# ./configure -- prefix=/usr/local/nginx/ --user=nginx --group=nginx
[root@nginx sbin]# useradd -M -s /sbin/nologin nginx
[root@nginx sbin]# vim /usr/local/nginx/conf/nginx.conf
# 定義 Tomcat 服務器集群,名為 my_tomcat
upstream my_tomcat {# 第一臺后端服務器,權重為 1(接收 1/3 的請求)server 192.168.10.101:8080 weight=1;# 第二臺后端服務器,權重為 2(接收 2/3 的請求)server 192.168.10.102:8080 weight=2;# 默認負載均衡算法為輪詢(round-robin),結合權重按比例分發請求
}# 虛擬主機配置,監聽 80 端口
server {listen 80;server_name localhost; # 響應的域名,此處為本地測試charset utf-8; # 設置響應字符集為 UTF-8,防止中文亂碼# 根路徑請求處理(靜態文件)location / {root html; # 靜態文件根目錄(相對于 Nginx 安裝路徑)index index.html index.htm; # 默認索引文件列表}# 正則匹配所有 .jsp 結尾的請求(動態請求)location ~ .*\.jsp$ {# 設置代理請求的 Host 頭為原始請求的主機名proxy_set_header HOST $host;# 將請求轉發到上游 Tomcat 集群proxy_pass http://my_tomcat;# 缺少的關鍵配置(建議添加):# proxy_set_header X-Real-IP $remote_addr; # 傳遞客戶端真實 IP# proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; # 保留完整的客戶端 IP 鏈# proxy_set_header X-Forwarded-Proto $scheme; # 傳遞原始請求協議(HTTP/HTTPS)# proxy_connect_timeout 30s; # 連接超時時間# proxy_read_timeout 60s; # 讀取響應超時時間}
}
客戶端訪問nginx
[root@localhost ~]# curl -I 192.168.10.103/index.jsp
HTTP/1.1 200
Server: nginx/1.26.3
Date: Mon, 07 Apr 2025 11:15:35 GMT
Content-Type: text/html;charset=UTF-8
Connection: keep-alive
優化日志可以看到真實客戶端的ip
我們查看tomcat的訪問日志是看不到真實客戶端的ip地址因為都是通過nginx代理客戶端訪問tomcat我們需要修改nginx配置把真實客戶端的ip地址返還給tomcat
查看tomcat訪問日志
[root@tomcat1 logs]# cat localhost_access_log.2025-04-07.txt
192.168.10.103 - - [07/Apr/2025:19:14:52 +0800] "GET /index.jsp HTTP/1.0" 200 208
192.168.10.103 - - [07/Apr/2025:19:14:52 +0800] "GET /index.jsp HTTP/1.0" 200 208
192.168.10.103 - - [07/Apr/2025:19:14:52 +0800] "GET /index.jsp HTTP/1.0" 200 208
編輯nginx配置文件
[root@nginx logs]# vim /usr/local/nginx/conf/nginx.conf# 匹配所有以.jsp結尾的請求
location ~ .*\.jsp$ {# 設置請求頭HOST為原始請求的域名,確保后端應用獲取正確的主機信息proxy_set_header HOST $host;# 兼容舊系統,設置客戶端IPproxy_set_header Client-IP $remote_addr;# 設置真實客戶端IP,常用于日志記錄和訪問控制proxy_set_header X-Real-IP $remote_addr;# 傳遞客戶端真實IP及經過的代理服務器IP列表,格式為"客戶端IP, 代理1IP, 代理2IP..."proxy_set_header X-Forward-For $proxy_add_x_forwarded_for;# 將請求轉發到名為my_tomcat的上游服務器組(通常是Tomcat應用服務器)proxy_pass http://my_tomcat;
}
編輯tomcat配置文件
[root@tomcat1 logs]# vim /usr/local/tomcat/conf/server.xml <!-- 配置Tomcat訪問日志記錄 -->
<Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs" <!-- 日志文件存儲目錄(相對于CATALINA_BASE) -->prefix="localhost_access_log" <!-- 日志文件名前綴 -->suffix=".txt" <!-- 日志文件名后綴 -->pattern="%{X-Real-IP}i %h %l %u %t "%r" %s %b" /><!-- 日志格式模式:%{X-Real-IP}i - 記錄X-Real-IP請求頭(即客戶端真實IP,通過Nginx傳遞)%h - 遠程主機名(或IP,如果DNS查找被禁用)%l - 遠程邏輯用戶名(始終為'-',因為未實現)%u - 認證后的遠程用戶(未認證則為'-')%t - 請求時間(格式:[日期時間])"%r" - 請求的第一行(包含方法、URI和協議)%s - HTTP狀態碼%b - 響應字節數(不包含頭部) -->
客戶端再次訪問nginx
[root@localhost ~]# curl -I 192.168.10.103/index.jsp
HTTP/1.1 200
Server: nginx/1.26.3
Date: Mon, 07 Apr 2025 12:13:38 GMT
Content-Type: text/html;charset=UTF-8
Connection: keep-alive
Set-Cookie: JSESSIONID=C3004E3F6925E4C2A3C4F43BE2818682; Path=/; HttpOnly
查看tomcat日志
[root@tomcat1 logs]# cat localhost_access_log.2025-04-07.txt xxxxxxxxxx [root@tomcat1 logs]# cat localhost_access_log.2025-04-07.txt
192.168.10.104 192.168.10.103 - - [07/Apr/2025:19:28:26 +0800] "HEAD /index.jsp HTTP/1.0" 200 -
192.168.10.104 192.168.10.103 - - [07/Apr/2025:19:28:27 +0800] "HEAD /index.jsp HTTP/1.0" 200