Server组件

Server组件作用:

  • 采用观察者模式,又叫源-收听者的设计模式,提供了可以动态添加、删除的监听器,作用是在Server组件的不同生命周期中完成不同的功能、逻辑;
  • Tomcat容器的全局命名资源实现
  • 提供关闭Tomcat方式(接收端口收到的SHUTDOWN命令).

Server组件监听器

Server组件监听器默认是六个

  1. NamingContextListener
  2. VersionLoggerListener
  3. AprLifecycleListener
  4. JreMemoryLeakPreventionListener
  5. GlobalResourcesLifecycleListener
  6. 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组件的更多相关文章

  1. 查看tomcat启动文件都干点啥---server对象

    在上一章查看tomcat启动文件都干点啥---Catalina.java中说道了构造Server,,这次尝试着说一下Tomcat中Server的内容,首先看一下org.apache.catalina. ...

  2. 查看Windows服务器安装了那些SQL Server组件

    如何查看Windows服务器安装了那些SQL Server组件呢? 最近就遇到这样一个需求,需要知道Windows服务器是否安装了Replication组件,那么有几种方法查看Windows服务器安装 ...

  3. 启动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 …… ...

  4. windows media server 组件安装后流媒体服务器启动失败

    做好的web应用,去客户现场部署的时候发现流媒体服务器不能启动.(现场服务器系统为windows server2008 R2) 自己测试的时候搭建环境没什么问题.从来没有遇到安装windows med ...

  5. 安装或删除Skype for business server组件的时候,报错"错误: 找不到 SQL 服务"

    安装或删除Skype for business server组件的时候,到了安装所有并置数据库的时候,报错“错误: 找不到 SQL 服务.确保计算机 skype.centos.com 中安装了 SQL ...

  6. 安装skype for business server组件 报错“未满足先决条件”和安装KB2982006补丁提示“此更新不适用于你的计算机”

    安装skype for business server组件 报错“未满足先决条件” 上网经查询发现是没有安装KB2982006-x64 更新补丁 去官网上找这个补丁,发现这个补丁要热更新啥的,还要写邮 ...

  7. 用msi安装MySQL时MySQL Server组件不能安装,或安装失败

    我的环境:       MySQL8.0.15,       win10 错误描述:在安装MySQL时,如果MySQL Server组件提示不能安装,错误提示是:VS 2015没有安装或安装失败.原因 ...

  8. 加薪攻略之UI组件库实践—storybook

    目录 加薪攻略之UI组件库实践-storybook 一.业务背景 二.选用方案 三.引入分析 项目结构 项目效果 四.实现步骤 1.添加依赖 2.添加npm执行脚本 3.添加配置文件 4.添加必要的w ...

  9. 【学习篇:他山之石,把玉攻】jquery实现调用webservice

    1.webservice端 using System; using System.Collections.Generic; using System.Web; using System.Web.Ser ...

随机推荐

  1. css样式表的知识点总结

    css总的来说有三种css样式可供选择: 1,行内样式表 行内样式表,直接写在了html文件的元素中,例如: <div style="color:red;"></ ...

  2. PHP中this,self,parent的区别

    {一}PHP中this,self,parent的区别之一this篇 面向对象编程(OOP,Object OrientedProgramming)现已经成为编程人员的一项基本技能.利用OOP的思想进行P ...

  3. Unity打包提示UnityEditor.BuildPlayerWindow+BuildMethodException: Build failed with errors.错误

    不要将打包的输出路径设置为Assets文件夹下面即可,MD真坑 老外给出的解释: As you have noticed after you click build settings you are ...

  4. golang使用 gzip压缩

    golang使用 gzip压缩 这个例子中使用gzip压缩格式,标准库还支持zlib, bz2, flate, lzw 压缩处理_三步: 1.创建压缩文件2.gzip write包装3.写入数据 ou ...

  5. Unity3D中默认函数的执行顺序

    直接用一张图来说明各个默认函数的执行顺序: FixedUpdate以固定的物理时间间隔被调用,不受游戏帧率影响.一个游戏帧可能会调用多次FixedUpdate.比如处理Rigidbody的时候最好用F ...

  6. 因为曾经装过Mysql导致再次装时windows无法启动MySQL服务报错1067的解决方法

    找到这里 MySQL右击属性 检查这里的可执行文件的路径是否正确,因为我这里显示的是原先的文件夹所以会一直启动失败,修改一下 这里你去百度经验 windows服务修改可执行文件路径 网址https:/ ...

  7. Android插件化的兼容性(中):Android P的适配

    Android系统的每次版本升级,都会对原有代码进行重构,这就为插件化带来了麻烦. Android P对插件化的影响,主要体现在两方面,一是它重构了H类中Activity相关的逻辑,另一个是它重构了I ...

  8. 史上最完整的MySQL注入

    原文作者: Insider 免责声明:本教程仅用于教育目的,以保护您自己的SQL注释代码. 在阅读本教程后,您必须对任何行动承担全部责任. 0x00 ~ 背景 这篇文章题目为“为新手完成MySQL注入 ...

  9. Java开发微服务为什么一定要选spring cloud?

    来自:网易乐得技术团队,作者:董添 李秉谦 现如今微服务架构十分流行,而采用微服务构建系统也会带来更清晰的业务划分和可扩展性.同时,支持微服务的技术栈也是多种多样的,本系列文章主要介绍这些技术中的翘楚 ...

  10. Python学习笔记【第五篇】:基础函数

    一.函数:函数定义关键字def  后跟函数名称 def 函数名(参数):             ...     函数体     ...     返回值 案例: # 定义函数 def say_hei( ...