Tomcat基本使用

我与影子孤独终老i 提交于 2020-02-26 02:42:52

安装

jdk安装

jdk下载地址:http://www.oracle.com/technetwork/java/javase/downloads/index.html

1)解压并配置环境变量
#cd /usr/local/src/
#tar xf jdk-8u231-linux-x64.tar.gz
#ln -s jdk1.8.0_231/ jdk
#cat > /etc/profile.d/jdk.sh << EOF
export JAVA_HOME=/usr/local/src/jdk
export CLASSPATH=.:\$JAVA_HOME/jre/lib/rt.jar:\$JAVA_HOME/lib/dt.jar:\$JAVA_HOME/lib/tools.jar
export PATH=\$PATH:\$JAVA_HOME/bin
EOF
#source /etc/profile.d/jdk.sh

2)查看jdk版本
#java -version
java version "1.8.0_231"
Java(TM) SE Runtime Environment (build 1.8.0_231-b11)
Java HotSpot(TM) 64-Bit Server VM (build 25.231-b11, mixed mode)

tomcat安装

安装包下载地址:https://archive.apache.org/dist/tomcat/tomcat-8/v8.5.42/bin/apache-tomcat-8.5.42.tar.gz

1)解压并为Tomcat做软连接
#cd /usr/local/src/
#tar xf apache-tomcat-8.5.42.tar.gz
#ln -s apache-tomcat-8.5.42 tomcat

2)启动和查看Tomcat状态
#cd tomcat/bin/
#./startup.sh 
Using CATALINA_BASE:   /usr/local/src/tomcat
Using CATALINA_HOME:   /usr/local/src/tomcat
Using CATALINA_TMPDIR: /usr/local/src/tomcat/temp
Using JRE_HOME:        /usr/local/src/jdk
Using CLASSPATH:       /usr/local/src/tomcat/bin/bootstrap.jar:/usr/local/src/tomcat/bin/tomcat-juli.jar
Tomcat started.
#ps -ef |grep tomcat|grep -v grep
root       6377      1  2 21:19 pts/0    00:00:05 /usr/local/src/jdk/bin/java -Djava.util.logging.config.file=/usr/local/src/tomcat/conf/logging.properties -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -Djdk.tls.ephemeralDHKeySize=2048 -Djava.protocol.handler.pkgs=org.apache.catalina.webresources -Dorg.apache.catalina.security.SecurityListener.UMASK=0027 -Dignore.endorsed.dirs= -classpath /usr/local/src/tomcat/bin/bootstrap.jar:/usr/local/src/tomcat/bin/tomcat-juli.jar -Dcatalina.base=/usr/local/src/tomcat -Dcatalina.home=/usr/local/src/tomcat -Djava.io.tmpdir=/usr/local/src/tomcat/temp org.apache.catalina.startup.Bootstrap start

上面的操作,启动身份是root,如果要使用普通用户启动可以使用下面的这种方法
#useradd -r java
#chown -R java.java /usr/local/src/tomcat/
#su - java -c '/usr/local/src/tomcat/bin/startup.sh'
su: warning: cannot change directory to /home/java: No such file or directory
Using CATALINA_BASE:   /usr/local/src/tomcat
Using CATALINA_HOME:   /usr/local/src/tomcat
Using CATALINA_TMPDIR: /usr/local/src/tomcat/temp
Using JRE_HOME:        /usr/local/src/jdk
Using CLASSPATH:       /usr/local/src/tomcat/bin/bootstrap.jar:/usr/local/src/tomcat/bin/tomcat-juli.jar
Tomcat started.
#ps aux |grep tomcat|grep -v grep
java       6529  4.5  4.7 2995916 87744 ?       Sl   21:25   0:02 /usr/local/src/jdk/bin/java -Djava.util.logging.config.file=/usr/local/src/tomcat/conf/logging.properties -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -Djdk.tls.ephemeralDHKeySize=2048 -Djava.protocol.handler.pkgs=org.apache.catalina.webresources -Dorg.apache.catalina.security.SecurityListener.UMASK=0027 -Dignore.endorsed.dirs= -classpath /usr/local/src/tomcat/bin/bootstrap.jar:/usr/local/src/tomcat/bin/tomcat-juli.jar -Dcatalina.base=/usr/local/src/tomcat -Dcatalina.home=/usr/local/src/tomcat -Djava.io.tmpdir=/usr/local/src/tomcat/temp org.apache.catalina.startup.Bootstrap start

使用systemd管理Tomcat服务

