Nginx+tomcat集群
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