JBoss Application Server 4.2.1 GA啓動順序 (轉)

原文出處:http://wangxuliangboy.iteye.com/blog/241068

本文以JBoss Application Server 4.2.1 GA(以下簡稱JBoss)爲例,介紹它在Windows平臺上的啓動過程。爲了方便敘述,對平臺環境做以下假定:Java運行時的安裝路徑爲C:\Java,JBoss的安裝路徑爲C:\JBoss。

既然用100% Java編寫的JBoss具有跨平臺的特性,那爲什麼還要強調Windows平臺呢?這是因爲,JBoss的啓動是從平臺相關的腳本文件開始的,而在不同平臺上的腳本文件是不同的。例如,Window平臺上的腳本文件是run.bat,linux平臺上的腳本是run.sh。兩個文件的內容有很大不同,功能也許差不多,無非是配置啓動環境,但是也有可能存在平臺相關的因素。我只看了run.bat,對run.sh並不瞭解,爲謹慎起見,我只介紹run.bat,對run.sh不作闡述。

在介紹JBoss啓動過程之前,我想先介紹一下JBoss的結構特徵,這將有利於大家理解啓動過程。JBoss基於JMX框架,它的結構就是一個MBeanSserver以及一些掛在MBeanServer上的MBean。MBean提供功能,MBeanServer是MBean之間的通信總線。JMX框架的好處就是給JBoss帶來了高度的靈活性、可配置性。可配置性也是JBoss的核心理念之一,幾乎所有的JBoss部件都可以被替換。JBoss通過系統屬性、配置文件等多種方法,幫助實現高度的可配置性。我們可以通過設置系統屬性,或者通過編輯配置文件,來定製自己的JBoss版本。這種可配置性體現在JBoss的各個角落,啓動過程只能窺一斑,若欲知全豹,可以研究一下JBoss的EJB容器等其它部件。

介紹完JBoss的結構特徵,我們開始進入JBoss的啓動過程。整個過程可以分爲六個階段,下面將依次介紹。

<!--[if !supportLists]-->一、<!--[endif]-->執行啓動腳本,配置啓動環境

JBoss的啓動過程從執行run.bat開始,run.bat的主要工作就是配置啓動環境。

JBoss的啓動環境其實是一些啓動參數,例如JBoss的安裝路徑、java命令的參數、JBoss的類路徑等。如果在配置過程中發生錯誤,run.bat的執行將被中斷。

run.bat將配置以下啓動參數:

JBOSS_HOME

JBoss的安裝路徑,其值爲C:\JBoss

PATH

將C:\JBoss\bin\native添加到PATH中,native下的文件是平臺相關的,可以優化JBoss的性能。

JAVA

java.exe文件的路徑,其值爲C:\Java\bin\java

JAVA_OPTSB

java命令的參數,其值爲-Dprogram.name=run.bat –server-Xms128m –Xmx512m –Dsun.rmi.dgc.client.gcInterval=3600000 –Dsun.rmi.dgc.server.gcInterval=3600000

JBOSS_CLASSPATH

JBoss的啓動類路徑,其值爲C:\Java\lib\tools.jar;C:\JBoss\bin\run.jar。JBoss的啓動前期需要的類文件都在這兩個jar中。

如果沒有設置系統環境變量JAVA_HOME,那麼run.bat的執行將被中斷,JBoss啓動失

敗。因此,在安裝好JBoss後,一定要設置JAVA_HOME系統環境變量。

如果run.bat執行順利,那麼在最後,將會執行以下命令:

C:\Java\bin\java -Dprogram.name=run.bat –server-Xms128m –Xmx512m –Dsun.rmi.dgc.

client.gcInterval=3600000 –Dsun.rmi.dgc.client.gcInterval=3600000  -Djava.endorsed.dirs=

C:\JBoss\lib\endorsed –classpath C:\Java\lib\tools.jar;C:\JBoss\bin\run.jar org.jboss.Main\%*

%*代表run.bat後面的啓動參數。

從這條命令開始,真正運行JBoss的代碼。

 