1.首先,需要为tomcat配置pid
#sed -i '/[ -z "\$CATALINA_BASE" ] && CATALINA_BASE="\$CATALINA_HOME"/a\CATALINA_PID="$CATALINA_BASE/tomcat.pid"' /usr/local/src/tomcat/bin/catalina.sh
配置后结果如下
141 # Copy CATALINA_BASE from CATALINA_HOME if not already set
142 [ -z "$CATALINA_BASE" ] && CATALINA_BASE="$CATALINA_HOME"
143 CATALINA_PID="$CATALINA_BASE/tomcat.pid" # 设置pid。一定要加在CATALINA_BASE定义后面,要不然pid会生成到/下面

2.创建服务脚本
#cat > /usr/lib/systemd/system/tomcat.service << EOF
[Unit]
Description=Apache Tomcat Web Application Container
After=syslog.target network.target

[Service]
Type=forking
Environment="JAVA_HOME=/usr/local/src/jdk"
PIDFile=/usr/local/src/tomcat/tomcat.pid
ExecStart=/usr/local/src/tomcat/bin/startup.sh
ExecReload=/bin/kill -s HUP \$MAINPID
ExecStop=/bin/kill -s QUIT \$MAINPID
PrivateTmp=true
SuccessExitStatus=143                                                   

[Install]
WantedBy=multi-user.target
EOF

3.启动Tomcat并设置为开机自启动,和查看状态
#systemctl enable --now tomcat && systemctl status tomcat
Created symlink from /etc/systemd/system/multi-user.target.wants/tomcat.service to /usr/lib/systemd/system/tomcat.service.
● tomcat.service - Apache Tomcat Web Application Container
   Loaded: loaded (/usr/lib/systemd/system/tomcat.service; enabled; vendor preset: disabled)
   Active: active (running) since Wed 2020-01-15 17:23:21 CST; 7ms ago
  Process: 9615 ExecStart=/usr/local/src/tomcat/bin/startup.sh (code=exited, status=0/SUCCESS)
 Main PID: 9623 (java)
   CGroup: /system.slice/tomcat.service
           └─9623 /usr/local/src/jdk/bin/java -Djava.util.logging.config.file=/usr/local/src/tomcat/conf/logging.properties -Djava.util.logging.manager=org.apache.juli....

Jan 15 17:23:21 CentOS7-01.localdomain systemd[1]: Starting Apache Tomcat Web Application Container...
Jan 15 17:23:21 CentOS7-01.localdomain startup.sh[9615]: Tomcat started.
Jan 15 17:23:21 CentOS7-01.localdomain systemd[1]: Started Apache Tomcat Web Application Container.

使用systemd管理Tomcat服务遇到的问题及解决办法

1.执行systemctl start tomcat命令
#systemctl start tomcat
Job for tomcat.service failed because the control process exited with error code. See "systemctl status tomcat.service" and "journalctl -xe" for details.
#journalctl -xe
......
startup.sh[10247]: Neither the JAVA_HOME nor the JRE_HOME environment variable is defined
startup.sh[10247]: At least one of these environment variable is needed to run this program
......
如果在tomcat的service文件中没有设置jdk的环境变量,就会在启动tomcat的时候报错,产生以上的错误信息,为解决此问题,需要在service文件中添加如下配置
[Service]
Environment="JAVA_HOME=/usr/local/src/jdk"
注:就算在/etc/profile.d/目录下单独配置了jdk环境变量,对于使用systemd管理tomcat服务也是无效的,所有需要在tomcat的service文件中配置。

2.执行systemctl stop tomcat命令
#systemctl stop tomcat
#systemctl status tomcat
● tomcat.service - Apache Tomcat Web Application Container
   Loaded: loaded (/usr/lib/systemd/system/tomcat.service; enabled; vendor preset: disabled)
   Active: failed (Result: exit-code) since Wed 2020-01-15 19:17:27 CST; 2min 21s ago
  Process: 10635 ExecStop=/bin/kill -s QUIT $MAINPID (code=exited, status=0/SUCCESS)
  Process: 10574 ExecStart=/usr/local/src/tomcat/bin/startup.sh (code=exited, status=0/SUCCESS)
 Main PID: 10582 (code=exited, status=143)

