Tomcat他山之石.可以攻玉(一)Server组件
Server组件
Server组件作用:
- 采用观察者模式,又叫源-收听者的设计模式,提供了可以动态添加、删除的监听器,作用是在Server组件的不同生命周期中完成不同的功能、逻辑;
- Tomcat容器的全局命名资源实现
- 提供关闭Tomcat方式(接收端口收到的SHUTDOWN命令).
Server组件监听器
Server组件监听器默认是六个
- NamingContextListener
- VersionLoggerListener
- AprLifecycleListener
- JreMemoryLeakPreventionListener
- GlobalResourcesLifecycleListener
- ThreadLocalLeakPreventionListener
Server组件监听器说明
监听器的作用就是在Tomcat各个组件如Server、Service、Context的某个生命阶段完成某些逻辑处理而出现, 使用方式 实现LifecycleListener接口,加入到组件的监听器集合中addLifecycleListern,逻辑处理写在LifecycleListener实现类的lifecycleEvent中。
1. NamingContextListener
NamingContextListener监听Tomcat启动之前、结束之前进行逻辑处理,在Tomcat启动之前创建、绑定命名资源,在Tomcat结束之前解绑命名资源,这个主要涉及到Ejb、JNDI等,全局命名资源存放在Server的globalNamingResources中,全局命名资源的意义:比如JNDI,在weblogic中资源名为jdbc/nbrSz,在Tomcat中就需要使用全局命名资源来访问,全局命名资源创建、绑定、解绑等工作就是由NamingContextListener来完成.
2.VersionLoggerListener
针对Tomcat初始化之前进行必要的日志操作,主要打印版本信息、机器环境信息;

3.AprLifecycleListener
Tomcat可以使用本地APR进行调优,调用本地库提高对静态文件处理能力。 AprLifecycleListener主要针对Tomcat初始化之前、销毁之后进行操作,初始化之前尝试初始化APR库,成功则使用APR接受处理客户端请求;Tomcat销毁之后,该监听器会做APR的清理工作.
4.JreMemoryLeakPreventionListener
该监听器主要用来解决内存泄露和锁文件,在Tomcat初始化之前使用系统类加载器加载一些类,并且设置缓存属性来达到避免内存泄露和锁文件的目的。
内存泄露,垃圾回收机制,如果一个想要回收对象被另外一个生命周期很长的对象一直引用着,GC是无法回收这个“垃圾对象”。还一种内存泄漏因为类加载器导致的,JRE库中某些类运行时以单例存在,从程序启动到关闭。JRE库这些类使用上下文类加载器加载,保留了上下文类加载器的引用,就导致了被引用的类加载器无法回收。 Tomcat部署多个Web应用使用不同的上下文类加载器,旧的上下文类加载器无法被回收,就导致了内存泄露。
比如DriverManager.getDrivers(); 在某个Web应用中我们调用这句话,数据库驱动以单例形式存在,持有这个web应用的上下文类加载器,后面部署另外的Web应用,每个加载JRE中单例类的
类加载器,后面都会变成无法被回收的对象,导致内存泄露。
除了上面的JRE单例导致类加载器无法被回收以外,还一种情况就是,JRE中某些类,线程加载它的时候会创建新的线程并且无线循环,新的线程上下文类加载器会继承父线程的类加载器,新线程就包含上下文类加载器,导致父类上下文类加载器无法被回收,内存泄露问题出现,比如某上下文类加载器加载Disposer类。
JreMemoryLeakPreventionListener就是防止JRE内存泄露问题,解决方案就是先将当前线程类加载器保存起来,用系统类加载器去加载这些会导致JRE内存泄露的类, 这样做以后比如Web应用用到这些类,双亲委派模型在系统类加载器中找到了就不会再加载一遍防止内存泄露,加载完成这些隐患的类后再讲原来的类加载器还原。 其他可能导致内存泄漏的类:ImageIO.getCacheDirectory()、 java.awt.Toolkit.getDefaultToolkit()、sun.misc.GC、甚至j解析xml的DocumentBuilderFactory,这些类在JreMemoryLeakPreventionListener都有出现。

锁文件情景主要是在Windows下使用URLConnection读取本地jar包内资源时,会将jar包内容缓存起来,当重新部署jar包会失效,还是读取的旧的资源。
JreMemoryLeakPreventionListener解决方案Tomcat初始化之前实例化URLConnection且禁用默认缓存即可。