<!--[if !supportLists]-->二、<!--[endif]-->JBoss啓動的入口

JBoss的魔術從Main.main方法開始。Main這個類位於run.jar中。Main.main方法創建了一個名爲”jboss”的線程組,然後創建並運行該線程組的線程”main”。”main”線程開始運行後,Main.main方法執行完畢,主線程也隨之結束。”main”線程的主要工作是調用Main.boot方法。

Main.boot方法的主要工作是處理命令行參數,然後創建並運行一個服務器實例。當服務器實例開始運行後,jboss的啓動過程也就成功結束了。下面的幾個階段都是boot方法的執行過程。

 

<!--[if !supportLists]-->三、<!--[endif]-->處理命令行參數

boot方法調用Main.processCommandLine方法,來處理命令行參數。這裏的命令行參數其實就是main方法的args參數,它作爲實參傳遞給processCommandLine方法。

processCommandLine方法使用了GNU-getopt程序包來解析命令行參數,對不同的命令行參數有不同的處理方式,簡單概括如下:

部分參數被簡單處理後,程序直接退出。這些參數包括:

-h 顯示幫助消息。

-V 顯示版本信息。版本信息從run.jar中的MANIFEST.MF文件中獲得。

部分參數被保存在服務器屬性(Main.props)中,這些參數包括:

-p 補丁目錄。

-n 從網絡啓動的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 extraClasspath中

部分參數被保存在系統屬性中,這些參數包括:

-D 系統屬性

-P 從給定url加載的屬性

-l 指定日誌插件類性,目前有log4j和jdk兩種。

         processCommandLine方法執行完畢後,boot方法將加載、創建並運行一個服務器實例。

 

<!--[if !supportLists]-->四、<!--[endif]-->加載並創建服務器實例

服務器實例是一個運行時對象,這個對象代表了運行着的JBoss應用服務器。啓動一個JBoss應用服務器,就會有一個服務器實例與之對應。在JBoss中,服務器實例的實現是可以配置的,也就是說,服務器類不是固化的,而是可以替換的。這就帶來一個問題:JBoss必須在啓動的過程中搜索並加載服務器類。

搜索並加載服務器實例類的工作由一個輔助類完成,它的全限定類名是org.jboss.system.server.ServerLoader。這個類會創建一個特定的類加載器,並使用這個類加載器加載服務器類,然後利用反射機制,創建一個服務器實例。

boot方法首先創建一個ServerLoader實例,我們把它稱爲loader,然後boot方法將一些url添加到loader中。我們把這些url稱爲服務器搜索路徑。loader就是在服務器搜索路徑中搜索服務器類。服務器搜索路徑包括:

bootURL          由-d參數提供。如果bootURL是文件目錄,則其下的jar的url也被添加。

bootLibraries   由-B參數提供。

Endorsed jars   位於C:\JBoss\lib\endorsed下的所有jar包。

jmxLibs           C:\JBoss\lib\jboss-jmx.jar。

concurrentLib   C:\JBoss\lib\concurrent.jar。

extraLibraries  由-L參數提供。

extraClasspath  由-C參數提供。

loader自帶的url     log4j-boot.jar、jboss-common.jar、jboss-system.jar、jboss-xml-binding.jar。

添加完服務器搜索路徑後,boot方法調用了loader的load方法。load方法以服務器

搜索路徑作爲參數,創建一個類加載器,並使用它搜索和加載服務器類。如果成功加載,就利用放射機制,創建一個服務器實例,我們把它稱爲server。

默認的服務器類是org.jboss.system.server.ServerImpl,它位於C:\JBoss

\lib\jboss-system.jar中,並不在jboss的類路徑中。因此,loader必須創建自己的類加載器,使用服務器搜索路徑作爲類搜索路徑,才能夠找到ServerImpl。通過設置jboss.server.type系統屬性,也可以使用自定義的服務器類。當然,前提是要保證自定義的服務器類的類文件要在服務器搜索路徑中。

         服務器實例創建完畢後,還需要對它進行配置,這就是下面的初始化工作。

 