Jan 15 19:17:19 CentOS7-01.localdomain systemd[1]: Starting Apache Tomcat Web Application Container...
Jan 15 19:17:19 CentOS7-01.localdomain startup.sh[10574]: Tomcat started.
Jan 15 19:17:19 CentOS7-01.localdomain systemd[1]: Started Apache Tomcat Web Application Container.
Jan 15 19:17:27 CentOS7-01.localdomain systemd[1]: Stopping Apache Tomcat Web Application Container...
Jan 15 19:17:27 CentOS7-01.localdomain systemd[1]: tomcat.service: main process exited, code=exited, status=143/n/a
Jan 15 19:17:27 CentOS7-01.localdomain systemd[1]: Stopped Apache Tomcat Web Application Container.
Jan 15 19:17:27 CentOS7-01.localdomain systemd[1]: Unit tomcat.service entered failed state.
Jan 15 19:17:27 CentOS7-01.localdomain systemd[1]: tomcat.service failed.

停止tomcat的时候并没有报错,但是查看tomcat的status时,发现tomcat服务进入了失败的状态,为解决此问题,需要在tomcat的service中添加如下配置
[Service]
SuccessExitStatus=143

参考文档:https://stackoverflow.com/questions/40331741/systemd-tomcat-service-failed-with-no-errors

目录结构

目录 说明
bin 服务启动、停止等相关
conf 配置文件
lib 库目录
logs 日志目录
webapps 应用程序,应用部署目录
work jsp编译后的结果文件

配置文件

文件名 说明
server.xml 主配置文件
web.xml 每个webapp只有“部署”后才能被访问,它的部署方式通常由web.xml进行定义,其存放位置为WEB-INF/目录中;此文件为所有的webapps提供默认部署相关的配置
context.xml 每个webapp都可以专用的配置文件,它通常由专用的配置文件context.xml来定义,其存放位置为WEB-INF/目录中;此文件为所有的webapps提供默认配置
tomcat-users.xml 用户认证的账号和密码文件
catalina.policy 当使用-security选项启动tomcat时,用于为tomcat设置安全策略
catalina.properties Java属性的定义文件,用于设定类加载器路径,以及一些与JVM调优相关参数
logging.properties 日志系统相关的配置。log4j

组件分类

类别 说明
顶级组件 Server,代表整个Tomcat容器
服务类组件 Service,组织Engine和Connector,里面只能包含一个Engine
连接器组件 Connector,有HTTP、HTTPS、A JP协议的连接器
容器类 Engine、Host、Context都是容器类组件,可以嵌入其它组件,内部配置如何运行应用程序。
内嵌类 可以内嵌到其他组件内,valve、logger、realm、loader、manager等。以logger举例,在不同容器组件内定义。
集群类组件 listener、cluster

内部组成结构

由上述组件就构成了Tomcat,如下图

Tomcat基本使用

名称 说明
Server Tomcat运行的进程实例
Connector 负责客户端的HTTP、HTTPS、A JP等协议的连接。一个Connector只属于某一个Engine
Service 用来组织Engine和Connector的关系
Engine 响应并处理用户请求。一个引擎上可以绑定多个Connector
Host 虚拟主机
Context 应用的上下文,配置路径映射path => directory
AJP(Apache Jserv protocol) 是一种基于TCP的二进制通讯协议。

核心组件说明

  • Tomcat启动一个Server进程。可以启动多个Server,但一般只启动一个
  • 创建一个Service提供服务。可以创建多个Service,但一般也只创建一个
    • 每个Service中,是Engine和其连接器Connector的关联配置
  • 可以为这个Server提供多个连接器Connector,这些Connector使用了不同的协议,绑定了不同的端口。其作用就是处理来自客户端的不同的连接请求或响应
  • Service内部还定义了Engine,引擎才是真正的处理请求的入口,其内部定义多个虚拟主机Host
    • Engine对请求头做了分析,将请求发送给相应的虚拟主机
    • 如果没有匹配,数据就发往Engine上的defaultHost缺省虚拟主机
    • Engine上的缺省虚拟主机可以修改
  • Host定义虚拟主机,虚拟主机有name名称,通过名称匹配
  • Context定义应用程序单独的路径映射和配置

Tomcat处理请求的流程

假设来自客户的请求为:http://localhost:8080/test/index.jsp
  1)浏览器端的请求被发送到服务端端口8080,Tomcat进程监听在此端口上。通过侦听的HTTP/1.1 Connector获得此请求。                  
  2)Connector把该请求交给它所在的Service的Engine来处理,并等待Engine的响应
  3)Engine获得请求localhost:8080/test/index.jsp,匹配它所有虚拟主机Host
  4)Engine匹配到名为localhost的Host。即使匹配不到也把请求交给该Host处理,因为该Host被定义为该Engine的默认主机
  5)localhost Host获得请求/test/index.jsp,匹配它所拥有的所有Context
  6)Host匹配到路径为/test的Context
  7)path=/test的Context获得请求/index.jsp,在它的mapping table中寻找对应的servlet
  8)Context匹配到URL PATTERN为*.jsp 的servlet,对应于JspServlet类构造HttpServletRequest对象和HttpServletResponse对象,作为参数调用JspServlet的doGet或doPost方法。
  9)Context把执行完了之后的HttpServletResponse对象返回给Host
  10)Host把HttpServletResponse对象返回给Engine
  11)Engine把HttpServletResponse对象返回给Connector
  12)Connector把HttpServletResponse对象返回给浏览器端

