3. Tomcat 的文件结构和组成
3.1 目录结构
目录 | 说明 |
---|---|
bin | 服务启动, 停止等相关程序和文件 |
conf | 配置文件 |
lib | 库目录 |
logs | 日志目录 |
webapps | 应用程序, 应用部署目录 |
work | jsp编译后的结果文件, 建议提前预热访问 |
work目录:
存放编译后的class和servlet文件, 将来访问网站后生成的页面都放在这里. 客户访问的jsp页面都是通过java类来实现的, 最后会通过jsp转换成servlet对应的类, servlet转换成类后, 再转换成class文件, 生成的中间字节码就会放在work目录. 类似于缓存, 下次在访问同一个页面, 就没有必要再把源码转换成class了, 可以直接利用字节码.
注意: 软件更新后, 一定要更新work目录的缓存, 否则用户访问的还是旧版的程序
└── work
└── Catalina
└── localhost
├── docs
├── examples
├── host-manager
├── manager
└── ROOT
conf目录:
存放tomcat配置文件
[20:25:07 root@201 ~]#ls /usr/local/tomcat/conf/
Catalina catalina.properties jaspic-providers.xml logging.properties tomcat.conf tomcat-users.xsd
catalina.policy context.xml jaspic-providers.xsd server.xml tomcat-users.xml web.xml
webapps目录:
存放java应用程序, 应用部署目录
[20:27:13 root@201 ~]#ls /usr/local/tomcat/webapps/
docs examples host-manager manager ROOT
3.2 配置文件
3.2.1 配置文件说明
server.xml: 主配置文件, xml格式, 存放在$CATALINA_BASE/conf下. 其中tomcat日志的格式和存放路径是定义在这里的(vales.AccessLogValue).
[21:25:47 root@201 ~]#vim /usr/local/tomcat/conf/server.xml
...
<Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
prefix="localhost_access_log" suffix=".txt"
pattern="%h %l %u %t "%r" %s %b" />
...
web.xml: 对应每一个app, 在tomcat中, 会认为每一个webapps下的目录都是对应一个app, 一个功能模块, 比如, 一个app和商品有关, 另一个和用户登录有关. 每个目录有可能有自己独立的设置, 那么就可以单独在每个app目录下单独建立一个web.xml来控制每个app的功能和设置. 如果是所有app共用的设置, 可以放在tomcat/conf/web.xml下. 如果是每个app单独的设置, 一般放在, $CATALINA_BASE/webapps/APP/WEB-INF下. 可以将/usr/local/tomcat/webapps/ROOT/WEB-INF/web.xml文件, 拷贝到对应APP/WEB-IN目录下, 保留基本格式, 再做单独的修改
context.xml: 定义目录映射关系, 设定某一个文件夹和一个磁盘文件夹的对应关系. conf/context.xml是全局配置, 也可以对每个app进行单独的配置.如果是每个app单独的设置, 一般放在, $CATALINA_BASE/webapps/APP/WEB-INF下.
注意: 配置文件大小写敏感
3.2.2 日志文件
[20:52:34 root@201 ~]#ls /usr/local/tomcat/logs -l
total 44
-rw-r----- 1 tomcat tomcat 19262 Nov 1 20:12 catalina.2020-11-01.log #tomcat服务日志
-rw-r----- 1 tomcat tomcat 19262 Nov 1 20:12 catalina.out #tomcat服务日志
-rw-r----- 1 tomcat tomcat 0 Nov 1 20:09 host-manager.2020-11-01.log #host manager管理日志
-rw-r----- 1 tomcat tomcat 1377 Nov 1 20:12 localhost.2020-11-01.log #默认主机服务日志
-rw-r----- 1 tomcat tomcat 0 Nov 1 20:09 localhost_access_log.2020-11-01.txt #默认主机访问日志
-rw-r----- 1 tomcat tomcat 0 Nov 1 20:09 manager.2020-11-01.log #manager 管理日志
- 日志格式定义:
[21:25:47 root@201 ~]#vim /usr/local/tomcat/conf/server.xml
...
<Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
prefix="localhost_access_log" suffix=".txt"
pattern="%h %l %u %t "%r" %s %b" />
...
# 默认格式
[21:28:14 root@201 /usr/local/tomcat/logs]#cat localhost_access_log.2021-03-21.txt
10.0.0.1 - - [21/Mar/2021:21:28:06 +0800] "GET / HTTP/1.1" 200 11215
10.0.0.1 - - [21/Mar/2021:21:28:06 +0800] "GET /tomcat.css HTTP/1.1" 200 5581
10.0.0.1 - - [21/Mar/2021:21:28:06 +0800] "GET /tomcat.png HTTP/1.1" 200 5103
10.0.0.1 - - [21/Mar/2021:21:28:06 +0800] "GET /bg-nav.png HTTP/1.1" 200 1401
10.0.0.1 - - [21/Mar/2021:21:28:06 +0800] "GET /bg-button.png HTTP/1.1" 200 713
10.0.0.1 - - [21/Mar/2021:21:28:06 +0800] "GET /bg-middle.png HTTP/1.1" 200 1918
10.0.0.1 - - [21/Mar/2021:21:28:06 +0800] "GET /bg-upper.png HTTP/1.1" 200 3103
10.0.0.1 - - [21/Mar/2021:21:28:06 +0800] "GET /asf-logo-wide.svg HTTP/1.1" 200 27235
10.0.0.1 - - [21/Mar/2021:21:28:06 +0800] "GET /favicon.ico HTTP/1.1" 200 21630
通常情况下,为便于分析网站瓶颈,可以将pattern修改为以下格式,其中D代表处理该请求所消耗的毫秒数,如此可以方便找到问题,提高系统性能。
pattern="%h %l %u %t "%r" %s %b %D" />
10.0.0.203 - - [01/Nov/2020:21:33:51 +0800] "GET / HTTP/1.1" 200 11215 258
为了便于日期统计, 也可以将日志以数字格式显示, 修改pattern为以下格式
pattern="%h %l %u %{Y-MM-d H:mm:s}t "%r" %s %b %D" />
10.0.0.203 - - 2020-11-1 21:40:25 "GET / HTTP/1.1" 200 11215 354
3.3 组件
3.3.1 组件分层和分类
- 顶级组件:
Server, 代表整个Tomcat容器, 一台主机可以启动多个Tomcat实例, 需要确保端口不冲突
- 服务类组件
Service, 实现组织Engine和Connector, 建立两者之间关联关系, Service里面只能包含一个Engine
- 连接器组件
Connector, 有HTTP(默认端口8080/tcp), HTTPS(默认端口443/tcp), AJP(默认端口8009/tcp)协议的连接器, AJP(Apache Jserv protocol)是一种基于TCP的二进制通讯协议, 管理端口(默认为8005端口), 执行shutdown命令
- 容器类
Engine, Host(虚拟主机), Context(上下文, 解决路径映射)都是容器类组件, 可以嵌入其他组件, 内部配置如何运行应用程序
- 内嵌类
可以内嵌到其他组件内, valve, logger, realm, loader, manager等. 以logger举例, 在不同容器组件内分别定义
- 集群类组件
listener, cluster
3.3.2 Tomcat内部构成
Server: 服务器, Tomcat运行的进程实例, 一个Server中可以有多个Service, 但通常就一个
Service: 服务, 用来组织Engine和Connector的对应关系, 一个Service中只有一个Engine
Connector: 连接器, 负责客户端的HTTP, HTTPS, AJP等协议连接, 一个Connector只属于某一个Engine
Engine: 即引擎, 用来响应并处理用户请求. 一个Engine上可以绑定多个Connector, 一个Engine上可以配置多个虚拟主机
Connector和Engine之间是平级的关系, 靠Service来连接
Host: 即虚拟主机, 可以实现多虚拟主机, 例如使用不同的FQDN区分. 每个虚拟主机有自己的app目录, appBase=webapps (相对于$CATALINA_BASE)
Context: 应用的上下文, 配置特定URL路径映射和目录的映射关系, URL --> Directory
3.3.3 核心组件
- Tomcat可以启动一个Server进程, 也可以启动多个进程, 即Tomcat多实例, 但一般只启动一个
- 启动Server后, 会创建一个Server提供服务. 一个Server可以创建多个Service, 但是一般也只创建一个
每个Service中, 是Engine是其连接器Connector的关联配置
一个Server, 可以为其创建的Service提供多个连接器Connector, 这些Connector使用了不同的协议, 绑定了不同的端口. 其作用就是处理来自客户端的不同的连接请求或响应
Service内部还定义了Engine, 引擎才是真正的处理请求的入口, 其内部定义了多个虚拟主机Host
Engine对请求头做分析, 将请求发送给相应的虚拟主机
如果没有匹配, 数据就发往Engine上的defaultHost缺省虚拟主机
Engine上的缺省虚拟主机可以修改
- Host定义虚拟主机, 虚拟主机有name名称, 通过名称匹配
- Context定义应用程序单独的路径映射和配置
3.4 Tomcat 处理请求过程
假设来自客户的请求为: http://localhost:8080/test/index.jsp
- 浏览器端的请求被发送到服务器端端口8080, Tomcat进程监听在此端口上, 通过侦听的HTTP/1.1 Connector获得此请求
- Connector把该请求交给它所在的Service的Engine来处理, 并等待Engine的相应
- Engine获得请求localhost:8080/test/index.jsp, 遍历它所有的虚拟主机Host
- Engine匹配到名为localhost的Host. 如果匹配不到, 就把请求交给该Engine中的defaultHost处理
- localhost Host获得请求/test/index.jsp, 匹配它所拥有的的所有的Context
- Host匹配到路径为/test的Context
- path=/test的Context获得请求index.jsp, 在它的mapping table中寻找对应的servlet
- Context匹配到URL PATTERN为*.jsp的servlet, 对应于JspServlet类构造HttpServletRequest对象和HttpServletResponse对象, 作为参数调用JspServlet的doGet或doPost方法.
- Context把执行完了之后的HttpServletResponse对象返回给Host
- Host把HttpServlerResponse对象返回给Engine
- Engine把HttpServletResponse对象返回给Connector
- Connector把HttpServletResponse对象返回给浏览器端
4. 应用部署
4.1 Tomcat 的根目录结构
Tomcat中默认网站根目录是$CATALINA_BASE/webapps/ROOT
不同web服务器的网站根目录: httpd-documentroot; nginx-root; tomcat-appbase(相对于$CATALINA_BASE的目录)
tomcat vs httpd vs nginx
- 网站默认站点目录结构不同
httpd: /var/www/html
nginx: /usr/share/nginx/html
tomact: /usr/local/tomcat/webapps/ROOT
假如访问: www.test.org/index.html
httpd访问的是: /var/www/html/index.html
nginx访问的是: /usr/share/nginx/html/index.html
tomcat访问的是: /usr/local/tomcat/webapps/ROOT/index.html
假如访问的是: www.test.org/blog/index.html
httpd访问的是: /var/www/html/blog/index.html
nginx访问的是: /usr/share/nginx/html/blog/index.html
tomcat访问的是: /usr/local/tomcat/webapps/blog/index.html 其他app目录和根目录是平级的, 每个app目录是一个独立的功能
- 案例: 创建app - 1024, 测试页面访问
[22:56:31 root@201 ~]#mkdir -pv /usr/local/tomcat/webapps/1024
mkdir: created directory '/usr/local/tomcat/webapps/1024'
[22:56:41 root@201 ~]#cd /usr/local/tomcat/webapps/1024/
[22:56:49 root@201 /usr/local/tomcat/webapps/1024]#echo '/usr/local/tomcat/webapps/1024/test.html' > test.html
每一个虚拟主机都可以使用appBase指令配置自己的站点目录, 使用appBase目录下的ROOT目录作为主站点目录
注意: Tomcat服务器无指定的字符编码, 浏览器会自动识别为GBK, 因此编写程序代码时, 要指定utf-8字符编码
4.2 JSP WebApp目录结构
- 主页配置: 默认按以下顺序查找主页文件, index.html --> index.htm --> index.jsp
- WEB-INF/: 当前目录WebApp的私有资源路径, 通过存储当前应用使用的web.xml和context.xml配置文件
- META-INF/: 类似于WEB-INF, 也是私有资源的配置信息, 和WEB-INF/目录一样浏览器无法访问
- classes/: 类文件, 当前webapp需要的类
- lib/: 当前应用依赖的jar包
4.3 主页设置
4.3.1 全局配置实现修改默认主页文件
默认情况下, tomcat会在$CATALINA_BASE/webapps/ROOT目录下按照以下次序查找文件, 找到第一个后, 就会显示, 不会继续查找
- index.html
- index.htm
- index.jsp
可以通过$CATALINA_BASE/webapps/web.xml中的以下配置来修改默认页面的优先级
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
4.3.2 WebApp的专用配置文件
针对app 1024设置专门的默认页面顺序
[16:24:59 root@201 ~]#ls /usr/local/tomcat/webapps/
docs examples host-manager manager ROOT
[16:25:03 root@201 ~]#mkdir /usr/local/tomcat/webapps/1024
[16:25:12 root@201 ~]#ls /usr/local/tomcat/webapps/
1024 docs examples host-manager manager ROOT
[16:25:22 root@201 ~]#echo '/usr/local/tomcat/webapps/1024/index.html' > /usr/local/tomcat/webapps/1024/index.html
[16:25:33 root@201 ~]#echo '/usr/local/tomcat/webapps/1024/index.htm' > /usr/local/tomcat/webapps/1024/index.htm
[16:25:37 root@201 ~]#mkdir /usr/local/tomcat/webapps/1024/WEB-INF
[16:27:20 root@201 ~]#cp -a /usr/local/tomcat/webapps/ROOT/WEB-INF/web.xml /usr/local/tomcat/webapps/1024/WEB-INF
[16:29:04 root@201 ~]#vim /usr/local/tomcat/webapps/1024/WEB-INF/web.xml
<welcome-file-list>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.html</welcome-file>
</welcome-file-list>
[16:30:58 root@201 ~]#systemctl restart tomcat
配置注意事项:
webapp的专有配置优先于系统的全局设置
修改系统的全局配置文件需要重新启动服务生效
修改webapp的专有配置, 无需重启即可生效
确保webapps及子目录的所有者和所属组都是tomcat
搭建多虚拟主机, 实现另一个站点test.wang.org
- 修改server.xml文件
[21:59:32 root@tomcat ~]#vim /usr/local/tomcat/conf/server.xml
...
# 拷贝一份localhost的Host语句块
<Host name="test.wang.org" appBase="/data/tomcat" # 网站名称为test.wang.org, 数据家目录为/data/tomcat
unpackWARs="true" autoDeploy="true">
<!-- SingleSignOn valve, share authentication between web applications
Documentation at: /docs/config/valve.html -->
<!--
<Valve className="org.apache.catalina.authenticator.SingleSignOn" />
-->
<!-- Access log processes all example.
Documentation at: /docs/config/valve.html
Note: The pattern used is equivalent to using pattern="common" -->
<Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
prefix="localhost_access_log" suffix=".txt"
pattern="%h %l %u %{Y-MM-d H:mm:s}t "%r" %s %b %D" />
</Host>
...
- 创建数据家目录
[22:01:13 root@tomcat ~]#mkdir -pv /data/tomcat
[22:01:13 root@tomcat ~]#chown -R tomcat.tomcat /data/tomcat/ # 确保tomcat有权限
# 创建ROOT目录, 因为每个虚拟主机的默认家目录都在ROOT
[22:02:00 root@tomcat ~]#mkdir /data/tomcat/ROOT
- 创建默认文件
[22:02:53 root@tomcat ~]#cd /data/tomcat/ROOT/
[22:03:01 root@tomcat /data/tomcat/ROOT]#echo 1024-webpage > index.html
[22:03:16 root@tomcat /data/tomcat/ROOT]#ls
index.html
- 访问测试
[22:03:33 root@tomcat /data/tomcat/ROOT]#vim /etc/hosts
10.0.0.83 test.wang.org
[22:05:04 root@tomcat /data/tomcat/ROOT]#systemctl restart tomcat
[22:05:13 root@tomcat /data/tomcat/ROOT]#curl test.wang.org:8080
1024-webpage
- 总结
1. 在一个tomcat虚拟主机, 也就是默认的localhost中, 可以搭建多个APPS, 虚拟主机的默认站点文件存放在ROOT目录下, 其余APPS的文件存放在webapps/APPS目录下
2. 而多虚拟主机可以自己指定文件位置, 默认的文件也是放在ROOT目录下, 其他APPS文件放在对应的appBase/APPS下
4.4 应用部署实现
4.4.1 WebApp应用的归档格式
- .war: WebApp打包, 类zip打包格式, 通常包括一个应用的所有资源, 比如jsp, html,配置文件等, 一个war包就是一个应用
- .jar: EJB类文件的打包压缩, 类zip格式文件, 包括很多的class文件
- .rar: 资源适配器类打包文件, 目前已不常用
- .ear: 企业群WebApp打包, 目前已不常用
传统应用开发测试后,通常打包为war格式,这种文件部署到了Tomcat的webapps目录下,默认会自动解开和部署上线
#conf/server.xml中文件配置
<Host name="localhost" appBase="webapps" unpackWARs="true" autoDeploy="true"> # 自动解包, 自动部署
# 把.war包放到webapps目录下, 会自动解包, 并且部署, 直接就可以在客户端访问
# unpackWARs控制是否自动解包, autoDeploy控制是否自动部署, 改为false, 解包后需要手动重启tomcat服务
4.4.2 部署方式
部署:将webapp的源文件放置到目标目录,通过web.xml和context.xml文件中配置的路径就可以访问该webapp,通过类加载器加载其特有的类和依赖的类到JVM上,即:最终用户可以通过浏览器访问该应用
自动部署:Tomcat一旦发现多了一个web应用APP.war包,默认会自动把它解压缩,加载并启动起来
手动部署:
- 冷部署:将webapp放到指定目录,才去启动Tomcat
- 热部署:Tomcat服务不停止,需要依赖manager、ant脚本、tcd(tomcat client deployer)等工具
反部署undeploy:停止webapp的运行,并从JVM上清除已经加载的类,从Tomcat应用目录中移除部署的文件
启动start:是webapp能够访问
停止stop:webapp不能访问,不能提供服务,但是JVM并不清除它
4.4.3 部署WebApp的目录结构
常见开发项目目录组成
#目录结构一般由开发用工具自动生成,以下模拟生成相关目录
mkdir projects/myapp/{WEB-INF,META-INF,classes,lib} -pv
mkdir: 已创建目录 "projects"
mkdir: 已创建目录 "projects/myapp"
mkdir: 已创建目录 "projects/myapp/WEB-INF"
mkdir: 已创建目录 "projects/myapp/META-INF"
mkdir: 已创建目录 "projects/myapp/classes"
mkdir: 已创建目录 "projects/myapp/lib"
#常见应用首页
vi projects/myapp/index.jsp
#手动复制项目目录到webapps目录下去
cp -r projects/myapp/ /usr/local/tomcat/webapps/
# 注意权限和属性, 因为projects目录一般都是root或者开发账号创建, 所以复制到webapps下, tomcat账号是没有权限的
chown -R tomcat.tomcat /usr/local/tomcat/webapps/myapp
#使用http://YourIP:8080/myapp/访问测试
4.4.4 案例: 手动部署应用
4.4.4.1 手动部署test.jsp文件, 到app - 1024应用
- 准备测试的.jsp页面
[00:08:10 root@201 /usr/local/tomcat/webapps/1024]#vim test.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>jsp例子</title>
</head>
<body>
后面的内容是服务器端动态生成字符串,最后拼接在一起
<%
out.println("hello jsp");
%>
</body>
</html>
- 页面文件的权限需要根据业务逻辑设定, 而配置文件的权限需要把tomcat设为所有者和所属组
用户访问java的 .jsp程序后, 在work对应的功能app目录下, JSP容器会把jsp页面转换成servlet, 然后再由tomcat转换成class类, 也就是java字节码, 下次访问时就不需要再做转换了.
一旦jsp程序发生了更新后, 建议删除此前生成的servlet和class文件, 防止如果没有自动生成新的文件, 那么用户访问的就还是旧的页面
- 访问test.jsp前, 观察work目录内容
[00:08:24 root@201 /usr/local/tomcat/webapps/1024]#tree ../../work/
../../work/
└── Catalina
└── localhost
├── 1024
├── docs
├── examples
├── host-manager
├── manager
└── ROOT
└── org
└── apache
└── jsp # 此前访问tomcat主页面生成的servlet和class类文件
├── index_jsp.class # tomcat再把*.java文件, 转换成class类, 也就是字节码
└── index_jsp.java # JSP容器把ROOT下的默认index.jsp页面转换成servlet, *.java文件
11 directories, 2 files
- 访问test.jsp
- 访问后查看work目录变化
[00:13:27 root@201 /usr/local/tomcat/webapps/1024]#tree ../../work/
../../work/
└── Catalina
└── localhost
├── 1024 # work/Catalina/localhost目录下生成1024-app的目录
│ └── org
│ └── apache
│ └── jsp
│ ├── test_jsp.class # servlet被转换成class类
│ └── test_jsp.java # test.jsp被转换成servlet
├── docs
├── examples
├── host-manager
├── manager
└── ROOT
└── org
└── apache
└── jsp
├── index_jsp.class
└── index_jsp.java
14 directories, 4 files
4.4.5 案例: 自动部署应用
apps2项目, 包含两个文件, 一个html一个jsp
4.4.5.1 制作应用的war包文件
[00:29:48 root@201 ~]#mkdir /data/app2
[00:30:56 root@201 ~]#cd /data/app2
[00:30:58 root@201 /data/app2]#vim test.html
<h1>This is test html </h1>
[00:32:03 root@201 /data/app2]#vim test.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>jsp例子</title>
</head>
<body>
后面的内容是服务器端动态生成字符串,最后拼接在一起
<%
out.println("hello jsp");
%>
</body>
</html>
[00:32:15 root@201 /data/app2]#jar cvf /data/app2.war *
added manifest
adding: test.html(in = 28) (out= 27)(deflated 3%)
adding: test.jsp(in = 316) (out= 271)(deflated 14%)
[00:36:07 root@201 /data/app2]#cd /data
[00:36:15 root@201 /data]#ls
app2 app2.war
[00:36:16 root@201 /data]#chown tomcat.tomcat app2.war
[00:37:36 root@201 /data]#ll
total 4
drwxr-xr-x 2 root root 39 Mar 22 00:32 app2
-rw-r--r-- 1 tomcat tomcat 858 Mar 22 00:35 app2.war
4.4.5.2 自动应用部署制作好的war包
[00:37:38 root@201 /data]#cd /usr/local/tomcat
[00:39:17 root@201 /usr/local/tomcat]#ls work/Catalina/localhost/ # 复制war包前, localhost目录没有app2目录
1024 docs examples host-manager manager ROOT
[00:39:49 root@201 /usr/local/tomcat]#cp -p /data/app2.war webapps/
[00:40:04 root@201 /usr/local/tomcat]#ls work/Catalina/localhost/ # 复制war包后, localhost目录自动生成app2目录
1024 app2 docs examples host-manager manager ROOT
[00:40:44 root@201 /usr/local/tomcat]#ll webapps/
total 8
drwxr-xr-x 3 root root 89 Mar 22 00:08 1024
drwxr-x--- 3 tomcat tomcat 55 Mar 22 00:40 app2 # app2自动解包
-rw-r--r-- 1 tomcat tomcat 858 Mar 22 00:35 app2.war # war包还会保存
drwxr-x--- 15 tomcat tomcat 4096 Mar 21 18:59 docs
drwxr-x--- 6 tomcat tomcat 83 Mar 21 18:59 examples
drwxr-x--- 5 tomcat tomcat 87 Mar 21 18:59 host-manager
drwxr-x--- 6 tomcat tomcat 114 Mar 21 18:59 manager
drwxr-x--- 3 tomcat tomcat 283 Mar 21 18:59 ROOT
[00:41:17 root@201 /usr/local/tomcat]#ll webapps/app2/
total 8
drwxr-x--- 2 tomcat tomcat 44 Mar 22 00:40 META-INF
-rw-r----- 1 tomcat tomcat 28 Mar 22 00:30 test.html
-rw-r----- 1 tomcat tomcat 316 Mar 22 00:32 test.jsp
[00:41:46 root@201 /usr/local/tomcat]#ll webapps/app2/META-INF/
total 4
-rw-r----- 1 tomcat tomcat 69 Mar 22 00:35 MANIFEST.MF
-rw-r----- 1 tomcat tomcat 0 Mar 22 00:35 war-tracker
# 此时work/Catalina/localhost生成的app2目录下没有内容, 因为客户端还没有人访问
[00:41:55 root@201 /usr/local/tomcat]#ll work/Catalina/localhost/app2/
total 0
- 访问test.jsp文件
# app2目录下会生成servlet和class类文件
[00:45:44 root@201 /usr/local/tomcat]#tree work/Catalina/localhost/app2/
work/Catalina/localhost/app2/
+-- org
+-- apache
+-- jsp
+-- test_jsp.class
+-- test_jsp.java
3 directories, 2 files
- 实现反部署, 自动删除缓存文件
[00:45:50 root@201 /usr/local/tomcat]#rm -rf webapps/app2.war # 删除webapps下的war包
[00:47:30 root@201 /usr/local/tomcat]#ls webapps/
1024 app2 docs examples host-manager manager ROOT
[00:47:33 root@201 /usr/local/tomcat]#ls webapps/ # 过几秒后, 对应的app目录会自动删除
1024 docs examples host-manager manager ROOT
[00:48:45 root@201 /usr/local/tomcat]#ls work/Catalina/localhost/ # app2目录也会被自动删除
1024 docs examples host-manager manager ROOT
4.4.6 案例: 部署基于JAVA的博客系统JPress
- 下载地址
# 把war包放在webapps下
[01:26:04 root@201 /usr/local/tomcat/webapps]#ls
1024 docs examples host-manager jpress-v3.2.1 jpress-v3.2.1.war manager ROOT
# 制作软连接
[01:26:15 root@201 /usr/local/tomcat/webapps]#ln -s jpress-v3.2.1 jpress
[01:31:18 root@201 /usr/local/tomcat/webapps]#ll
total 69376
drwxr-xr-x 3 root root 89 Mar 22 00:08 1024
drwxr-x--- 15 tomcat tomcat 4096 Mar 21 18:59 docs
drwxr-x--- 6 tomcat tomcat 83 Mar 21 18:59 examples
drwxr-x--- 5 tomcat tomcat 87 Mar 21 18:59 host-manager
lrwxrwxrwx 1 root root 13 Mar 22 01:31 jpress -> jpress-v3.2.1
drwxr-x--- 6 tomcat tomcat 86 Mar 22 01:26 jpress-v3.2.1
-rw-r--r-- 1 root root 71034734 Mar 22 01:02 jpress-v3.2.1.war
drwxr-x--- 6 tomcat tomcat 114 Mar 21 18:59 manager
drwxr-x--- 3 tomcat tomcat 283 Mar 21 18:59 ROOT
# 安装MySQL, 授权jpress用户
[01:33:41 root@201 /usr/local/tomcat/webapps]#yum -y install mysql-server
[01:35:20 root@201 /usr/local/tomcat/webapps]#systemctl enable --now mysqld
Created symlink /etc/systemd/system/multi-user.target.wants/mysqld.service → /usr/lib/systemd/system/mysqld.service.
[01:35:36 root@201 /usr/local/tomcat/webapps]#mysql -e 'create user jpress@"localhost" identified by "jpress"'
[01:35:58 root@201 /usr/local/tomcat/webapps]#mysql -e 'create database jpress'
[01:36:10 root@201 /usr/local/tomcat/webapps]#mysql -e 'grant all on jpress.* to jpress@"localhost"'
- 访问jpress
4.4.7 案例: 基于WEB的管理Server Status和Manager App实现应用部署
Tomcat提供了基于WEB的管理页面, 默认由tomcat-admin-webapps.norach包提供相关文件
4.4.7.1 实现WEB管理Server Status和Manager App
- 默认情况下, Server Status, Manager App, Host Manager三个链接都是拒绝访问的
- 启动方法
- 先修改conf/tomcat-users.xml
[01:58:25 root@201 /usr/local/tomcat]#ls conf/
Catalina catalina.policy catalina.properties context.xml jaspic-providers.xml jaspic-providers.xsd logging.properties server.xml tomcat.conf tomcat-users.xml tomcat-users.xsd web.xml
# 查看配置信息
[01:58:27 root@201 /usr/local/tomcat]#vim conf/server.xml
...
<GlobalNamingResources>
<!-- Editable user database that can also be used by
UserDatabaseRealm to authenticate users
-->
<Resource name="UserDatabase" auth="Container"
type="org.apache.catalina.UserDatabase"
description="User database that can be updated and saved"
factory="org.apache.catalina.users.MemoryUserDatabaseFactory"
pathname="conf/tomcat-users.xml" /> # 此文件指定了授权用户信息
</GlobalNamingResources>
...
- 用户认证通过配置文件conf/tomcat-users.xml设定, 需要添加manager-gui角色
<tomcat-users xmlns="http://tomcat.apache.org/xml"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://tomcat.apache.org/xml tomcat-users.xsd"
version="1.0">
<role rolename="manager-gui"/> # 添加manager-gui角色
<user username="admin" password="000000" roles="manager-gui"/> # 添加管理员账号和密码
</tomcat-users>
# 全局配置修改后, 需要重启tomcat服务
[02:03:13 root@201 /usr/local/tomcat]#systemctl restart tomcat
- 修改conf/tomcat-users.xml后, 在服务器本机就可以访问Server Status和Manager两个app了, 不过需要在服务器上安装firefox, 并且利用xmanager开启Linux上的图形化界面
[02:06:50 root@201 /usr/local/tomcat]#yum -y install firefox
[02:14:35 root@201 /usr/local/tomcat]#yum -y install libGL.so.1
[02:13:49 root@201 /usr/local/tomcat]#export DISPLAY=10.0.0.1:0.0
- Windows开启xManager-broadcast, 然后在tomcat服务器执行以下命令
[02:15:25 root@201 /usr/local/tomcat]#firefox 127.0.0.1:8080
Running without a11y support!
libGL error: MESA-LOADER: failed to open swrast (search paths /usr/lib64/dri)
libGL error: failed to load driver: swrast
- Server Status
- Manager App
- Host Manager仍然不能访问, 需要添加admin-gui到配置文件
vim /usr/local/tomcat/conf/tomcat-users.xml
<role rolename="manager-gui"/>
<role rolename="admin-gui"/> # 添加admin-gui角色
<user username="admin" password="000000" roles="manager-gui,admin-gui"/> # 允许manger-gui和admin-gui
- 修改webapps/manager/META-INF/context.xml文件
默认情况, Manager和Host-Manager只允许本地访问, 因此Windows无法远程打开
...
<Context antiResourceLocking="false" privileged="true" >
<CookieProcessor className="org.apache.tomcat.util.http.Rfc6265CookieProcessor"
sameSiteCookies="strict" />
<Valve className="org.apache.catalina.valves.RemoteAddrValve"
allow="127\.\d+\.\d+\.\d+|::1|0:0:0:0:0:0:0:1" /> # 从正则表达式可以看出, 默认只能本地访问
<Manager sessionAttributeValueClassNameFilter="java\.lang\.(?:Boolean|Integer|Long|Number|String)|org\.apache\.catalina\.filters\.CsrfPreventionFilter\$LruCache(?:\$1)?|java\.util\.(?:Linked)?HashMap"/>
</Context>
...
# 修改配置, 允许10.0.0.0网段访问
allow="127\.\d+\.\d+\.\d+|::1|0:0:0:0:0:0:0:1|10\.0\.0\.\d+" />
# 因为修改的是webapps的配置文件, 因此无需重启服务, 即可生效
- 此时, 就可以通过Windows访问Server Status和Manager App了
- 设置host-manager允许远程访问
vim webapps/host-manager/META-INF/context.xml
allow="127\.\d+\.\d+\.\d+|::1|0:0:0:0:0:0:0:1|10\.0\.0\.\d+" />
4.4.7.2 基于WEB应用程序管理器实现应用程序的部署
Manager App管理界面可以实现以下功能:
应用程序管理: 可以启动, 停止, 重新加载, 反部署, 清理过期session
应用程序部署: 热部署, 部署war文件
方式1: 指定目录部署软件
# 创建代码存放目录
[03:02:17 root@201 ~]#mkdir /data/tomcat
# 给tomcat账号权限
[03:02:41 root@201 ~]#chown -R tomcat.tomcat /data/tomcat
# 把之前部署在1024目录中的test.jsp复制到该目录下, 作为要部署的代码
[03:02:21 root@201 ~]#cd /data/tomcat/
[03:02:24 root@201 /data/tomcat]#cp /usr/local/tomcat/webapps/1024/test.jsp .
- 添加选项
Context Path (required): 指定通过浏览器访问的虚拟目录, 部署成功后, 会在webapps下生成对应目录, 代码会部署到该目录下
WAR or Directory URL: 指定服务器本地存放代码的磁盘目录
- 点击Deploy后查看结果
[03:03:52 root@201 /data/tomcat]#ll /usr/local/tomcat/webapps/
total 69380
drwxr-xr-x 3 root root 89 Mar 22 00:08 1024
drwxr-x--- 3 tomcat tomcat 55 Mar 22 03:01 app2
-rw-r----- 1 tomcat tomcat 858 Mar 22 03:01 app2.war
drwxr-x--- 15 tomcat tomcat 4096 Mar 21 18:59 docs
drwxr-x--- 6 tomcat tomcat 83 Mar 21 18:59 examples
drwxr-x--- 5 tomcat tomcat 87 Mar 21 18:59 host-manager
lrwxrwxrwx 1 root root 13 Mar 22 01:31 jpress -> jpress-v3.2.1
drwxr-x--- 6 tomcat tomcat 86 Mar 22 01:26 jpress-v3.2.1
-rw-r--r-- 1 root root 71034734 Mar 22 01:02 jpress-v3.2.1.war
drwxr-x--- 6 tomcat tomcat 114 Mar 21 18:59 manager
drwxr-x--- 3 tomcat tomcat 283 Mar 21 18:59 ROOT
drwxr-x--- 2 tomcat tomcat 22 Mar 22 03:06 testjsp # 自动生成testjsp目录
[03:09:03 root@201 /data/tomcat]#ll /usr/local/tomcat/webapps/testjsp/
total 4
-rw-r----- 1 tomcat tomcat 316 Mar 22 03:06 test.jsp
- 浏览器访问
方式2: 直接部署war包文件
需要把war包传到Windows上
- 先删除之前部署的testjsp, 点击undeploy后, webapps下的testjsp目录会被自动删除
- 把test.jsp打包成war文件, 传给Windows
[03:15:48 root@201 /data/tomcat]#jar cvf test.war *
added manifest
adding: test.jsp(in = 316) (out= 271)(deflated 14%)
[03:15:52 root@201 /data/tomcat]#ll
total 8
-rw-r--r-- 1 tomcat tomcat 316 Mar 22 03:02 test.jsp
-rw-r--r-- 1 root root 721 Mar 22 03:15 test.war
- 选择war包部署
- 验证部署成功
[03:17:48 root@201 ~]#ll /usr/local/tomcat/webapps/test
total 4
drwxr-x--- 2 tomcat tomcat 44 Mar 22 03:17 META-INF
-rw-r----- 1 tomcat tomcat 316 Mar 22 03:02 test.jsp