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 ...
随机推荐
- k8s1.13.3安装istio(helm方式)
官方文档:https://istio.io/zh/docs/setup/kubernetes/install/helm/ 一.环境信息 centos7 k8s1.13.3 主机名 ip cpu ram ...
- ceph删除pool提示(you must first set the mon_allow_pool_delete config option to true)解决办法
现象: 1.在mon节点打开/etc/ceph/ceph.conf,增加以下 2.重启ceph-mon systemctl restart ceph-mon.target 3.删除pool [root ...
- Lua5.2&Lua5.3中废除的方法
Lua5.2和Lua5.3中居然把 table.getn() 废除了, webAdd = {"QQ", "BaiDu", "SMW"} fo ...
- mqtt mosquitto 源码安装
下载地址 ububtu : wget https://codeload.github.com/eclipse/mosquitto/zip/master 安装依赖 sudo apt-get insta ...
- 在Ubuntu16上安装mininet和floodlight过程,超全篇
第一歩:更改root密码 第二歩:更新源 sudo apt-get update.sudo apt-get upgrade 第三步:安装git sudo apt install g ...
- linux系统下安装redis以及java调用redis
关系型数据库:MySQL Oracle 非关系型数据库:Redis 去掉主外键等关系数据库的关系性特性 1)安装redis编译的c环境,yum install gcc-c++ 2)将redis-2. ...
- Redis-05.主从复制与Sentinel
主从复制(master/slave) 主机(master)数据更新后根据配置和策略,自动同步到备机(slave).通过主从复制,能够实现读写分离.容灾恢复. 实现主从复制非常简单,只需要在从(slav ...
- 英语演讲稿——Get Along with Fear
Hi. My name is Zhang Meng. I’m an engineer at Keysight. Today I’m not going to introduce my birthpla ...
- VS 快捷键使用
代码注释与整理 Ctrl+K+C:注释所选代码块 Ctrl+K+U:取消代码块注释 Ctrl+K+D:整理对齐整个代码区 Ctrl+K+F:整理对齐所选代码块 选择代码 Home:跳转行首 End:跳 ...
- Python自动化编程-树莓派的介绍与使用(一)
Raspberry Pi(中文名为“树莓派”,简写为RPi,(或者RasPi / RPI) [1] 是为学习计算机编程教育而设计),只有信用卡大小的微型电脑,其系统基于Linux. 随着Windo ...