应用部署

根目录

Tomcat中默认网站根目录是CATALINA_BASE/webapps/,在Tomcat的webapps目录中,有个非常特殊的目录ROOT,它就是网站默认根目录。
每一个虚拟主机的目录都可以使用appBase配置自己的站点目录,里面都可以使用ROOT目录作为主站目录。

JSP WebApp目录结构

主页配置:一般指定为index.jsp或index.html
WEB-INF/:当前WebApp的私有资源路径,通常存储当前应用使用的web.xml和context.xml配置文件
META-INF/:类似于WEB-INF
classes/:类文件,当前webapp需要的类
lib/:当前应用依赖的jar包

更改默认主页文件

默认情况下,访问Tomcat的主页,返回的内容是CATALINA_BASE/webapps/ROOT/index.jsp文件提供的,这里将在CATALINA_BASE/webapps/ROOT/下添加一个index.html文件,内容如下
#cat /usr/local/src/tomcat/webapps/ROOT/index.html 
tomcat index.html
添加完该文件内容后再访问Tomcat默认页,返回结果如下
#curl localhost:8080
tomcat index.html

产生上面结果的原因是CATALINA_BASE/conf/web.xml文件中的<welcome-file-list>标签内容(默认页)所导致的,复制到CATALINA_BASE/webapps/ROOT/WEB-INF/web.xml中,如下

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
                      http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
  version="3.1"
  metadata-complete="true">

  <display-name>Welcome to Tomcat</display-name>
  <description>
     Welcome to Tomcat
  </description>

   <welcome-file-list>
        <welcome-file>index.jsp</welcome-file>
        <welcome-file>index.htm</welcome-file>
        <welcome-file>index.html</welcome-file>
    </welcome-file-list>

</web-app>

配置修改后,再次访问首页,结果如下图

Tomcat基本使用

从上面的验证结果可以发现,Tomcat的默认页访问顺序是从上往下依次匹配的

webapp归档格式

.war:WebApp打包
.jar:EJB类打包文件
.rar:资源适配器类打包文件
.ear:企业级WebApp打包

传统应用开发测试后,通常打包为war格式,这种文件部署到了Tomcat的webapps下,还可以自动展开。

部署Deploy

  • 部署:将webapp的源文件放置到目标目录,通过web.xml和context.xml文件中配置的路径就可以访问该webapp,通过类加载器加载其特有的类和依赖的类到JVM上。
    • 自动部署Auto Deploy:Tomcat发现多了这个应用就把它加载并启动起来
    • 手动部署
    • 冷部署:将webapp放到指定目录,才去启动Tomcat
    • 热部署:Tomcat服务不停止,需要依赖manager、ant脚本、tcd(tomcat client
      deployer)等工具
  • 反部署undeploy:停止webapp的运行,并从JVM上清除已经加载的类,从Tomcat应用目录中移除部署的文件
  • 启动start:是webapp能够访问
  • 停止stop:webapp不能访问,不能提供服务,但是JVM并不清除它

实验

1 添加一个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");
%>
<br>
<%=request.getRequestURL()%>
</body>
</html>

把test.jsp放到ROOT下去,然后访问http://YourIP:8080/test.jsp
立即可以看到,这是通过路径映射找到相应的test.jsp后,转换成test_jsp.java,再编译成test_jsp.class

CATALINA_BASE/work/Catalina/localhost/ROOT/org/apache/jsp/ 目录下有转换后的文件

2 添加一个应用

模拟部署一个应用

常见开发项目目录组成结构
#mkdir projects/myapp/{WEB-INF,classes,lib} -p
#tree projects/
projects/
└── myapp
    ├── classes
    ├── lib
    └── WEB-INF

4 directories, 0 files

常见应用首页,内容就用上面的test.jsp
#cp webapps/ROOT/test.jsp projects/myapp/index.jsp

复制项目目录到webapps目录下去
#cp -r projects/myapp/ /usr/local/src/tomcat/webapps/

访问测试http://YourIP:8080/myapp

主配置文件详解

CATALINA_BASE/conf/server.xml