5.GlobalResourcesLifecycleListener
GlobalResourcesLifecycleListener监听Tomcat容器的启动、销毁,Tomcat启动时GlobalResourcesLifecycleListener实例化JNDI资源的MBean,Tomcat停止时销毁MBean.
6.ThreadLocalLeakPreventionListener
ThreadLocalLeakPreventionListener监听Tomcat容器启动后、停止前、停止后,目的是为了防止ThreadLocal对象带来的内存泄漏问题。
ThreadLocal带来的内存泄露问题,Tomcat内部接收请求都是通过线程池的方式处理,线程池中线程生命周期一般都长,比如某个Web应用A,经常使用ThreadLocal保存一些信息A,A又是由Web应用的WebappClassLoader加载的, 假设部署新的Web应用,实例化了新的WebappClassLoader,线程池中线程一直在运行着或等待着,但是旧的WebappClassLoader由于A保留着引用无法被回收,这样就导致了内存泄露。
解决方案就是当新的Web应用部署时,将所有的线程池内所有线程销毁并且重新创建新的线程。
程序方式结束Tomcat
除了可执行脚本bat/sh方式结束Tomcat,Tomcat还提供我们一种程序的方式结束Tomcat:
当程序部署在Tomcat中,我们只需要能够执行下面代码,就能够结束Tomcat的一生:
public class ShutDownCli {
public static void main(String[] args) throws IOException {
Socket socket = new Socket("localhost",8005);
OutputStream os = socket.getOutputStream();
os.write("SHUTDOWN".getBytes());
socket.close();
}
}
原理就是 Tomcat启动后主线程和守护线程两种,主线程一直在监听server.xml中<Server>的port,也就是8005端口,而守护线程才是用来接收请求并处理的。主线程8005端口收到SHUTDOWN命令,主线程执行Tomcat关闭并退出,主线程结束,Tomcat就结束了。
Tomcat他山之石.可以攻玉(一)Server组件的更多相关文章
- 查看tomcat启动文件都干点啥---server对象
在上一章查看tomcat启动文件都干点啥---Catalina.java中说道了构造Server,,这次尝试着说一下Tomcat中Server的内容,首先看一下org.apache.catalina. ...
- 查看Windows服务器安装了那些SQL Server组件
如何查看Windows服务器安装了那些SQL Server组件呢? 最近就遇到这样一个需求,需要知道Windows服务器是否安装了Replication组件,那么有几种方法查看Windows服务器安装 ...
- 启动tomcat出现Removing obsolete files from server... Could not clean server of obsolete ……错误
在Eclipse启动tomcat出现"Removing obsolete files from server... Could not clean server of obsolete …… ...
- windows media server 组件安装后流媒体服务器启动失败
做好的web应用,去客户现场部署的时候发现流媒体服务器不能启动.(现场服务器系统为windows server2008 R2) 自己测试的时候搭建环境没什么问题.从来没有遇到安装windows med ...
- 安装或删除Skype for business server组件的时候,报错"错误: 找不到 SQL 服务"
安装或删除Skype for business server组件的时候,到了安装所有并置数据库的时候,报错“错误: 找不到 SQL 服务.确保计算机 skype.centos.com 中安装了 SQL ...
- 安装skype for business server组件 报错“未满足先决条件”和安装KB2982006补丁提示“此更新不适用于你的计算机”
安装skype for business server组件 报错“未满足先决条件” 上网经查询发现是没有安装KB2982006-x64 更新补丁 去官网上找这个补丁,发现这个补丁要热更新啥的,还要写邮 ...
- 用msi安装MySQL时MySQL Server组件不能安装,或安装失败
我的环境: MySQL8.0.15, win10 错误描述:在安装MySQL时,如果MySQL Server组件提示不能安装,错误提示是:VS 2015没有安装或安装失败.原因 ...
- 加薪攻略之UI组件库实践—storybook
目录 加薪攻略之UI组件库实践-storybook 一.业务背景 二.选用方案 三.引入分析 项目结构 项目效果 四.实现步骤 1.添加依赖 2.添加npm执行脚本 3.添加配置文件 4.添加必要的w ...
- 【学习篇:他山之石,把玉攻】jquery实现调用webservice
1.webservice端 using System; using System.Collections.Generic; using System.Web; using System.Web.Ser ...
随机推荐
- Notes : <Hands-on ML with Sklearn & TF> Chapter 7
.caret, .dropup > .btn > .caret { border-top-color: #000 !important; } .label { border: 1px so ...
- 两种 js下载文件的方法(转)
function DownURL(strRemoteURL, strLocalURL){ try{ var xmlHTTP = new ActiveXObjec ...
- Runnable与Callable区别
相同点: 两者都是接口:(废话) 两者都可用来编写多线程程序: 两者都需要调用Thread.start()启动线程: 不同点: 两者最大的不同点是:实现Callable接口的任务线程能返回执行结果:而 ...
- HTML和CSS初级前端面试题汇总(持续补充)
1.浏览器内核 IE:trident Firefox:gecko Safari:webkit Opera:以前是presto,现在是Blink Chrome:Blink 2.HTML文件开头的DOCT ...
- 关于select的使用感受~大坑~select不能添加点击事件触发~
这是一个坑,把我摔惨了! select+option是浏览器自带的下拉选项框,样式及其丑,还好现在有很多框架都相应做了些美化,select 元素是一种表单控件,可用于在表单中接受用户输入. 还有一个重 ...
- 初识大数据(二. Hadoop是什么)
hadoop是一个由Apache基金会所发布的用于大规模集群上的分布式系统并行编程基础框架.目前已经是大数据领域最流行的开发架构.并且已经从HDFS.MapReduce.Hbase三大核心组件成长为一 ...
- jquery向Django后台发送数组
在$.ajax中加入 traditional:true, //加上此项可以传数组 后端用 array = request.POST.getlist('ids') #django接收数组 来接收数组
- android 图形图像
Canvas 画布 paint 画笔 Path 路径Path代表任意多条直线连接而成的任意图形,当Canvas根据Path绘制时,它可以绘制出任意的形状 使用 Matrix 控制图像或组件变换步骤:① ...
- ubuntu设置ssh登录
1.为ubuntu添加root用户(其实Ubuntu中的root帐号默认是被禁用了的,所以登陆的时候没有这个账号),打开初始账号,输入命令:sudo passwd root,设置root的密码 2.切 ...
- UML顺序图知识点介绍(Sequence Diagram)
消息 调用消息 调用(procedure call)消息的发送者把控制传递给消息的接收者,然后停止活动,等待消息接受者放弃会返回控制 在Rational Rose(2016版本如图所示) 异步消息 异 ...