JBossApplicationServer的启动过程.doc

上传人:sk****8 文档编号:3533962 上传时间:2019-06-02 格式:DOC 页数:9 大小:61.50KB
下载 相关 举报
JBossApplicationServer的启动过程.doc_第1页
第1页 / 共9页
JBossApplicationServer的启动过程.doc_第2页
第2页 / 共9页
JBossApplicationServer的启动过程.doc_第3页
第3页 / 共9页
JBossApplicationServer的启动过程.doc_第4页
第4页 / 共9页
JBossApplicationServer的启动过程.doc_第5页
第5页 / 共9页
点击查看更多>>
资源描述

1、JBoss Application Server 的启动过程本文以 JBoss Application Server 4.2.1 GA(以下简称 JBoss)为例,介绍它在Windows 平台上的启动过程。为了方便叙述,对平台环境做以下假定:Java 运行时的安装路径为 C:Java,JBoss 的安装路径为 C:JBoss。 既然用 100% Java 编写的 JBoss 具有跨平台的特性,那为什么还要强调 Windows平台呢?这是因为,JBoss 的启动是从平台相关的脚本文件开始的,而在不同平台上的脚本文件是不同的。例如,Window 平台上的脚本文件是 run.bat,linux 平台

2、上的脚本是 run.sh。两个文件的内容有很大不同,功能也许差不多,无非是配置启动环境,但是也有可能存在平台相关的因素。我只看了 run.bat,对 run.sh 并不了解,为谨慎起见,我只介绍 run.bat,对 run.sh 不作阐述。在介绍 JBoss 启动过程之前,我想先介绍一下 JBoss 的结构特征,这将有利于大家理解启动过程。JBoss 基于 JMX 框架,它的结构就是一个 MBeanSserver 以及一些挂在 MBeanServer 上的 MBean。MBean 提供功能,MBeanServer 是 MBean 之间的通信总线。JMX 框架的好处就是给 JBoss 带来了高度

3、的灵活性、可配置性。可配置性也是 JBoss 的核心理念之一,几乎所有的 JBoss 部件都可以被替换。JBoss 通过系统属性、配置文件等多种方法,帮助实现高度的可配置性。我们可以通过设置系统属性,或者通过编辑配置文件,来定制自己的 JBoss 版本。这种可配置性体现在 JBoss 的各个角落,启动过程只能窥一斑,若欲知全豹,可以研究一下 JBoss 的EJB 容器等其它部件。介绍完 JBoss 的结构特征,我们开始进入 JBoss 的启动过程。整个过程可以分为六个阶段,下面将依次介绍。一、执行启动脚本,配置启动环境JBoss 的启动过程从执行 run.bat 开始,run.bat 的主要工

4、作就是配置启动环境。JBoss 的启动环境其实是一些启动参数,例如 JBoss 的安装路径、java 命令的参数、JBoss 的类路径等。如果在配置过程中发生错误,run.bat 的执行将被中断。run.bat 将配置以下启动参数:JBOSS_HOME JBoss 的安装路径,其值为 C:JBossPATH将 C:JBossbinnative 添加到 PATH 中,native 下的文件是平台相关的,可以优化JBoss 的性能。JAVA java.exe 文件的路径,其值为 C:JavabinjavaJAVA_OPTSBjava 命令的参数,其值为-Dprogram.name=run.bat

5、server-Xms128m Xmx512m Dsun.rmi.dgc.client.gcInterval=3600000 Dsun.rmi.dgc.server.gcInterval=3600000JBOSS_CLASSPATHJBoss 的启动类路径,其值为 C:Javalibtools.jar;C:JBossbinrun.jar。JBoss 的启动前期需要的类文件都在这两个 jar 中。如果没有设置系统环境变量 JAVA_HOME,那么 run.bat 的执行将被中断,JBoss启动失败。因此,在安装好 JBoss 后,一定要设置 JAVA_HOME 系统环境变量。如果 run.bat

6、执行顺利,那么在最后,将会执行以下命令:C:Javabinjava -Dprogram.name=run.bat server-Xms128m Xmx512m Dsun.rmi.dgc.client.gcInterval=3600000 Dsun.rmi.dgc.client.gcInterval=3600000 -Djava.endorsed.dirs=C:JBosslibendorsed classpath C:Javalibtools.jar;C:JBossbinrun.jar org.jboss.Main%*%*代表 run.bat 后面的启动参数。从这条命令开始,真正运行 JBoss

7、 的代码。二、JBoss 启动的入口JBoss 的魔术从 Main.main 方法开始。Main 这个类位于 run.jar 中。Main.main 方法创建了一个名为”jboss ”的线程组,然后创建并运行该线程组的线程”main”。”main”线程开始运行后,Main.main 方法执行完毕,主线程也随之结束。”main”线程的主要工作是调用 Main.boot 方法。Main.boot 方法的主要工作是处理命令行参数,然后创建并运行一个服务器实例。当服务器实例开始运行后,jboss 的启动过程也就成功结束了。下面的几个阶段都是 boot 方法的执行过程。三、处理命令行参数boot 方法调

