暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

Tomcat部署系统之我见

中间件技术讨论圈 2017-01-18
148

笔者从事应用服务器的领域多年,原来经历过2-3次应用服务器的部署改造,Tomcat的部署功能可以说不是很完善,笔者根据经验通过本文讲述一下,JAVA EE应用服务器通常是怎么做应用部署的;


1.区分热部署,自动部署,部署,解部署等名词


部署:

一个应用调用部署接口,部署接口将应用进行扫描解析,并查找当前war包中的xxx标签,将一个应用解析为内存对象,例如Tomcat中就是以StandardContext这种对象存在;

在应用请求访问的时候,请求到当前的应用,路由到应用内存对象中,拿已经解析的内存metadata的属性,查询信息,执行结果并返回;

Tomcat中的HostConfig一系列的deployWar,deployApplication,deployContextDescription方法都是


解部署:

应用部署之后解析之后生成的应用内存对象,在Tomcat中就是StandardContext这种对象,对应应用的卸载,将这个对象从内存中干掉,这样在查询应用列表就查不到当前应用了;

Tomcat中的HostConfig的undeploy方法


应用启动:

应用内存对象生成并不意味着,能够接受应用的请求访问,需要准备一下,初始化创建很多资源,如JNDI资源的准备,ref准备等等,关于这些准备就是在启动时进行的;

在Tomcat中,其实就是StandardContext的生命周期lifecycle的startInternal方法中的内容;


应用停止:

和应用启动相反;

但通常不同的应用服务器对于应用停止的理解是不一样的,因为毕竟一个应用启动的过程中,会创建n多的资源,而你在停止的时候,好不容易把这些资源给干掉,来回创建资源是很费事的;

所以,有的应用服务器通过一个标识来做应用的启动和停止的开关,这个开关用于应用请求中,当请求路由到应用内存对象的时候,如果该标识为false,那么代表着应用已经停止,请求这时候就会返回了;

在Tomcat中实现为pause属性,详细见context.reload


重部署:

重部署其实很简单,就是先解部署,再部署,上述的两个接口之间的组合关系;

但是比较高明的应用服务器的重部署做的确实很不错,很多资源是可以重复利用的,不是完全按照解部署再重部署去做;

Tomcat中的重部署接口抽取的不好,但可以看出就是先进行undeploy,再调用deployApps;

上述的5个接口构成了接口层。


自动部署:

如果说前面的5个是部署接口的话,自动部署就是一个机制;

该机制是搞一个目录,这个目录通过程序进行周期性的扫描,然后基于下列三种情况,调用前面的几个接口:

1.如果发现该目录有新文件,那么调用部署接口继续部署

2.如果发现该目录文件的时间戳发生变化,或者context.xml发生变化,那么调用重部署接口进行重部署

3.如果发现该目录的对应文件消失,那么调用解部署接口进行应用解部署

该目录叫做自动部署目录;


管理控制台部署:

其实很简单,就是大家经常在界面上上传一些war包等文件,这一步有一个upload的过程,利用的html页面的file组件,

上传到一个目录中,然后一般程序调用部署接口进行部署。


应用部署目录:

区别于自动部署目录,应用部署目录应该是一个独立的目录,该目录不存在自动部署周期性的扫描;

无论是管理控制台部署,还是自动部署,甚至你用程序JMX远程直接调用部署接口,无论啥招,应用部署目录中都应该存在该部署的应用,上述的5个接口都是从该位置开始进行部署的;

当然有一种情况除外,就是你需要指定一个目录部署,这个就是Tomcat中的DocBase的了


启动部署:

随着应用服务器的启动,如果在应用部署目录和配置文件中有对应的应用需要部署的话,那么随着应用服务器的启动,这些这些应用直接就会部署起来;


热部署:

所谓的热部署是在当前应用部署目录中启动的一个线程,该线程和自动部署的线程一样,也是周期定期的扫描;

但是这种扫描内容不是看看目录中有没有增减,部署描述文件是否发生变化,进而发生重部署等耗时操作

热部署要的是高效,深入监听的扫描应用中的classes等资源,如果发现资源一旦变化,能最大程度的让应用恢复到最新的状态;

如果要用Tomcat去解释的话,那么Tomcat的Context.reload就是一个典型的热部署;


2.应用部署的设计


对于一般的应用服务器来说,有如下的设计能满足应用部署系统的设计:


管理控制台调用部署接口层开放出来的JMX,restful等接口进行部署;

自动部署也是调用部署接口层的部署,解部署,重部署接口;

热部署调用的是reload方法;

启动部署调用的是部署接口层开放出来的部署接口;

当然,如果在一个JVM下,就没有必要搞什么JMX和restful了,损失性能和效率;

上图的右侧是应用部署流程:

1.应用包的解析:查看该应用是否是符合JAVA EE格式,如war包的格式,即使是目录的话,也应该看看是否有WEB-INF/classes这种目录;

2.应用 服务器部署描述符扫描:一般应用服务器都会带一些自己的特有的部署配置,这个配置就被叫做部署描述符,tomcat中也有,就是context.xml文件;

3.JAVA EE规范配置文件扫描:如web.xml这种,manifest.mf这种

4.原注释扫描:自从JAVA EE5之后,开始有一些原注释放在类当中,如servlet3.0规范@Servlet这种,都需要进行扫描

5.基于前面几个步骤,可以生成一些应用内存对象,如Tomcat中的StandardContext

6.应用这个时候需要准备启动类,单纯类似StandardContext还不够,例如应用中需要用到的一些资源信息,如JNDI资源,数据源的ref都要准备好

7.应用准备就绪,加入到应用服务器的应用列表中,在Tomcat中也就是Wrapper列表中,Tomcat中可以通过Mapper进行访问了



3.评价一下Tomcat的部署

1.Tomcat的部署功能并没有将这些接口都非常清晰的抽取出来,应该抽取出来

2.Tomcat中的自动部署目录和应用部署目录重合了(当然你部署在外面就另当别论了)

3.正因为目录重合了,自动部署功能和应用部署目录重合,所以自动部署和reload的东西有点傻傻的分不清,

4.自动部署目录中的war包解析完事,如果按照一般的JAVA EE应用服务器的做法,应该将其转移到应用部署目录中,

5.Tomcat的管理控制台很弱,提供最基础的功能


总结:

总体而言,Tomcat的部署系统虽然从设计角度算不上高明,但是麻雀虽小,五脏俱全,该有的都有,不过对于商用的应用服务器的部署系统要比tomcat健全的多,功能要多,并且设计也更为合理一些,不过tomcat作为一个开源项目,只要能用并且保持稳定其实就行了;


文章转载自中间件技术讨论圈,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论