• <ruby id="5koa6"></ruby>
    <ruby id="5koa6"><option id="5koa6"><thead id="5koa6"></thead></option></ruby>

    <progress id="5koa6"></progress>

  • <strong id="5koa6"></strong>
    • 軟件測試技術
    • 軟件測試博客
    • 軟件測試視頻
    • 開源軟件測試技術
    • 軟件測試論壇
    • 軟件測試沙龍
    • 軟件測試資料下載
    • 軟件測試雜志
    • 軟件測試人才招聘
      暫時沒有公告

    字號: | 推薦給好友 上一篇 | 下一篇

    使用WebLogic JMX進行定制調試

    發布: 2007-6-22 07:38 | 作者:   | 來源:   | 查看: 21次 | 進入軟件測試論壇討論

    領測軟件測試網

       

      維護復雜的遺留系統是一項挑戰,而文檔、理性設計以及編碼實踐的缺乏通常會使情況變得更為糟糕。遺憾的是,幾乎所有的軟件開發人員在其職業生涯中都會遇到此類任務。

      對于任何使用數據庫的應用程序,跟蹤應用程序所生成的SQL語句是非常有益的。這樣的跟蹤有助于分析性能瓶頸和調試錯誤,還可以幫助開發人員了解與應用程序相關的業務流程。

      對于遺留的應用程序,我們希望可以進行這樣的跟蹤而不必修改任何代碼或應用程序配置。利用WebLogic的JMX API,我們可以快速地編寫出跟蹤大型復雜遺留應用程序的JDBC調用的少量代碼,而不會對現有代碼和應用程序配置產生影響。此外,這種小項目有助于我們理解JMX以及在幕后WebLogic是如何使用JMX的。在本文中,我將展示利用WebLogic JMX跟蹤SQL語句的細節。

      什么是JMX?

      JMX全稱為Java Management Extensions(Java管理擴展)。MBean(即managed bean,托管bean)是可以通過JMX API進行管理的資源。大多數應用服務器使用JMX來提供管理控制臺并管理資源。此外,應用程序開發人員可以在他們的定制應用程序中使用JMX來提供管理和審計功能。

      WebLogic的JMX實現為開發人員和管理員提供了哪些優點?

      WebLogic Server使用JMX MBeans進行配置和管理。每個WebLogic Server會有一個自己的MBean的副本,它由管理服務器負責更新。管理服務器維護它所管理的所有服務器的MBeans的正本。一旦管理服務器發生故障,托管服務器將根據本地的MBean副本運行,直到管理服務器可以再次更新該服務器的本地MBean。

      WebLogic不僅提供了一個使用JMX MBeans的管理控制臺,它還提供了一個API以便允許應用程序開發人員配置和研究WebLogic資源。利用WebLogic JMX的最容易的方式就是使用WebLogic控制臺來更改WebLogic資源的配置,以及查看控制臺中的技術指標。雖然WebLogic控制臺的監控和配置功能相當強大,可以滿足運行在WebLogic上的大多數應用程序的需要,WebLogic JMX API還是提供了一種更為強大的工具來管理運行在WebLogic平臺上的應用程序。WebLogic JMX API的使用使得配置和擴展WebLogic資源成為可能,還可以從WebLogic的子系統接收通知。例如,一個JDBC連接的最小和最大數設為n的應用程序可能希望有一個監聽器,以便監聽來自WebLogic JMX MBeans的通知,并且在有n-x個并發JDBC連接使用應用程序時,會向管理員發送電子郵件,從而使管理員可以決定增加n值并重新配置JDBC連接池(這里x是一個由管理員決定的任意數字)。應用程序開發人員進一步使用JMX的例子包括WebLogic子系統中的跟蹤事件,包括EJB事件和服務器啟動/停止事件。

      在分析JDBC語句方面,WebLogic應用程序中有哪些可用選項?

      在WebLogic應用程序中,有多種技術可以用來創建對JDBC語句的動態跟蹤。為來自java.sql包的Statement、PreparedStatement和CallableStatement類創建子類,以便使用Log4J或WebLogic記錄之類的記錄系統打印跟蹤信息,然后在應用程序中使用這些子類,這是一個可行方案,但是并不適用于遺留代碼。也可以使用類似于TOAD的工具來實現這種跟蹤,但是此類工具對于應用程序開發人員而言可能不容易得到,而且可能無法提供所需的全部信息。AOP技術是打印JDBC語句的另一種可行方案。然而在撰寫本文時,BEA WebLogic還沒有正式支持AOP,盡管關于WebLogic AOP的文章已經在dev2dev網站上出現。在撰寫本文時,在WebLogic上實現AOP也并不是一項輕而易舉的任務。使用WebLogic 6.1或8.1的WebLogic JMX不需要使用任何附加的類庫和配置,因為所需的所有類均可在weblogic.jar中得到,而且代碼實現起來相當簡單。況且WebLogic JMX是一項非常成熟的技術,可以通過不改變任何核心應用程序代碼或者字節碼來實現。

      使用WebLogic JMX API

      WebLogic javadoc可以通過http://e-docs.bea.com/wls/docs81/javadocs/在線獲得。該API包括幾個名稱中包含management的包,這些包就是WebLogic的JMX實現(參見表1)。

    使用WebLogic JMX進行定制調試(圖一)

      使用JMX跟蹤JDBC調用

      一種編寫跟蹤代碼并提供一個用戶界面來查看SQL的簡單方法是編寫一個JSP、一個Servlet以及一個Java Bean或對象。我們將展示bean/POJO的全部細節,而省去用戶界面/控制器方面的大多數細節,因為大多數WebLogic開發人員對此已有很深的了解。注意,無需修改任何部署描述符、數據庫連接池或數據源來實現跟蹤,所有對應用程序的更改將在運行時進行。

      步驟1

      首先我們將創建一個名為MyTracerBean.java的類,并導入所需的WebLogic JMX包和類。
    import javax.naming.Context;
    import weblogic.jndi.Environment;
    import weblogic.management.MBeanHome;
    import weblogic.management.configuration.JDBCConnectionPoolMBean;
    import weblogic.management.runtime.JDBCStatementProfile;
    import weblogic.management.runtime.JDBCConnectionPoolRuntimeMBean;
    import javax.management.InstanceNotFoundException;
    import javax.management.InvalidAttributeValueException;
    import javax.naming.NamingException;

    使用WebLogic JMX進行定制調試(圖二)

      這些類均位于weblogic.jar中,因此不需要向WebLogic類路徑添加任何JAR或類。

      步驟2

      接下來我們將編寫一個獲取MBeanHome的方法。
    private MBeanHome getMBeanHome() {
    //URL to the serve whose JDBC activity we are tracing
    String url = "t3://localhost:7001";
        String username = "mywlconsoleuname";
        String password = "mywlconsolepsswd";
    //The MBeanHome will allow us to
    //retrieve the MBeans related to JDBC statement tracing
    MBeanHome home = null;

    try { //We'll need the environment so that we can //retrieve the initial context
        Environment env = new Environment();
        env.setProviderUrl(url);
        env.setSecurityPrincipal(username);
        env.setSecurityCredentials(password Context ctx = env.getInitialContext();
    //Retrieving the MBeanHome interface for the server with //the url t3://localhost:7001
        home =(MBeanHome)ctx.lookup(MBeanHome.LOCAL_JNDI_NAME);
        } catch (NamingException ne) {
         System.out.println("Error getting MBeanHome " + ne);
        }
        return home;
    }

      對于最簡單的情形:管理服務器也駐留了我們要跟蹤的JDBC應用程序,上述代碼完全可行;但是對于管理服務器獨立于托管服務器,并且涉及到幾個獨立JVM的情形,我們需要獲得管理MBeans home而不是本地MBeans home。二者的區別在于,本地home只為單個服務器提供Mbean,而管理home則為管理服務器所管理的所有服務器提供MBean。為了獲得管理MBeans home而不是本地MBeans home,可以將上述代碼中的LOCAL_JNDI_NAME替換為ADMIN_JNDI_NAME。

      步驟3

      提供一種打開和關閉JDBC分析的方式是非常有用的,因為分析的開銷相當大,所以不需要時應當將其關閉。默認情況下,分析是關閉的,因此必須在跟蹤任何JDBC語句前打開它。創建一個如下的方法:
    public void configureJDBCAuditing(boolean isOn) {
       try {
        MBeanHome home = getMBeanHome();
        //Retreive the bean to help us configure the Pool
    JDBCConnectionPoolMBean mConfigBean =
    (JDBCConnectionPoolMBean)home.getConfigurationMBean("MyPool","JDBCConnectionPoolConfig");
       mConfigBean.setSqlStmtProfilingEnabled(isOn);
       mConfigBean.setSqlStmtParamLoggingEnabled(isOn);
       } catch (InvalidAttributeValueException iave) {
       System.out.println("Invalid attribute while configuring tracing " + iave);
       } catch (InstanceNotFoundException infe) {
       System.out.println("Instance not found while configuring tracing " + infe);
       }
    }
      在上述代碼中,我們還告知連接池我們希望查看傳入SQL語句中的參數。這會增加跟蹤的開銷,但是它可以為我們提供一些有價值的信息。

      步驟4

      在配置JDBC池來保存配置文件之后,我們可以對其進行查詢。記住,檢索到的配置文件數等于打開分析后所執行的SQL語句數,而不等于所有由MyPool ConnectionPool執行的SQL語句數。以下的代碼檢索配置文件,maxProfiles參數指示應該獲取最近的多少個配置文件。創建的方法如下:
    /** Pass in -1 to get all profiles */
    public JDBCStatementProfile[] getProfiles(int maxProfiles) {
       JDBCStatementProfile[] profiles = null;
       try {
        MBeanHome home = getMBeanHome();
    JDBCConnectionPoolRuntimeMBean mbean =
    (JDBCConnectionPoolRuntimeMBean)home.getRuntimeMBean("MyPool
    ","JDBCConnectionPoolRuntime");
        int numProfiles = mbean.getStatementProfileCount();
        int profilesIndex = 0;
        //figure out index to start at and how many we want
        if (maxProfiles != -1) {
        profilesIndex = numProfiles - maxProfiles;
    }else {
        maxProfiles = numProfiles;
    }
    profiles =mbean.getStatementProfiles(profilesIndex,maxProfiles);
       } catch (InstanceNotFoundException infe) {
    System.out.println("Problem retrieving jdbc profiles " + infe);
       }
       return profiles;
      }
      JDBCConnectionPoolRuntimeMBean的getStatementProfiles方法在WebLogic 8.1 API文檔中沒有提及,盡管它曾在WebLogic 6.1文檔中出現。不過這看起來是個錯誤,因為在WebLogic 8.1中該方法是可用的,并且WebLogic 8.1還修復了方法中的一個bug(CR094729,參見http://e-docs.bea.com/wls/docs81/notes/resolved_sp01.html),這意味著WebLogic 8.1是打算包含該方法的。

      步驟5

      可以添加一個清空功能,使得重啟服務器時可以清空語句緩存:
    public void reset() {
       MBeanHome home = getMBeanHome();
       try {
    JDBCConnectionPoolRuntimeMBean mbean =
    (JDBCConnectionPoolRuntimeMBean)home.getRuntimeMBean("MyPool
    ","JDBCConnectionPoolRuntime");
    //Remove everything from the cache
        mbean.resetStatementProfile();
       } catch (InstanceNotFoundException infe) {
    System.out.println("Problem while resetting JDBC profiles " + infe);
       }
      }

      步驟6

      對配置文件進行迭代,獲得要顯示的信息(參見清單1)。這些代碼可能放在用戶界面層,比如放在一個JSP中。

      清單1
    MyTracerBean myTracer = new MyTracerBean();
    //In this case we want the 100 most recently executed statements
    JDBCStatementProfile[] profiles = myTracer.getProfiles(100);
    //Doing the looping so that the most recent statements information is
    //retrieved first
    for (int i=profiles.length-1;i>-1;i--) {
    //Getting the number of parameters passed into the current //statement
    int paramCount = profiles[i].getParameterCount();
    //Format the start and end time for the current statement
    SimpleDateFormat simpleDateFormat =
    new SimpleDateFormat("yyyyy.MMMMM.dd GGG hh:mm:ss:SS aaa");
    String startTime=simpleDateFormat.format(new Date(profiles[i].getStartTime()));
    String endTime=simpleDateFormat.format(new Date(profiles[i].getStopTime()));

    //Append the parameters together in order to display them
    StringBuffer paramsBuffer = new StringBuffer();
    if (paramCount < 1) {
    paramsBuffer.append("None");
    } else {
    for (int j=0;j<paramCount;j++) {
    paramsBuffer.append(profiles[i].getParameter(j));
    paramsBuffer.append(" ");
    }
    }

    String statementTxt = profiles[i].getStatementText();
    String paramsTxt = paramsBuffer.toString();
    String timeTaken = profiles[i].getTimeTaken()

    //Then use statementTxt, paramsTxt, timeTaken, startTime, endTime
    // etc to show the statement details in a UI
    }

      展望WebLogic JMX的前景

      在撰寫本文時,剛剛發布的WebLogic 9.0支持的是JMX 1.2而不是WebLogic 8.1及以前版本一直支持的JMX 1.0。響應JMX規范的變化,9.0中的WebLogic JMX API有了相當大的變化,清單1中的代碼可能會引起不支持的警告。當升級至9.0時,應當用JDBCDataSourceRuntimeMBean替換JDBCConnectionPoolRuntimeMBean。不過,在撰寫本文時,絕大多數運行在WebLogic上的遺留應用程序還沒有使用WebLogic Server 9.0,而且很可能在相當長的一段時間內不會使用9.0。

    延伸閱讀

    文章來源于領測軟件測試網 http://www.kjueaiud.com/


    關于領測軟件測試網 | 領測軟件測試網合作伙伴 | 廣告服務 | 投稿指南 | 聯系我們 | 網站地圖 | 友情鏈接
    版權所有(C) 2003-2010 TestAge(領測軟件測試網)|領測國際科技(北京)有限公司|軟件測試工程師培訓網 All Rights Reserved
    北京市海淀區中關村南大街9號北京理工科技大廈1402室 京ICP備2023014753號-2
    技術支持和業務聯系:info@testage.com.cn 電話:010-51297073

    軟件測試 | 領測國際ISTQBISTQB官網TMMiTMMi認證國際軟件測試工程師認證領測軟件測試網

    老湿亚洲永久精品ww47香蕉图片_日韩欧美中文字幕北美法律_国产AV永久无码天堂影院_久久婷婷综合色丁香五月

  • <ruby id="5koa6"></ruby>
    <ruby id="5koa6"><option id="5koa6"><thead id="5koa6"></thead></option></ruby>

    <progress id="5koa6"></progress>

  • <strong id="5koa6"></strong>