<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    posts - 39,  comments - 44,  trackbacks - 0

     

    一、 引言

      JMX(Java管理擴展)提供了一組工具用來管理本地和遠程應用程序、系統(tǒng)對象、設備等。本文將解釋如何使用JMX(JSR 160)來遠程控制Web應用程序,并將解釋應用程序中可用于JMX客戶的代碼,同時將展示使用如MC4J和jManage等的不同客戶如何連接到支持JMX的應用程序。此外,我們還將詳細地討論使用RMI協(xié)議和JNDI來保護通訊層。
           首先我們要分析一個簡單的web應用程序,它監(jiān)控已經(jīng)登陸的用戶數(shù)目并通過一個安全的JMX服務來顯示該項統(tǒng)計。我們還將運行這個應用程序的多個實例并且從所有的運行實例中跟蹤這個統(tǒng)計數(shù)字。當然,你可以下載這個示例web應用程序。它需要你安裝J2SE 5.0 SDK并且你的JAVA_HOME環(huán)境變量指向基安裝目錄。J2SE 5.0實現(xiàn)了1.2版本的JMX API和JMX 1.0版本的Remote API。同時還需要一個支持Servlet的容器;我使用的是Apache Tomcat 5.5.12。另外,我還使用Apache Ant來構建這一示例應用程序。

      二、 建立示例應用程序

      首先,你要下載示例應用程序并且使用ant war(更多的細節(jié)見build.XML中的注釋)來創(chuàng)建一個WAR文件。把jmxapp.war復制到Tomcat的webapps目錄。假定Tomcat正在運行于你的本地機器的端口8080,那么該應用程序的URL將是:

    http://localhost:8080/jmxapp

      如果你看到一個提示你輸入名字和口令的登陸屏幕,那么一切已經(jīng)就緒了。

      三、 跟蹤一些有意義的數(shù)據(jù)

      本文中的應用程序使用Struts框架來提交登錄表單。一旦提交結束,即執(zhí)行LoginAction.execute(..)方法-它將簡單地檢查是否用戶的ID為"hello"以及是否其口令為"world"。如果二者都正確,那么登錄成功并且控制被導向login_success.JSP;如果不正確,那么我們返回到登錄表單。根據(jù)登錄成功與否決定調用incrementSuccessLogins(HttpServletRequest)方法還是incrementFailedLogins(HttpServletRequest)方法。現(xiàn)在,讓我們先分析一下incrementFailedLogins(HttpServletRequest):

    private void incrementFailedLogins(HttpServletRequest request) {
     HttpSession session = request.getSession();
     ServletContext context =session.getServletContext();
     Integer num = (Integer) context.getAttribute( Constants.FAILED_LOGINS_KEY);
     int newValue = 1;
     if (num != null) { newValue = num.intValue() + 1; }
     context.setAttribute( Constants.FAILED_LOGINS_KEY, new Integer(newValue));
    }

      這個方法增加一個在應用程序范圍存儲的FAILED_LOGINS_KEY變量。這個incrementSuccessLogins(HttpServletRequest)方法是以相似的方法實現(xiàn)的。該應用程序追蹤有多少人成功地登錄和有多少人認證失敗。這真不錯,但是我們該如何存取這些數(shù)據(jù)?這就是引入JMX的原因。

      四、 創(chuàng)建JMX MBeans

      MBeans基礎知識及其適于JMX架構的方面超出了本文所討論的范圍。我們將為我們的應用程序簡單地創(chuàng)建、實現(xiàn)、暴露和保護一個MBean。我們所感興趣的是暴露相應與下列兩個方法的兩種數(shù)據(jù)。下面是我們的簡單MBean接口:

    public interface LoginStatsMBean {
     public int getFailedLogins();
     public int getSuccessLogins();
    }

      這兩個方法簡單地返回成功和失敗登陸的數(shù)目。LoginStatsMBean的實現(xiàn)-LoginStats,為上面兩種方法提供了一種具體的實現(xiàn)。讓我們分析一下getFailedLogins()實現(xiàn):

    public int getFailedLogins() {
     ServletContext context = Config.getServletContext();
     Integer val = (Integer) context.getAttribute( Constants.FAILED_LOGINS_KEY);
     return (val == null) ? 0 : val.intValue();
    }

      該方法返回一個存儲在ServletContext中的值。getSuccessLogins()方法是以相似的方式實現(xiàn)的。

      五、 創(chuàng)建和保護一個JMX代理

      管理應用程序的JMX相關方面的JMXAgent類有以下幾個責任:

      1. 創(chuàng)建一個MBeanServer。

      2. 用MBeanServer注冊LoginStatsMBean。

      3. 創(chuàng)建一個JMXConnector以允許遠程客戶進行連接。

       o 包含對JNDI的使用。

       o 也必須有一個RMI注冊運行。

      4. 使用一個用戶名和口令保護JMXConnector。

      5. 分別在應用程序啟動和停止時,啟動和停止JMXConnector。

      JMXAgent的類輪廓是:

    public class JMXAgent {
    public JMXAgent() {
    //初始化JMX服務器
    }
    public void start() {
    //啟動JMX服務器
    }
    //在應用程序結束時調用
    public void stop() {
    //停止JMX服務器
    }
    }

      讓我們理解在該構造器的這部分代碼-它能夠使得客戶遠程地監(jiān)控該應用程序。

      用MBeans創(chuàng)建一個MBeanServer

      我們首先創(chuàng)建一個MBeanServer對象。它是JMX基礎結構的核心組件,它允許我們暴露我們的MBeans作為可管理的對象。MBeanServerFactory.createMBeanServer(String)方法使得這一任務極為輕松。所提供的參數(shù)是服務器的域。可以把它當作這個MBeanServer的唯一的名字。然后,我們用MbeanServe來注冊LoginStatsMBean。MBeanServer.reGISterMBean(Object,ObjectName)方法使用的參數(shù)有兩個:一個是MBean實現(xiàn)的一個實例;另一個是類型ObjectName的一個對象-它用于唯一地標識該MBean;在這種情況下,DOMAIN+":name=LoginStats"就足夠了。

    MBeanServer server = MBeanServerFactory.createMBeanServer(DOMAIN);
    server.registerMBean(new LoginStats(),new ObjectName(DOMAIN+ ":name=LoginStats"));
    六、 創(chuàng)建JMXServiceURL

      到現(xiàn)在為止,我們已經(jīng)創(chuàng)建了一個MBeanServer并且用它注冊了LoginStatsMBean。下一步是使得該服務器對客戶可用。為此,我們必須創(chuàng)建一個JMXServiceURL-它描述了客戶將用來存取該JMX服務的URL:

    JMXServiceURL url = new JMXServiceURL("rmi",null,
    Constants.MBEAN_SERVER_PORT,
    "/jndi/rmi://localhost:" +Constants.RMI_REGISTRY_PORT +"/jmxapp");

      讓我們細致地分析一下上面一行代碼。該JMXServiceURL構造器使用了四個參數(shù):

      1. 在連接時使用的協(xié)議(rmi,jmxmp,iiop,等等)。

      2. JMX服務的主機。用localhost作為參數(shù)就足夠了。然而,提供null強制JMXServiceURL找到可能是最好的主機名。例如,在這種情況下,它將把null翻譯成zarar-這是我的計算機的名字。

      3. JMX服務使用的端口。

      4. 最后,我們必須提供URL路徑-它指示怎樣找到JMX服務。在這種情況下,它會是/jndi/rmi://localhost:1099/jmxapp。

      其中,/jndi部分是指,客戶必須為JMX服務做一下JNDI查詢。rmi://localhost:1099指示,存在一個運行于本機的端口1099的RMI注冊。這里的jmxapp是在RMI注冊中唯一標識這個JMX服務的。在JMXServiceURL對象上的一個toString()產(chǎn)生下列結果:

    service:jmx:rmi://zarar:9589/jndi/rmi://localhost:1100/jmxapp

      上面是客戶將最終使用來連接到該JMX服務的URL。J2SE 5.0文檔有關于這個URL結構的更為詳細的解釋。

      (一) 保護服務

      J2SE 5.0提供了一種有利于JMX用一種容易的方式進行用戶認證的機制。我創(chuàng)建了一個簡單的文本文件-它存儲用戶名和口令信息。文件的內容是:

    zarar siddiqi
    fyodor dostoevsky

      用戶zarar和fyodor被分別通過口令siddiqi和dostoevsky認證。下一步是創(chuàng)建并保護一個JMXConnectorServer,它暴露了該MbeanServer。username/password文件的路徑被存儲在該鍵下的一個映射中-jmx.remote.x.password.file。這個映射在以后創(chuàng)建JMXConnectorServer時使用。

    ServletContext context = Config.getServletContext();
    //得到存儲jmx用戶信息的文件
    String userFile =context.getRealPath("/")+"/Web-INF/classes/"+Constants.JMX_USERS_FILE;
    //創(chuàng)建authenticator并且初始化RMI服務器
    Map<string> env = new HashMap<string>();
    env.put("jmx.remote.x.password.file", userFile);
    現(xiàn)在,讓我們創(chuàng)建JMXConnectorServer。下面一行代碼完成這一功能:
    connectorServer = JMXConnectorServerFactory.
    newJMXConnectorServer(url, env, server);

      這個JMXConnectorServerFactory.newJMXConnectorServer(JMXServiceURL,Map,MBeanServer)方法使用我們剛創(chuàng)建的三個對象作為參數(shù)-它們是JMXServiceURL,存儲認證信息的映射和MBeanServer。其中,connectorServer實例變量允許我們分別在應用程序啟動和停止時,分別用start()和stop()來啟動和停止JMXConnectorServer。

      提示 盡管JSR 160的J2SE 5.0實現(xiàn)相當有力;但是另外的實現(xiàn),例如MX4J,也提供了一些類-它們提供了方便的特性,例如口令混淆,也就是PasswordAuthenticator類。

      七、 啟動RMI注冊

      在早些時候,我提到RMI注冊并且指出當訪問服務時執(zhí)行一個JNDI查詢。然而,現(xiàn)在我們沒有一個正運行的RMI注冊,因此一個JNDI查詢將失敗。一個RMI注冊的啟動可以用手工方式或編程方式來實現(xiàn)。

      (一) 使用命令行

      在你的WindowsLinux命令行上,輸入下列一名來啟動一個RMI注冊:

    rmiregistry &

      這將啟動你的默認主機和端口(分別是localhost和1109)的RMI注冊。然而,對于我們的web應用程序來說,我們不可能依賴一個在應用程序啟動時可用的RMI而寧愿用編程方式來實現(xiàn)之。

      (二) 以編程方式啟動RMI注冊

      為了以編程方式啟動RMI注冊,你可以使用LocateRegistry.createRegistry(int port)方法。該方法返回類型注冊的一個對象。當我們想在應用程序一端終止這個注冊時,我們保存這個參考。就在我們啟動我們的在JMXAgent.start()中的JMXConnectorServer之前,我們首先啟動RMI注冊,使用下列代碼行:

    registry = LocateRegistry.createRegistry(Constants.RMI_REGISTRY_PORT);

      在應用程序一端,在JMXAgent.stop()中停止JMXConnectorServer之后,調用下列方法來終止該注冊:

    UnicastRemoteObject.unexportObject(registry,true);

      注意,StartupListener類觸發(fā)了應用程序開始和結束任務。
    八、 訪問我們的JMX服務

      我們可以有好幾種方法來存取JSR 160服務。為此,我們可以通過編程或通過使用一個GUI來實現(xiàn)。

      (一) 使用MC4J連接

      通過把jmxapp.war復制到Tomcat的Webapps目錄來發(fā)布該應用程序。下載并且安裝MC4J。一旦安裝完,創(chuàng)建一新的類型JSR 160的服務器連接并且指定該服務器URL-它在應用程序啟動時在應用程序服務器日志中打印。在我的示例中,它是:

    service:jmx:rmi://zarar:9589/jndi/rmi://localhost:1100/jmxapp

      提供用戶名和口令,MC4J分別把它們參考為"Principle"和"Credentials"。點擊Next將把你帶到一個屏幕-在此你可以定制你的classpath。默認設置應該工作正常,并且你可以點擊"Finish"來連接到該JMX服務。一旦建立連接,瀏覽如圖1所示的MC4J樹結構,直到你找到LoginStats MBean實現(xiàn)的"Properties"選項。


    圖1.MC4J視圖

      點擊Properties顯示統(tǒng)計,如圖2所示:


    圖2.屬性窗口

      (二) 使用jManage連接到一個"簇"

      通過把jmxapp.war復制到Tomcat的webapps目錄發(fā)布該應用程序。請注意一下在應用程序啟動時所打印的URL。接下來,發(fā)布這個應用程序的另一個實例-通過改變Constants類中的RMI_REGISTRY_PORT并且MBEAN_SERVER_PORT變量,這樣該應用程序的第二個實例就不會試圖使用已經(jīng)在使用的端口了。改變在build.XML文件中的app.name屬性,以便新的實例將被發(fā)布到一個不同的上下文(例如,jmxapp2)。用ant創(chuàng)建一個清理的war文件-它將在其目錄下創(chuàng)建jmxapp2.war。把jmxapp2.war復制到Tomcat的webapps目錄。該應用程序將要發(fā)布,而且現(xiàn)在你有相同應用程序的兩個實例在運行了。我再次提醒你注意在啟動時所打印的URL。

      下載和安裝jManage。一旦安裝了,使用jManage的web接口來創(chuàng)建一個JSR 160應用程序-通過使用主頁中的"添加新應用程序"鏈接。"添加應用程序"頁面顯示在圖3中:


    圖3."添加應用程序"頁面

      為要發(fā)布的第二個應用程序重復前面的步驟并再次使用適當?shù)挠脩裘⒖诹詈蚒RL。。一旦你創(chuàng)建了這兩個應用程序,你必須通過遵循在主頁中找到的"添加新應用程序簇"鏈接來創(chuàng)建一個簇。現(xiàn)在,把這兩個已經(jīng)創(chuàng)建的應用程序添加到你的簇上,如圖4所示:


    圖4.添加應用程序簇頁面


      好了,我們已經(jīng)完成了!從主頁上,點擊簇中的一個應用程序,然后點擊"Find More Objects"按鈕。你將看到name=LoginStats MBean;點擊它,則你就會看到我們已經(jīng)暴露的FailedLogins和SuccessLogins屬性。點擊在該同一頁面上的"Cluster View"鏈接將顯示與圖5相類似的一個頁面-其中,你可以看到兩個應用程序的運行計數(shù)統(tǒng)計:


    圖5.針對jmxapp和jmxapp2的簇視圖

      試著登錄到兩個應用程序(http://localhost:8080/jmxapp和http://localhost:8080/jmxapp2)并且觀察這些數(shù)字是怎樣改變的。

      九、 結論

      現(xiàn)在你已經(jīng)知道了怎樣使你的新的和現(xiàn)有web應用程序支持JMX并且安全地管理它們-使用MC4J和jManage。盡管J2SE 5.0提供了JMX說明書的一個有力的實現(xiàn),但是另外的開源工程例如XMOJO和MX4J還提供了另外的特征,例如經(jīng)由web接口甚至更多的方式的連接。如果有興趣的讀者想了解更多地有關JMX的知識,你可以看一下J. Steven Perry寫的《Java Management Extensions》一書。如果你對遠程應用程序管理感興趣的話,Jeff Hanson寫的《Connecting JMX客戶and Servers》將是很有閱讀價值的,其中提供了許多真實世界的例子。

    posted on 2008-01-20 01:47 礦礦 閱讀(236) 評論(0)  編輯  收藏

    只有注冊用戶登錄后才能發(fā)表評論。


    網(wǎng)站導航:
    博客園   IT新聞   Chat2DB   C++博客   博問  
     
    主站蜘蛛池模板: 免费国产美女爽到喷出水来视频| 免费一级毛片不卡不收费| 亚洲最大av无码网址| 亚洲色无码专区一区| 中文字幕免费高清视频| 亚洲av无码乱码国产精品fc2 | 美女在线视频观看影院免费天天看| 久久久久久久国产免费看| 四虎影视永久免费观看网址| 亚洲日韩精品无码专区加勒比| 免费无码国产V片在线观看| 国产免费变态视频网址网站| 亚洲AV无码之国产精品| 在线观看人成网站深夜免费| 一区二区亚洲精品精华液| 性感美女视频在线观看免费精品| 国产国拍精品亚洲AV片| 成av免费大片黄在线观看| 久久精品国产亚洲7777| baoyu122.永久免费视频| 亚洲伦理一区二区| 午夜性色一区二区三区免费不卡视频 | 亚洲成人免费电影| 午夜时刻免费入口| 黑人粗长大战亚洲女2021国产精品成人免费视频 | 国产一级大片免费看| 亚洲AV无码男人的天堂| 亚洲国产黄在线观看| 国产在线国偷精品免费看| 亚洲国产天堂久久综合网站| 免费无码精品黄AV电影| 美女被爆羞羞网站在免费观看| h视频在线免费看| 亚洲欧洲精品成人久久曰| 国产在线98福利播放视频免费| 亚洲理论片在线观看| 噜噜嘿在线视频免费观看| 日本高清免费中文在线看| 亚洲s色大片在线观看| 歪歪漫画在线观看官网免费阅读| 麻豆亚洲AV永久无码精品久久|