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 ...
随机推荐
- C#运行时通过字符串实例化类对象
备忘,记个C#版本. using System; using System.Collections.Generic; using System.Linq; using System.Text; usi ...
- linux nfs远程挂载和卸载
一.nfs远程挂载 1.首先确定服务端(实体挂载节点)的IP 2.通过cat /etc/hosts 查看服务端的server name 3.mount -t nfs servername:/挂载文件 ...
- python模块:subprocess
# subprocess - Subprocesses with accessible I/O streams # # For more information about this module, ...
- HTTP协议 与 TCP协议 的区别
TCP协议是传输层协议,主要解决数据如何在网络中传输,而HTTP是应用层协议,主要解决如何包装数据. TCP/IP和HTTP协议的关系,从本质上来说,二者没有可比性,我们在传输数据时,可以只使用(传输 ...
- js之Ajax下载文件
传统上,客户端将依靠浏览器来处理从服务器下载文件.然而,这种方法需要打开一个新的浏览器窗口,iframe或任何其他类型的不友好和黑客行为.为下载请求添加额外的头信息也很困难.更好的解决方案是使用HTM ...
- Python3--Numpy
数组的形状是它有多少行和列,上面的数组有5行和5列,所以它的形状是(5,5). itemsize属性是每个项占用的字节数.这个数组的数据类型是int 64,一个int 64中有64位,一个字节中有8位 ...
- Note on Preliminary Introduction to Distributed System
今天读了几篇分布式相关的内容,记录一下.非经典论文,非系统化阅读,非严谨思考和总结.主要的着眼点在于分布式存储:好处是,跨越单台物理机器的计算和存储能力的限制,防止单点故障(single point ...
- Python爬虫的学习经历
在准备学习人工智能之前呢,我看了一下大体的学习纲领.发现排在前面的是PYTHON的基础知识和爬虫相关的知识,再者就是相关的数学算法与金融分析.不过想来也是,如果想进行大量的数据运算与分析,宏大的基础数 ...
- window7 32位部署django
window7 32位安装环境,所有的软件都用32位的,如果你想要用64位的软件需要操作系统和下面的相关软件都换成64位,我是在虚拟机上装了win7 32版做的测试. 软件下载地址: python2. ...
- 在已有数据的表中添加id字段并且自增
各位大牛,小弟在开发过程中,遇到了这样一个问题,由于新功能的增加需要使原有的一张表的结构作出调整,需要添加一个id主键字段,但是因为表里有很多数据了,所以,怎样才能添加这个字段,并且使原有的数据也能够 ...