Tomcat和负载均衡
后端 tomcat
Tomcat 的本质
Tomcat 本质上是一个 Servlet 容器,也可以称作一个轻量级 Web 应用服务器(Web Server + Servlet Container)。
它的主要职责是:
- 接收 HTTP 请求(内置了一个简单的 HTTP 服务器)
- 将请求分发给对应的 Web 应用(基于 URL 映射)
- 执行 Servlet / JSP 并生成响应
- 返回 HTTP 响应给客户端
换句话说,Tomcat 是一个 Java Web 应用运行环境,可以托管基于 Servlet、JSP、Spring MVC、Spring Boot(war 部署)等的应用。
运行原理
Tomcat 的核心工作流程可简化为以下几个步骤:
-
启动
加载
server.xml配置,启动各个Connector(监听端口,如 8080)初始化
Service、Engine、Host、Context组件创建并初始化
Servlet 容器 -
接收请求
Connector监听 HTTP 请求(基于 NIO/线程池)请求被封装为
Request对象 -
请求分发
Mapper根据 URL → 找到对应的Context(即某个 Web 应用)找到对应的
Wrapper(某个 Servlet) -
执行 Servlet
Tomcat 调用 Servlet 的
service()方法Servlet 处理请求,可能访问数据库或调用其他 API
返回
Response对象 -
响应客户端
Tomcat 将
Response转换为 HTTP 响应报文通过 Socket 返回给客户端浏览器
主要配置文件
Tomcat 的核心配置文件主要有:
| 文件 | 作用 |
|---|---|
conf/server.xml | Tomcat 的主配置文件,定义 Connector(端口、协议)、Engine、Host、Context等 |
conf/web.xml | 全局的 Web 应用默认配置(比如默认的 MIME 映射、默认 Servlet) |
context.xml | 定义 Web 应用级别的配置,如数据源(JNDI)、Session 配置 |
tomcat users.xml | 用户、角色和安全相关配置,用于 Manager App、Admin Console登录 |
应用内的 WEB-INF/web.xml | 每个 Web 应用自己的 Servlet、Filter、Listener 配置 |
调用应用接口
当你的应用部署到 Tomcat 中时,Tomcat 会:
- 在启动时加载你的 web.xml 或注解(如 @WebServlet )
- 创建并初始化 Servlet
- 当有 HTTP 请求时,将请求参数封装成
HttpServletRequest - 调用你的 Servlet 或框架(如 Spring MVC 的 DispatcherServlet)
- 你的业务代码处理完成后返回
HttpServletResponse
也就是说,Tomcat 并不关心业务逻辑,只负责把请求转给你的代码执行。
调用数据库接口
Tomcat 提供了 JNDI 数据源 支持,让应用能复用数据库连接池:
1,配置数据源
在 context.xml 或某个应用的 META-INF/context.xml :
<Resource name="jdbc/MyDB"
auth="Container"type="javax.sql.DataSource"maxActive="20"maxIdle="10"maxWait="10000"username="root"password="123456"driverClassName="com.mysql.cj.jdbc.Driver"url="jdbc:mysql://localhost:3306/test"/>
2, 应用代码获取数据源
Context initCtx = new InitialContext();DataSource ds = (DataSource) initCtx.lookup("java:comp/env/jdbc/MyDB");Connection conn = ds.getConnection();// 执行 SQL ...
这样做的好处:
- 连接池由 Tomcat 管理,性能更好
- 数据源配置与应用解耦,方便运维
部署 tomcat
1,关闭防火墙 与增强功能
systemctl stop firewalld
setenforce 0
2,配置环境
jdk依赖环境
首先下载安装包 然后再上传并解压(解压完之后配置环境变量即可)。
tar zxvf jdk-8u91-linux-x64.tar.gz -C /usr/local/
vim /etc/profile #这是配置JDK
export JAVA_HOME=/usr/local1/jdk1.8.0_91export JRE_HOME=${JAVA_HOME}/jreexport CLASSPATH=.:${JAVA_HOME}/lib:${JRE_HOME}/libexport PATH=${JAVA_HOME}/bin:$PATH
source /etc/profile #刷新 使环境变量生效
查看有没有安装好开发环境
java -version
显示结果:
openjdk version "1.8.0_181" #显示JDK1.8OpenJDK Runtime Environment (build 1.8.0_181-b13)OpenJDK 64-Bit Server VM (build 25.181-b13, mixed mode)
安装 tomcat
首先下载安装包 然后再上传并解压
tar zxvf apache-tomcat-8.5.16.tar.gz
#将tomcat文件移动到/usr/local,同时重命名为tomcat
mv /opt/apache-tomcat-8.5.16/ /usr/local/tomcat #启动tomcat
/usr/local/tomcat/bin/shutdown.sh # 关闭
/usr/local/tomcat/bin/startup.sh # 启动 #查看端口
netstat -ntap | grep 8080
#或者
netstat -ntap | grep java
总结
- 本质:Tomcat 是 Java Web 应用的运行容器,负责接收 HTTP 请求、调用 Servlet、返回响应
- 原理:Connector 监听请求 → Mapper 分发 → Servlet 执行 → 返回响应
- 配置文件:server.xml(端口、Host)、web.xml(全局)、context.xml(数据源)、tomcat users.xml(用户)
- 应用接口调用:Tomcat 把请求交给你的 Servlet/框架
- 数据库接口调用:通过 JNDI 数据源或自己管理 JDBC 连接
补充:Tomcat目录文件详解
[root@localhost tomcat]# ls -l
total 92
drwxr-x---. 2 root root 4096 Mar 30 15:36 bin
drwx------. 3 root root 254 Mar 30 15:36 conf
drwxr-x---. 2 root root 4096 Mar 30 15:36 lib
-rw-r-----. 1 root root 57092 Jun 22 2017 LICENSE
drwxr-x---. 2 root root 197 Mar 30 15:36 logs
-rw-r-----. 1 root root 1723 Jun 22 2017 NOTICE
-rw-r-----. 1 root root 7064 Jun 22 2017 RELEASE-NOTES
-rw-r-----. 1 root root 15946 Jun 22 2017 RUNNING.txt
drwxr-x---. 2 root root 30 Mar 30 15:36 temp
drwxr-x---. 7 root root 81 Jun 22 2017 webapps
drwxr-x---. 3 root root 22 Mar 30 15:36 work
- bin :启动和关闭Tomcat脚本文件
- conf:存放Tomcat服务器各种配置文件
- lib :Tomcat服务器的jar包
- logs:Tomcat日志
- temp:Tomcat运行时产生的文件
- webapps:项目资源的目录
- work:Tomcat工作目录
补充:Tomcat配置文件详解
[root@localhost conf]# ls -l
total 224
drwxr-x---. 3 root root 23 Mar 30 15:36 Catalina
-rw-------. 1 root root 13816 Jun 22 2017 catalina.policy
-rw-------. 1 root root 7376 Jun 22 2017 catalina.properties
-rw-------. 1 root root 1338 Jun 22 2017 context.xml
-rw-------. 1 root root 1149 Jun 22 2017 jaspic-providers.xml
-rw-------. 1 root root 2358 Jun 22 2017 jaspic-providers.xsd
-rw-------. 1 root root 3622 Jun 22 2017 logging.properties
-rw-------. 1 root root 7511 Jun 22 2017 server.xml
-rw-------. 1 root root 2164 Jun 22 2017 tomcat-users.xml
-rw-------. 1 root root 2633 Jun 22 2017 tomcat-users.xsd
-rw-------. 1 root root 168251 Jun 22 2017 web.xml
- catalina.policy:权限控制配置文件
- catalina.properties:Tomcat的属性配置文件
- context.xml:上下文配置文件
- logging.properties:日志相关配置文件
- server.xml:主配置文件,通过配置文件,可以修改tomcat的启动端口、网站目录、虚拟主机、开启https等功能
- tomcat-user.xml/.xsd:管理用户配置文件
制配置文件 - web.xml:Tomcat的servlet、servlet-mapping、filter、MIME等相关配置
部署反向代理与负载均衡
1,规划部署负载均衡和反向代理
- Nginx 服务器:192.168.37.133:80
- Tomcat服务器1:192.168.37.134:8080
- Tomcat服务器2:192.168.37.135:8080
2,部署Nginx 负载均衡器
注意:如果前面部署过 这边就不需要再操作了
systemctl stop firewalldsetenforce 0yum -y install pcre-cdevel zlib-devel openssl-devel gc gcc-c++ makeuseradd -M -s /sbin/nologin nginxcd /opttar zxvf nginx-1.20.2.tar.gz -C /opt/cd nginx-1.20.2/./configure \--prefix=/usr/local/nginx \--user=nginx \--group=nginx \--with-file-aio \ #启用文件修改支持 --with-http_stub_status_module \ #启用状态统计
--with-http_gzip_static_module \ #启用 g
zip静态压缩
--with-http_flv_module \ #启用 flv模块,提供对 flv 视频的伪流支持
--with-http_ssl_module #启用 SSL模块,提供SSL加密功能
--with-stream #启用 stream模块,提供4层调度 make && make installln -s /usr/local/nginx/sbin/nginx /usr/local/sbin/vim /lib/systemd/system/nginx.service
文件内容:
[Unit]Description=nginxAfter=network.target[Service]Type=forkingPIDFile=/usr/local/nginx/logs/nginx.pidExecStart=/usr/local/nginx/sbin/nginxExecrReload=/bin/kill -s HUP $MAINPIDExecrStop=/bin/kill -s QUIT $MAINPIDPrivateTmp=true[Install]WantedBy=multi-user.target
chmod 754 /lib/systemd/system/nginx.servicesystemctl start nginx.service #立即启动 Nginx 服务systemctl enable nginx.service #仅设置开机自启,不会立即启动服务
3, 部署后端2台Tomcat 应用服务器
systemctl stop firewalldsetenforce 0source /etc/profiletar zxvf jdk-8u91-linux-x64.tar.gz -C /usr/local/vim /etc/profileexport JAVA_HOME=/usr/local1/jdk1.8.0_91export JRE_HOME=${JAVA_HOME}/jreexport CLASSPATH=.:${JAVA_HOME}/lib:${JRE_HOME}/libexport PATH=${JAVA_HOME}/bin:$PATHtar zxvf apache-tomcat-8.5.16.tar.gzmv /opt/apache-tomcat-8.5.16/ /usr/local/tomcat/usr/local/tomcat/bin/shutdown.sh #关闭/usr/local/tomcat/bin/startup.sh #开启netstat -ntap | grep 8080第二台同理
4,动静分离配置
Tomcat1 server 配置
mkdir /usr/local/tomcat/webapps/testvim /usr/local/tomcat/webapps/test/index.jsp<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%><html><head><title>JSP test1 page</title> #指定为 test1 页面
</head><body><% out.println("动态页面 1,http://www.test1.com");%></body></html>vim /usr/local/tomcat/conf/server.xml#由于主机名 name 配置都为 localhost,需要删除前面的 HOST 配置<Host name="localhost" appBase="webapps" unpackWARs="true" autoDeploy="true"
xmlValidation="false" xmlNamespaceAware="false"><Context docBase="/usr/local/tomcat/webapps/test" path="" reloadable="true"></Context></Host>/usr/local/tomcat/bin/shutdown.sh /usr/local/tomcat/bin/startup.sh
Tomcat2 server 配置
mkdir /usr/local/tomcat/tomcat1/webapps/test vim /usr/local/tomcat/webapps/test/index.jsp<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%><html><head><title>JSP test2 page</title> #指定为 test2 页面
</head><body><% out.println("动态页面 2,http://www.test2.com");%></body></html>vim /usr/local/tomcat/tomcat1/conf/server.xml#删除前面的 HOST 配置<Host name="localhost" appBase="webapps" unpackWARs="true" autoDeploy="true" xmlValidation="false" xmlNamespaceAware="false"><Context docBase="/usr/local/tomcat/tomcat1/webapps/test" path=""
reloadable="true" /></Host>/usr/local/tomcat/bin/shutdown.sh /usr/local/tomcat/bin/startup.sh
Nginx server 配置
#准备静态页面和静态图片
echo '<html><body><h1>这是静态页面</h1></body></html>' > /usr/local/nginx/html/index.html
mkdir /usr/local/nginx/html/img
cp /root/game.jpg /usr/local/nginx/html/imgvim /usr/local/nginx/conf/nginx.conf......http {......#gzip on;#配置负载均衡的服务器列表,weight参数表示权重,权重越高,被分配到的概率越大upstream backend {server 192.168.37.134:8080 weight=1;server 192.168.37.135:8081 weight=1;}server {listen 80;server_name localhost;charset utf-8;#access_log logs/host.access.log main;#配置Nginx处理动态页面请求,将 .jsp文件请求转发到Tomcat 服务器处理location ~ .*\.(jsp|php)$ {proxy_pass http://backend;#设置后端的Web服务器可以获取远程客户端的真实IP##设定后端的Web服务器接收到的请求访问的主机名(域名或IP、端口),默认HOST的值为proxy_pass指令设置的主机名。如果反向代理服务器不重写该请求头的话,那么后端真实服务器在处理时会认为所有的请求都来在反向代理服务器,如果后端有防攻击策略的话,那么机器就被封掉了。proxy_set_header HOST $host;
##把$remote_addr赋值给X-Real-IP,来获取源IPproxy_set_header X-Real-IP $remote_addr;##在nginx 作为代理服务器时,设置的IP列表,会把经过的机器ip,代理机器ip都记录下来proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;}#配置Nginx处理静态图片请求location ~ .*\.(gif|jpg|jpeg|png|bmp|swf|css)$ {root /usr/local/nginx/html/img;expires 10d;}location / {root html;index index.html index.htm;}......}......}
测试效果
测试静态页面效果 浏览器访问 http://192.168.37.133/
浏览器访问 http://192.168.37.133/game.jpg
测试负载均衡效果,不断刷新浏览器测试
浏览器访问 http://192.168.37.133/index.jsp