8、用 Main.processCommandLine 方法,来处理命令行参数。这里的命令行参数其实就是 main 方法的 args 参数,它作为实参传递给 processCommandLine 方法。processCommandLine 方法使用了 GNU-getopt 程序包来解析命令行参数,对不同的命令行参数有不同的处理方式,简单概括如下:部分参数被简单处理后,程序直接退出。这些参数包括:-h 显示帮助消息。-V 显示版本信息。版本信息从 run.jar 中的 MANIFEST.MF 文件中获得。部分参数被保存在服务器属性(Main.props)中,这些参数包括:-p 补丁目录。-n 从网络

9、启动的 url。-c 服务器配置的名称,预定义的有三种,minimal、default 和 all。当然也可以自定义。-b 所有 JBoss 服务绑定的地址,如果需要从其它机器访问 JBoss 服务,则必须配置该参数。-g HA 分区的名称-u UDP 多播地址部分参数被保存在 Main 的成员变量中,这些参数包括:-d 启动补丁目录 保存在 URL bootURL 中-B 添加到启动类路径的额外的库 保存在 List bootLibraries 中-L 添加到类加载路径的额外的库 保存在 List extraLibraries 中-C 添加到类加载路径的额外的 url 保存在 List ex

10、traClasspath 中部分参数被保存在系统属性中,这些参数包括:-D 系统属性-P 从给定 url 加载的属性-l 指定日志插件类性,目前有 log4j 和 jdk 两种。processCommandLine 方法执行完毕后,boot 方法将加载、创建并运行一个服务器实例。四、加载并创建服务器实例服务器实例是一个运行时对象,这个对象代表了运行着的 JBoss 应用服务器。启动一个 JBoss 应用服务器,就会有一个服务器实例与之对应。在 JBoss 中,服务器实例的实现是可以配置的,也就是说,服务器类不是固化的,而是可以替换的。这就带来一个问题:JBoss 必须在启动的过程中搜索并加载服

11、务器类。搜索并加载服务器实例类的工作由一个辅助类完成,它的全限定类名是org.jboss.system.server.ServerLoader。这个类会创建一个特定的类加载器,并使用这个类加载器加载服务器类,然后利用反射机制,创建一个服务器实例。boot 方法首先创建一个 ServerLoader 实例,我们把它称为 loader,然后 boot 方法将一些 url 添加到 loader 中。我们把这些 url 称为服务器搜索路径。loader 就是在服务器搜索路径中搜索服务器类。服务器搜索路径包括:bootURL 由-d 参数提供。如果 bootURL 是文件目录,则其下的 jar 的 ur

12、l 也被添加。bootLibraries 由-B 参数提供。Endorsed jars 位于 C:JBosslibendorsed 下的所有 jar 包。jmxLibs C:JBosslibjboss-jmx.jar。concurrentLib C:JBosslibconcurrent.jar。extraLibraries 由-L 参数提供。extraClasspath 由-C 参数提供。loader 自带的 url log4j-boot.jar、jboss-common.jar、jboss-system.jar、jboss-xml-binding.jar。添加完服务器搜索路径后,boot 方

13、法调用了 loader 的 load 方法。load 方法以服务器搜索路径作为参数,创建一个类加载器,并使用它搜索和加载服务器类。如果成功加载,就利用放射机制,创建一个服务器实例,我们把它称为 server。默认的服务器类是 org.jboss.system.server.ServerImpl,它位于 C:JBosslibjboss-system.jar 中,并不在 jboss 的类路径中。因此, loader 必须创建自己的类加载器,使用服务器搜索路径作为类搜索路径,才能够找到 ServerImpl。通过设置jboss.server.type 系统属性,也可以使用自定义的服务器类。当然,前提

14、是要保证自定义的服务器类的类文件要在服务器搜索路径中。服务器实例创建完毕后,还需要对它进行配置,这就是下面的初始化工作。五、初始化服务器实例初始化服务器实例的主要工作就是将服务器配置信息封装到一个对象中。这个对象是类 org.jboss.system.server.ServerConfigImpl 的实例。它包括了服务器实例的基本配置信息,例如 JBoss 的安装路径、服务器的根目录、服务器的日志目录、服务器的临时目录、服务器的库路径等。boot 方法调用 server 的 init 方法,开始初始化工作。Init 方法将初始化工作委派给server.doInit 方法。doInit 方法创建