1)8005端口

<Server port="8005" shutdown="SHUTDOWN">

该端口是Tomcat的管理端口,默认监听在127.0.0.1上。SHUTDOWN这个字符串接收到后就会关闭此Server。

#ss -nlt|grep 8080
LISTEN     0      100       [::]:8080                  [::]:*  
#telnet 127.0.0.1 8005
Trying 127.0.0.1...
Connected to 127.0.0.1.
Escape character is '^]'.
SHUTDOWN
Connection closed by foreign host.

这个管理功能建议禁用,将SHUTDOWN改为一串猜不出来的字符串,例如
<Server port="8005" shutdown="4dbbcd8bf182d05bed2b5ef419397b0d">

2)用户认证

CATALINA_BASE/conf/tomcat-users.xml

Tomcat基本使用

如果想要使用Manager App,需要一个角色manager-gui,在CATALINA_BASE/conf/tomcat-users.xml配置文件中添加,如下
<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"/>
  <user username="test" password="test" roles="manager-gui"/>
</tomcat-users>

Tomcat启动加载后,这些内容是常驻内存的。如果配置了新的用户,需要重启Tomcat。访问Manager App

Tomcat基本使用

访问manager的时候告诉403,提示中告诉去manager的context.xml中修改,文件路径CATALINA_BASE/webapps/manager/META-INF/context.xml

<?xml version="1.0" encoding="UTF-8"?>
<Context antiResourceLocking="false" privileged="true" >
  <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>
从配置文件中可以看到allow后面的正则表达式写的是只允许本地访问,但我当前的地址是192.168段的,所有需要添加正则表达式以支持访问,配置后如下
allow="127\.\d+\.\d+\.\d+|::1|0:0:0:0:0:0:0:1|192\.168\.\d+\.\d+"

重启后再次访问测试

Tomcat基本使用

3)Service

<Service name="Catalina">

一般情况下,一个Server实例配置一个Service,name属性相当于该Service的ID。

4)连接器配置

<Connector port="8080" protocol="HTTP/1.1"
           connectionTimeout="20000"
           redirectPort="8443" />

redirectPort,如果访问HTTPS协议,自动转向这个连接器。但大多数时候,Tomcat并不会开启HTTPS,因为Tomcat往往部署在内部,HTTPS性能较差。

5)引擎配置

<Engine name="Catalina" defaultHost="localhost">

defaultHost指向内部定义某虚拟主机。缺省虚拟主机可以改动,默认localhost。

6) 虚拟主机配置

<Host name="localhost" appBase="webapps" unpackWARs="true" autoDeploy="true">

配置说明:
name #必须是主机名,用主机名来匹配。
appBase #当前主机的网页根目录,是相对于CATALINA_HOME,也可以使用绝对路径
unpackWARs #是否自动解压war格式
autoDeploy #热部署,自动加载并运行应用

虚拟主机配置实验

尝试再配置一个虚拟主机,并将myapp部署到/data/webapps目录下

<Host name="www.hechunping.com" appBase="/data/webapps/" unpackWARs="true"
autoDeploy="false" />

#mkdir /data/webapps -p
#cp -r projects/myapp/ /data/webapps/ROOT
刚才在虚拟主机中主机名定义www.hechunping.com,所有需要在宿主机的hosts文件中添加域名解析

访问测试

Tomcat基本使用

Context配置

Context作用

  • 路径映射
  • 应用独立配置,例如单独配置应用日志、单独配置应用访问控制
<Context path="/test" docBase="/data/test" reloadable="false" />

配置说明:
path #指的是访问的路径
docBase #可以是绝对路径,也可以是相对路径(相对于Host的appBase)
reloadable #true表示如果WEB-INF/classes或META-INF/lib目录下.class文件有改动,就会将WEB应用重新加载,性能消耗很大。生产环境中,会使用false来禁用。

将projects/myapp下的项目文件复制到/data/下
#cp -r projects/myapp/ /data/myapp_v1
#cd /data/
#ln -s myapp_v1/ test

在Tomcat的主配置文件server.xml中添加如下内容
<Host name="www.hechunping.com"  appBase="/data/webapps"                          unpackWARs="true" autoDeploy="true">
  <Context path="/test" docBase="/data/test" reloadable="false" />
</Host>

访问测试http://www.hechunping.com:8080/test/

Tomcat基本使用

注意:这里特别使用了软链接,原因就是以后版本升级,需要将软链接指向myapp_v2,重启Tomcat。如果新版上线后,出现问题,重新修改软链接到上一个版本的目录,并重启,就可以实现回滚。
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!