<!--[if !supportLists]-->五、<!--[endif]-->初始化服務器實例

初始化服務器實例的主要工作就是將服務器配置信息封裝到一個對象中。這個對象是類org.jboss.system.server.ServerConfigImpl的實例。它包括了服務器實例的基本配置信息,例如JBoss的安裝路徑、服務器的根目錄、服務器的日誌目錄、服務器的臨時目錄、服務器的庫路徑等。

boot方法調用server的init方法,開始初始化工作。Init方法將初始化工作委派給server.

.doInit方法。doInit方法創建並配置ServerConfigImpl對象,並在最後在控制檯和日誌中打印出服務器的配置信息。

ServerConfigImpl對象是一個MBean,因此,用戶可以利用jmx控制檯查看服務器實例的配置信息。

初始化完畢後,就要啓動服務器實例了。

 

<!--[if !supportLists]-->六、<!--[endif]-->啓動服務器實例

啓動服務器實例是一個複雜的過程,其中有很多的工作需要完成。前面已經提到,JBoss是基於JMX框架的,JBoss的主要功能都是以MBean的形式作爲服務提供的,服務之間利用JMX總線進行通信。直到目前爲止,我們還沒有看到JMX相關的工作。因此,在服務器實例的啓動過程中,首要的工作就是要搭建JMX框架。JMX框架搭建完畢後,JBoss需要創建幾個基本的服務,這些服務正是以MBean的形式,掛在JMX框架上。之後,JBoss開始了部署過程。JBoss預配置的服務、用戶的部署單元都在這個階段被部署、啓動。

boot方法調用server.start方法,開始了啓動過程。start方法將啓動工作委派給了server.

doStart方法。doStart方法依次完成以下工作:

<!--[if !supportLists]-->1.         <!--[endif]-->創建並啓動計時器

這個計時器是用來計算JBoss啓動的時間,JBoss啓動成功後,會在控制檯輸出啓動過程所耗的時間,背後的祕密就在這裏。(這個無關緊要,爲了完整性介紹一下)。

<!--[if !supportLists]-->2.         <!--[endif]-->創建MBeanServer實例

         MBeanServer是JMX框架的核心。JBoss需要創建一個MBeanServer實例。,MBeanServer的實現也是可以配置的。目前可以使用兩種MBeanServer,一種是jvm platform MBeanServer,它是Java平臺提供的;另一種是JBoss提供的,全限定類名爲org.jboss.mx.server.MBeanServerImpl。通過設置javax.management.builder.initial系統屬性,也可以使用自定義的MBeanServer。那麼JBoss究竟使用的是哪種實現呢?如果Java版本達到或高於5.0,且jboss.platform.mbeanserver系統屬性爲true,則使用jvm platform MBeanServer,否則都使用JBoss提供的MBeanServerImpl。(這一點說得並不準確,涉及到LazyMBeanServer,我還不太清除。大家可以認爲,絕大部分情況下,都是用JBoss提供的MBeanServerImpl)。

<!--[if !supportLists]-->3.         <!--[endif]-->創建並註冊基礎服務

    在創建MBeanServerImpl的過程中,會創建以下3個MBean:

第一個MBean是javax.management.MBeanServerDelegate,

ObjectName=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之前創建的,後面兩個MBean實在MBeanServerImpl的構造函數中創建的。第二個MBean是用來MBeanServer的註冊表,所有掛在MBeanServer上的MBean都被註冊到註冊表中。第三個MBean與JBoss的類加載架構有關,也是基礎服務之一。

    服務器server和ServerConfigImpl也都是MBean,也都被註冊到MBeanServer,ObjectName分別爲jboss.system:type=Server和jboss.system:type=ServerConfig。

    然後,doStart方法創建並註冊以下3個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主要封裝了JBoss運行的軟硬件平臺的信息,包括主機地址、J操作系統版本、Java版本等。

    第二個MBean是用來控制MBean的生命週期。JMX規範沒有規定

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章