15、并配置 ServerConfigImpl 对象,并在最后在控制台和日志中打印出服务器的配置信息。ServerConfigImpl 对象是一个 MBean,因此,用户可以利用 jmx 控制台查看服务器实例的配置信息。初始化完毕后,就要启动服务器实例了。六、启动服务器实例启动服务器实例是一个复杂的过程,其中有很多的工作需要完成。前面已经提到,JBoss 是基于 JMX 框架的, JBoss 的主要功能都是以 MBean 的形式作为服务提供的,服务之间利用 JMX 总线进行通信。直到目前为止,我们还没有看到 JMX 相关的工作。因此,在服务器实例的启动过程中,首要的工作就是要搭建 JMX 框架。JM

16、X 框架搭建完毕后,JBoss 需要创建几个基本的服务,这些服务正是以 MBean的形式,挂在 JMX 框架上。之后,JBoss 开始了部署过程。 JBoss 预配置的服务、用户的部署单元都在这个阶段被部署、启动。boot 方法调用 server.start 方法,开始了启动过程。 start 方法将启动工作委派给了server.doStart 方法。doStart 方法依次完成以下工作:1. 创建并启动计时器这个计时器是用来计算 JBoss 启动的时间,JBoss 启动成功后,会在控制台输出启动过程所耗的时间,背后的秘密就在这里。(这个无关紧要,为了完整性介绍一下)。2. 创建 MBeanS

17、erver 实例MBeanServer 是 JMX 框架的核心。JBoss 需要创建一个 MBeanServer 实例。,MBeanServer 的实现也是可以配置的。目前可以使用两种 MBeanServer,一种是jvm platform MBeanServer,它是 Java 平台提供的;另一种是 JBoss 提供的,全限定类名为 org.jboss.mx.server.MBeanServerImpl。通过设置javax.management.builder.initial 系统属性,也可以使用自定义的 MBeanServer。那么 JBoss 究竟使用的是哪种实现呢?如果 Java 版本

18、达到或高于 5.0,且jboss.platform.mbeanserver 系统属性为 true,则使用 jvm platform MBeanServer,否则都使用 JBoss 提供的 MBeanServerImpl。(这一点说得并不准确,涉及到LazyMBeanServer,我还不太清除。大家可以认为,绝大部分情况下,都是用JBoss 提供的 MBeanServerImpl)。3. 创建并注册基础服务在创建 MBeanServerImpl 的过程中,会创建以下 3 个 MBean:第一个 MBean 是 javax.management.MBeanServerDelegate, Objec

19、tName=JMImplementation:type=MBeanServerDelegate第二个 MBean 是一个动态 MBean,org.jboss.mx.modelmbean.XMBean,ObjectName=JMImplementation:type=MBeanRegistry第三个 MBean 是 org.jboss.mx.loading.UnifiedLoaderRepository3, ObjectName=JMImplementation:service=LoaderRepository,name=Default第一个 MBean 是在调用 MBeanServerImpl

20、 之前创建的,后面两个 MBean 实在MBeanServerImpl 的构造函数中创建的。第二个 MBean 是用来 MBeanServer 的注册表,所有挂在 MBeanServer 上的 MBean 都被注册到注册表中。第三个 MBean与 JBoss 的类加载架构有关,也是基础服务之一。服务器 server 和 ServerConfigImpl 也都是 MBean,也都被注册到MBeanServer,ObjectName 分别为 jboss.system:type=Server 和jboss.system:type=ServerConfig。然后,doStart 方法创建并注册以下 3

21、 个 MBean:第一个 MBean 是 org.jboss.system.server.ServerInfo,ObjectName= jboss.system:type=ServerInfo第二个 MBean 是 org.jboss.system.ServiceController,ObjectName= jboss.system:service=ServiceController第三个 MBean 是 org.jboss.deployment.MainDeployer,ObjectName= jboss.system:service=MainDeployer第一个 MBean 主要封装了

22、JBoss 运行的软硬件平台的信息,包括主机地址、J 操作系统版本、Java 版本等。第二个 MBean 是用来控制 MBean 的生命周期。 JMX 规范没有规定 MBean 的生命周期,JBoss 对 JMX 的扩充。每个 MBean 可以有若干生命周期回调方法,JBoss的 JMX 框架会在特定的时候调用这些回调方法。第二个 MBean 就是负责调用MBeabn 的生命周期回调方法。第三个 MBean 是主部署器,所有的部署单元都由它部署。它会根据服务和部署单元的类型,将部署任务委派给相应的子部署器。接着,doStart 方法调用 Runtime.getRuntime.setShutdo

