Tomcat是由Apache软件基金会下属的Jakarta项目开发的一个servelet容器,按照Sun microsystems提供的技术 规范开发出来,Tomcat 8实现了对servlet 3.1和Javaserver page 2.3(JSP)的支持,并提供了作为web服务器的 一些特有功能,如Tomcat管理和控制平台、安全域管理和Tomcat附加组件等
-
安装jdk和apache
-
修改/etc/profile 末尾追加
export JAVA_H0ME=/usr/local/jdk1.8.0_211
export JRE_HOME=/usr/local/jdk1.8.0_211
export CLASSPATH=$JAVA_HOME/lib/tools.jar:$JAVA_H0ME/lib/dt.jar
export PATH=$JAVA_HOME/bin:$JRE_HOME/bin:$PATH
刷新一下 source /etc/profile 查看一下 java -version 3. 启动一下tomcat 4.查看一下端口 4. 测试一下
多实例(一个主机运行多个Tomcat)
- 复制一个tomcat配置文件 cp -r /usr/local/tomcat /usr/local/tomcat2
- 修改/usr/local/tomcat2/conf/server.xml (把各个端口号加一)
- 启动tomcat2
- 测试
查看
JPS命令功能描述:jps是用于查有权限访问的hotspot虚拟机(jdk中带的虚拟机)的进程
命令语法: jps [options] [hostid]
options:命令选项,用来对输出格式进行控制
-p 仅仅显示vm标识,不显示jar,class,main参数等信息
-m 输出主函数传入的参数
-l 输出应用程序主类完整package名称或jar完整名称
-v 列出jvm参数,-Xms20m -Xmx50m是启动程序指定的jvm参数与
-V 输出通过.hotsportrc或者-XX:Flags=<filename>指定的jvm参数
hostid:指定特定主机,可以使IP地址或域名,也可以指定具体协议,端口 [protocol:][//hostname][:port]
[servername]
配置 目录结构 程序目录 ——Tomcat执行脚本目录 conf ——Tomcat配置文件 lib ——Tomcat运行需要的库文件(JARS) logs —— Tomcat执行时的LOG文件 temp ——Tomcat临时文件存放目录 webapps ——Tomcat的主要Web发布目录(存 放我们自己的JSP,SERVLET,类) work ——Tomcat的工作目录,Tomcat将翻译JSP文件到的Java文件和class文件 放在这里 web工程发布目录结构 webapps是 Tomcat的主要Web发布目录,默认情况下把Web应用文件放于此目录 项目名: 项目名下面有WEB-INF , META-INF,两个文件夹,和一些给浏览器访问的资源,如html文件; WEB-INF:可以称为是安全目录,因为在这下面的文件,浏览器是访问不到的,
- web.xml:Web应用程序配置文件,描述了 servlet 和其他的应用组件配置及命名规则。
- classes:包含所需要的 class 文件,包括 servlet class 和其他的一些class,他们不能包含在 .jar文件中。
- lib:存放web应用需要的各种JAR文件 META-INF:用来配置应用程序、扩展程序、类加载器和服务
默认webapps目录结构 docs:Tomcat帮助文档 examples:web应用实例 host-manager:主机管理 manager:应用管理 ROOT:默认站点根 目录 配置文件 conf目录主要是用来存放tomcat的一些配置文件。 server.xml 主配置文件 web.xml 与其他适用于整个web应用程序设置的配置文件 context.xml 默认的context设 置,应用于安装了Tomcat的所有主机的所有部署内容 tomcat-users.xml用来配置管理tomcat的用户与权限 catalina.xml Tomcat的安全防护策略文件 组件
- Server提供一个接口,由1至多个Service组成,让其它程序可以访问到这个Service集合,同时维护各个 Service的生命周期,包括如何初始化,如何结束服务,如何找到别人请求的服务。
- Service又由1-n个Connector及单个Container组成,只是在Container和Connector外多包了一层,提供各种 服务
- Connector组件是可选择替换的,负责接收浏览器发过来的TCP连接请求,创建Request/Response,分配线 程,将创建的对象传递给Container来处理请求
- Container是容器的父接口,由四个容器组成,分别是Engine,Host,Context,Wrapper。其中Engine包 含Host,Host包含Context,Content包含Wrapper,一个Servlet class对应一个Wrapper
- Engine容器是作为顶级Container组件来设计的,由Host组成,其作用相当于一个Container的门面。有了 Engine,请求的处理过程变为:浏览器发出请求,Connector接受请求,将请求交由Container(这里是 Engine)处理,Container(Engine来担当)查找请求对应的Host并将请求传递给它,Host拿到请求后查 找相应的应用上下文环境,准备 servlet环境并调用service方法。
- Host容器是Engine的子容器,一个Host在Engine中代表一个虚拟主机,这个主机可以运行多个应用,他 负责安装和展开这些应用,并且标识这个应用,以便能够区分他们。它的子容器通常是Context,他除了 关联子容器外,还保存一个主机应有的信息。Host不是必需的,但是要运行 war程序,就必须要使用 Host,因为在war中必有web.xml文件,这个文件解析就需要Host,如果有多个Host就需要定义一个top 容器 Engine,而Engine没有父容器,一个Engine就代表一个完整的Servlet引擎
- Context代表Servlet的Context,它具备Servlet运行的基本环境,理论上只要有Context就能运行Servlet, 简单的Tomcat可以没有Engine和Host。其最重要的功能就是管理Servlet实例,Servlet实例在Context中是 以Wrapper 出现的。
- Wrapper代表一个Servlet,它负责管理Servlet,包括装载,初始化,执行以及资源回收。它是最底层的 容器。
- valve 阀门,拦截请求并在将其转至对应的webapp前进行某种处理操作,可以用于任何容器中,比如记 录日志、基于ip做访问控制 配置文件解读
<?xml version="1.0" encoding="UTF-8"?>
<Server port="8005" shutdown="SHUTDOWN">
<Listener className="org.apache.catalina.startup.VersionLoggerListener" />
<Listener className="org.apache.catalina.core.AprLifecycleListener"
SSLEngine="on" />
<Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener"
/>
<Listener
className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" />
<Listener className="org.apache.catalina.core.ThreadLocalLeakPreventionListener"
/>
<GlobalNamingResources>
<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>
<Service name="Catalina">
<Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" />
<Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />
<Engine name="Catalina" defaultHost="localhost">
<Realm className="org.apache.catalina.realm.LockOutRealm">
<Realm className="org.apache.catalina.realm.UserDatabaseRealm"
resourceName="UserDatabase"/>
</Realm>
<Host name="localhost" appBase="webapps"
unpackWARs="true" autoDeploy="true">
<Valve className="org.apache.catalina.valves.AccessLogValve"
directory="logs"
prefix="localhost_access_log" suffix=".txt"
pattern="%h %l %u %t "%r" %s %b" />
</Host>
</Engine>
</Service>
</Server>
engine是核心组件,负责通过connector接收用户请求,并处理请求,将请求转发至对应的虚拟主机host上, defaulthost指定缺省的处理请求的主机名,它至少与其中呢一个host元素的name属性值是一样的 realm表示存 放用户名、密码及role的数据库 Tomcat Server处理一个http请求的过程 假设来自客户的请求为: http://localhost:8080/wsota/wsota_index.jsp 请求被发送到本机端口8080,被在那里侦听的Coyote HTTP/1.1 Connector获得 Connector把该请求交给它所在 的Service的Engine来处理,并等待来自Engine的回应 Engine获得请求localhost/wsota/wsota_index.jsp,匹配它 所拥有的所有虚拟主机Host Engine匹配到名为localhost的Host(即使匹配不到也把请求交给该Host处理,因为 该Host被定义为该Engine的默认主机) localhost Host获得请求/wsota/wsota_index.jsp,匹配它所拥有的所有 Context Host匹配到路径为/wsota的Context(如果匹配不到就把该请求交给路径名为""的Context去处理) path="/wsota"的Context获得请求/wsota_index.jsp,在它的mapping table中寻找对应的servlet Context匹配到 URL PATTERN为*.jsp的servlet,对应于JspServlet类 构造HttpServletRequest对象和HttpServletResponse对象, 作为参数调用JspServlet的doGet或doPost方法 Context把执行完了之后的HttpServletResponse对象返回给Host Host把HttpServletResponse对象返回给Engine Engine把HttpServletResponse对象返回给Connector Connector 把HttpServletResponse对象返回给客户browser
自定义目录 修改server.xml文件中的host元素 #appBase 定义站点目录 #docBase 定义应用目录 #Context path 指出你的访 问路径(虚拟应用名,可为空) #Context docBase 指定你的存放路径 #debug 为设定dedug的登记,0提供最 少的信息,9提供最多的信息 #reloadable=true 当web.xml或者class有改动的是后续都会自动更新加载,不需要 从新启动服务 #crosscontext="true" 表示配置的不同context共享一个session #unpackWARs 是否自动解压war 包 #autoDeploy 是否自动部署(热部署) appBase 这个目录表示: 这个目录下面的子目录将自动被部署为应用(autoDeploy="true") 这个目录下的war 文件将被自动解压缩并部署为应用(unpackWARs="true") 这个目录下的子目录,会当做单独的虚拟目录,或 者叫应用 如果不想使用Tomcat下的webapp目录路,则appBase下面加一行docBase,把路径配置到docBase 中,把appBase为空就可以了
自定义目录
- 修改/usr/local/tomcat/conf/server.xml
- 创建所需目录和网页
[root@bogon ~]# mkdir -p /data/project
[root@bogon ~]# vim /data/project/index1.jsp
[root@bogon ~]# vim /data/project/index2.jsp
- 修改112 /usr/local/tomcat/conf/web.xml
4. 重启tomcat 5. 查看端口 6. 测试
自定义一个监控页面,通过web查看运行性能(类似phpinfo) server.xml如下设置
- 修改/usr/local/tomcat/conf/web.xml
- 创建所需目录和网页
<%
Runtime rtm = Runtime.getRuntime();
long mm = rtm.maxMemory()/1024/1024;
long tm = rtm.totalMemory()/1024/1024;
long fm = rtm.freeMemory()/1024/1024;
out.println("JVM memory detail info :<br>");
out.println("Max memory:"+mm+"MB"+"<br>");
out.println("Total memory: "+tm+"MB"+"<br>");
out.println("Free memory: "+fm+"MB"+"<br>");
out.println("Available memmory can be used is :"+(mm+fm-tm)+"MB"+"<br>");
%>
- 重启tomcat
- 查看端口
- 测试
远程监控 Tomcat开启JMX远程调试功能
- 修改/usr/local/tomcat/bin/catalina.sh
- 配置认证,配置jmxremote.access和jmxremote.password 进入默认按照jdk的目录 修改/usr/local/jdk1.8.0_211/jre/lib/management/jmxremote.password 修改/usr/local/jdk1.8.0_211/jre/lib/management/jmxremote. Access
- 限制口令文件读取权限 chmod 600 jmxremote.password jmxremote.access
- 重启tomcat
- 查看端口 6.测试
后台 app manager 做这个的时候要把catalina.sh里边写入的东西删除掉,否则Tomcat无法访问到页面
-
修改 修改/usr/local/tomcat/conf/tomcat-users.xml文件,配置manager角色、用户名及密码
-
修改/usr/local/tomcat/webapps/manager/META-INF/context.xml 20
-
重启tomcat
-
查看端口
-
测试
-
创建测试网页
-
打包网页 jar -cvf bdqn.war index.jsp
-
测试 (1) (2)
8. 查看 /usr/local/tomcat/webapps/有没有test
热部署 tomcat的热部署实现原理:tomcat启动的时候会有启动一个线程每隔一段时间会去判断应用中加载的类是否发生 变法(类总数的变化,类的修改),如果发生了变化就会把应用的启动线程停止掉,清除引用,并且把加载该应 10-Tomcat.md 5/12/2019 18 / 23 用的WebappClassLoader设为null,然后创建一个新的WebappClassLoader来重新加载应用。 <Host appBase="webapps" autoDeploy="true" name="localhost" unpackWARs="true"> reloadable的作用是当你修改了jsp之后会自动编译class文件,等于即时生效,但是代价不低,适合本地 开发调试,一般在开发阶段将reloadable的属性设置为true,有助于调试servlet和其他的class文件,但是 由于这样会增加服务器的运行负载,损耗系统性能,在项目运行阶段将它设置为false war包部署 直接将web项目文件(一般是复制生成的war包)复制到Tomcat的webapps目录 如果Tomcat没有开启自解压,则将war包解压到webapps目录 解压命令jar(解压到当前目录) jar -xf bdqnweb.war war包也可以使用unzip解压,使用unzip命令的时候,可 以指定解压目录 安全 端口防护 修改目标端口为不易猜测的端口,降低自动扫描软件发现到的几率 后台管理 删除默认的管理后台(如果不需要使用),降低被爆破和提权的风险 删除webapp下的host-manager和manager目录 禁用目录浏览 修改 conf/web.xml文件,将listings改为false 隐藏信息 尽量避免暴露服务器的版本信息,隐藏错误页面。在配置中对一些常见的错误进行重定向,避免出现错误时 Tomcat默认显示的错误页面暴露服务器和版本信息;必须确保程序根目录下的错误页面已经存在; vim conf/web.xml 添加内容
<error-page>
<error-code>404</error-code>
<location>/notfound.jsp</location>
</error-page>
重启Tomcat,测试一下 firefox 192.168.43.249:8088/aaaaaaaaaaaaaaa
注意:这里的意思是说,如果是404的错误就找/目录下的notfound.jsp,所以一定要知道自己的网页根目录在哪,并在这个目录下创建notfound.jsp页面,页面内容自己编辑 网页根目录是server.xml文件中 host 标签下的context标签里的docBase
上边web.xml中只写了404报错的,其他常见报错也可以写,比如
<error-page>
<error-code>403</error-code>
<location>/forbidden.jsp</location>
</error-page>
<error-page>
<error-code>404</error-code>
<location>/notfound.jsp</location>
</error-page>
<error-page>
<error-code>500</error-code>
<location>/systembusy.jsp</location>
</error-page>
脚本权限收回 去除其他用户对Tomcat的bin目录下的 shutdown.sh、startup.sh、catalina.sh的可执行权限,防止其他用户有 Tomcat的权限 chmod -R 744 /usr/local/apache-tomcat-8.5.35/bin/ 日志规范 开启Tomcat默认访问日志中的referer和user-agent记录,开启这两个是为了一旦出现安全问题,能够更好的根 据日志进行问题排查 [root@localhost apache-tomcat-8.5.35]# vim conf/server.xml 原来是这样:
<Valve className="org.apache.catalina.valves.AccessLogValve"
directory="logs"
10-Tomcat.md 5/12/2019
20 / 23
prefix="localhost_access_log" suffix=".txt"
pattern="%h %l %u %t "%r" %s %b" />
修改后的样子:
<Valve className="org.apache.catalina.valves.AccessLogValve"
directory="logs"
prefix="localhost_access_log" suffix=".txt"
pattern="%h %l %u %t %r %s %b %{Referer}i %{User-Agent}i %D" />
主机管理器的使用 (末尾添加)
- 修改/usr/local/tomcat/conf/tomcat-users.xml
<role rolename="admin-gui"/> <user username="xgp" password="123.com" roles="admin-gui"/> 2. 修改/usr/local/tomcat/webapps/host-manager/META-INF/context.xml 3. 重启tomcat 4. 查看端口 5. 浏览器测试
日志切割使用cronolog
-
编译安装Cronolog
-
修改/usr/local/tomcat/bin/catalina.sh 448 加注释 找到第二个org.apache.catalina.starup.Bootstrap修改 472
-
重启tomcat
-
查看端口
-
测试
定义错误页面
- 修改/usr/local/tomcat/conf/web.xml 23
- 创建所需网页 vim /usr/local/tomcat/webapps/ROOT/error.jsp
- 重启tomcat
- 查看端口
- 测试
线程池优化
- 修改/usr/local/tomcat/conf/server.xml 56 修改 69
2.重启tomcat 2. 查看端口
Tomcat优化 1 /usr/local/tomcat/bin/catalina.sh 开头添加
JAVA_OPTS="-Dfile.encoding=UTF-8 -server -Xms1024M -Xmx1024M -XX:NewSize=512M -XX:MaxNewSize=1024M -XX:PermSize=256M -XX:MaxPermSize=356M -XX:NewRatio=2 -XX:ParallelGCThreads=15 -XX:+DisableExplicitGC" -Xms:表示 JVM初始内存大小,也可以说是Java 初始化堆的大小,-Xms 与-Xmx 设成一样的值,避免 JVM 反复重新申请内存,导致性能大起大落,默认值为物理内存的 1/64 -Xmx:表示最大 Java 堆大小,当应用程序需要的内存超出堆的最大值时虚拟机就会提示内存溢出,并且导致应用服务崩溃,因此一般建议堆的最大值设置为可用内存的最大值的80%。 -Xmn:设置JVM最小内存(128-256就够了,一般不设置) -XX:NewSize:设置新生代内存大小。 新生代,对象新创建的时候分配的内存空间,老生代在垃圾回收器回收过后该对象依然没有被回收,该对象就会移动到老生代 -XX:PermSize:设置持久代内存大小,用于存放静态文件,如今Java类、方法等。持久代对垃圾回收没有显著影响,但是有些应 用可能动态生成或者调用一些class,持久带也称为方法区,方法区存储每一个java类的结构信息:比如运行时常量池,字段和方法数据,构造函数和普通方法的字节码内容以及类、实例、接口初始化时需要使用到的特殊方法等数据,JDK8中已经把持久代(PermGen Space) 干掉了,取而代之的元空间(Metaspace)。Metaspace占用的是本地内存,不再占用虚拟机内存。 -XX:MaxPermSize:设置最大值持久代内存大小,永久代不属于堆内存,堆内存只包含新生代和老年代 -XX:NewRatio:改变新旧空间的比例,意思是新空间的尺寸是旧空间的1/8(默认为8) -XX:ParallelGCThreads 可用来增加并行度,需要多cpu -XX:+DisableExplicitGC:关闭System.gc(),简单理解就是关闭java中的内存回收机制
2.重启tomcat 3. 查看端口 4. 测试
Tomcat的请求方式 Tomcat支持三种接收请求的方式:BIO NIO APR 1、BIO:每个请求都要创建一个线程来处理,线程开销比较大,不适用高并发的场景,性能也最低 2、NIO:基于缓冲区,能提供非阻塞I/O操作,和传统的BIO相比,具备更好的并发性能 3、APR(Apache portable run-time libraries):简单理解,就是从操作系统级别解决异步IO问题,大幅度的提高服务器的处理和相应性能,也是Tomcat运行高并发的首选模式 APR提供的主要功能模块包括:内存分配及内存池、原子操作、文件I/O、锁、内存映射、哈希表、网络I/O、轮询、进程及线程操作等等,通过采用APR,Tomcat可以获得高度可扩展性以及优越的性能,并且可以更好的与本地服务器技术集成,从而可以使Tomcat作为一款通用的Web服务器使用,而不仅仅作为轻量级应用服务器。在这种情况下,Java将不再是一门侧重于后端的编程语言,也可以更多的用于成熟的Web服务器平台。 Excutor重要参数说明:
- name:共享线程池的名字,这是connector为了共享线程池要引用的名字,改名字必须唯一
- namePrefix:在JVM上,每运行线程都可以有一个name字符串,这一属性为线程池中每个线程的name字 符串设置了一个前缀,Tomcat将把线程号追加到这一前缀后面,默认值为tomcat-exec-
- maxThreads:该线程池可以容纳的最大线程数,默认200
- maxIdleTime:在Tomcat关闭一个空闲线程之前,允许空闲线程持续的时间(单位为毫秒)。只有当前 活跃的线程数大于minSpareThread的值,才会关闭空闲进程,默认值60000,一分钟
- minSpareThreads:Tomcat应该始终打开的最小不活跃线程数,默认25
- threadPriority:线程的等级 Connector重要参数说明
- executor:表示使用参数值对应的线程池
- minProcessors:服务器启动时创建的处理请求的线程数
- maxProcessors:最大可以创建的处理请求的进程数
- acceptCount:指定当前所有可以使用的处理请求的线程数都被使用时,可以放到处理队列中的请求数, 超过这个数的请求不予处理 处理方式 org.apache.coyote.http11.Http11NioProtocol :表示nio处理类 org.apache.coyote.http11.Http11AprProtocol :表示apr 模式 HTTP/1.1 : 表示bio模式 APR提供的主要功能模块包括:内存分配及内存池、原子操作、文件I/O、锁、内存映射、哈希表、网络 I/O、轮询、进程及线程操作等等,通过采用APR,Tomcat可以获得高度可扩展性以及优越的性能,并且 可以更好的与本地服务器技术集成,从而可以使Tomcat作为一款通用的Web服务器使用,而不仅仅作为 轻量级应用服务器。在这种情况下,Java将不再是一门侧重于后端的编程语言,也可以更多的用于成熟 的Web服务器平台。
- /usr/local/tomcat/conf/server.xml 修改
- 重启tomcat 3.查看端口