23、wnHook 方法,安装 jvm 关机钩子。这个钩子执行 JBoss 关闭时必要的清理工作,包括销毁已有部署、移除MBean 等。再接着,doStart 方法创建并注册两个子部署器 JARDeployer 和 SARDeployer,它们也都是 MBean。JARDeployer 是用来不包括 WEB-INF 和 META-IN 目录的JAR 包的子部署器。SARDeployer 是用来部署 JBoss MBean SAR 服务的子部署器,它可以部署.sar 的部署包和目录,以及以-server.xml 结尾的 XML 服务描述符文件。除了上面两种子部署器,还有很多其它类型的子部署器。它们作为

24、部署单元,被SARDeployer 创建。(有点奇怪吧,这些部署器本身也是部署单元)最后,doStart 方法开始创建预配置的服务,JavaEE 规范规定的服务,例如事务管理器、安全管理器就在包括在其中。4. 部署预配置的服务预配置的服务都在 C:JBossserverconfjboss-service.xml 被定义。它们都是以MBean 的形式存在。具体包括哪些服务,我就不在详细阐述。不过,其中一个服务我后面会介绍到,类名是 org.jboss.deployment.scanner.URLDeploymentScanner。它与下一个阶段紧密相关。doStart 方法”C:JBossser

25、verconfjboss-service.xml”为参数,调用MainDeployer.deploy 方法。因为部署单元的名称以-server.xml 结尾,MainDeployer 将部署任务委派给 SARDeployer。SARDeployer 进行真正的部署工作。除了 jboss=service.xml 中配置的服务,还有其它很多部署单元,包括用户创建的部署单元,是怎么部署的呢?答案就在下个阶段。5. 部署所有的部署单元还记得上面提到的 URLDeploymentScanner 吗?它是实现 JBoss 热部署功能的重要角色。热部署功能是指,如果你可以在 JBoss 运行的时候添加、删除

26、、修改部署单元,而不需要重启 JBoss。这个功能大大方便了 JavaEE 应用的开发、调试和部署。实现热部署功能是很复杂的,其中有很多技术问题需要解决。例如类加载器问题,JBoss 统一类加载器架构就是为了解决这个问题。我们不考虑这些技术问题,最直接的问题就是需要有个机制来监视部署单元的变化。我们应该需要一个线程去监视所有的部署单元,如果有变化,就要重新部署。为了监视的方便,我们应该把所有的部署单元放在一个目录下。如果一个部署单元被添加到这个目录,JBoss 应该自动部署它;如果这个目录下的一个部署单元被修改了,JBoss 应该自动重新部署它;如果这个目录下的一个部署单元被删除了,JBoss

27、应该自动销毁已部署的单元。不错,JBoss 正是这样做的。所有的需要动态部署单元,都被放到C:JBossserverdefaultdeploy 目录下。而 URLDeploymentScanner 正是监视该目录的 MBean,它会启动一个线程,周期性地扫描该目录下的部署单元,如果有变化,就会进行相应的处理。如果我们需要部署一个组件,只要将它 copy 到 deploy 目录即可。如果不需要该组建了,只需将它从 deploy 目录删除。deploy 下的部署单元并不仅仅是用户开发的部署单元,很多都是 JBoss 提供的企业级服务。如果需要详细了解,可以浏览一下该目录。6. 启动生命维持线程生命

28、维持线程是为了避免 JBoss 的 jvm 停机的。因为 boot 方法执行结束后,”main”线程也随之结束。如果没有其它线程存在,JBoss 的 jvm 将停机。因此,boot 方法在最后会创建并运行一个 LifeThread,以维持 jvm 的运行。也许有人会问,不是有一个监视 deploy 目录的线程吗,何必要增加一个线程?问题在于,JBoss 是高度可定制的,URLDeploymentScanner 未必一定存在。创建 LifeThread 的意义就是,保证至少有一个线程会维持 JBoss jvm 的运行。至此,JBoss 的启动过程成功结束。最终的结果就是创建了一个 JMX 的框架:一个 MBeanServer,以及众多的 MBean 挂在上面。MBean 代表了 JBoss 提供的所有功能,MBeanServer 是 MBean 之间的通信总线。当然,还有一个勤劳的小线程维持着 jvm 的运行。上面所叙述的所有内容,是我在研究了 JBoss 的部分源代码,以及参考了部分书籍后,得出的体会。可能会叙述不准确、甚至错误的地方,欢迎大家指正!发表于 2007 年 10 月 07 日 19:04:00|评论(0)|编辑|收藏http:/

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 实用文档资料库 > 策划方案

Copyright © 2018-2021 Wenke99.com All rights reserved

工信部备案号浙ICP备20026746号-2  

公安局备案号:浙公网安备33038302330469号

本站为C2C交文档易平台,即用户上传的文档直接卖给下载用户,本站只是网络服务中间平台,所有原创文档下载所得归上传人所有,若您发现上传作品侵犯了您的权利,请立刻联系网站客服并提供证据,平台将在3个工作日内予以改正。