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

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

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

    Java學(xué)習(xí)

    java,spring,structs,hibernate,jsf,ireport,jfreechart,jasperreport,tomcat,jboss -----本博客已經(jīng)搬家了,新的地址是 http://www.javaly.cn 如果有對(duì)文章有任何疑問(wèn)或者有任何不懂的地方,歡迎到www.javaly.cn (Java樂(lè)園)指出,我會(huì)盡力幫助解決。一起進(jìn)步

     

    Java 理論與實(shí)踐: 用JMX檢測(cè)應(yīng)用程序


    【IT168 技術(shù)文檔】

        調(diào)試器和分析器可以提供對(duì)應(yīng)用程序的行為的深入觀察,但在出現(xiàn)嚴(yán)重問(wèn)題之前,這些工具通常用不上。將監(jiān)視掛鉤(hook)構(gòu)建到應(yīng)用程序內(nèi),會(huì)使理解程序 的執(zhí)行變得更容易而且不會(huì)破壞調(diào)試器。既然 Java 管理擴(kuò)展(JMX)已經(jīng)構(gòu)建進(jìn)了 Java SE 平臺(tái),而且 jconsole 查看器提供了統(tǒng)一的監(jiān)視 GUI,那么用 JMX 為應(yīng)用程序提供一個(gè)窗口,要比以前更加容易而且更為有效。

    有多少次您曾經(jīng)注視著運(yùn)行中的應(yīng)用程序,問(wèn)自己:“它到底在做什么?為什么用了這么長(zhǎng)時(shí)間呢?” 在這些時(shí)刻,您可能會(huì)想如果自己在應(yīng)用程序中構(gòu)建了更多的監(jiān)視功能就好了。例如,在服務(wù)器應(yīng)用程序中,能夠查看排隊(duì)等候處理的任務(wù)的數(shù)量和類(lèi)型、當(dāng)前正在處理的任務(wù)、過(guò)去一分鐘或一小時(shí)內(nèi)的吞吐量統(tǒng)計(jì)、平均任務(wù)處理時(shí)間等。這些統(tǒng)計(jì)值容易搜集,但是在需要數(shù)據(jù)的時(shí)候,如果沒(méi)有非侵入性的數(shù)據(jù)檢索機(jī)制,那么這些值就不太有用。

    可以用許多方式導(dǎo)出操作性數(shù)據(jù)——可以把周期性統(tǒng)計(jì)快照寫(xiě)入日志文件、創(chuàng)建 Swing GUI、使用內(nèi)嵌的 HTTP 服務(wù)器在 Web 頁(yè)面上顯示統(tǒng)計(jì)值或者發(fā)布可以用來(lái)查詢應(yīng)用程序的 Web 服務(wù)。但是在缺少監(jiān)視和數(shù)據(jù)發(fā)布基礎(chǔ)設(shè)施的情況下,多數(shù)應(yīng)用程序開(kāi)發(fā)人員都做不到這些,因此造成對(duì)應(yīng)用程序工作情況的了解要比預(yù)期的少很多。

    JMX

    在 Java 5.0 中,類(lèi)庫(kù)和和 JVM 提供了一種全面的管理和監(jiān)視基礎(chǔ)設(shè)施——JMX。JMX 是一種用來(lái)提供可以遠(yuǎn)程訪問(wèn)的管理接口的標(biāo)準(zhǔn)措施,也是一種向應(yīng)用程序添加靈活且強(qiáng)大的管理接口的簡(jiǎn)易方式。被稱(chēng)作受管 bean(MBean)的 JMX 組件,是提供與實(shí)體的管理有關(guān)的訪問(wèn)器和業(yè)務(wù)方法的 JavaBean。每個(gè)受管的實(shí)體(可能是整個(gè)應(yīng)用程序或應(yīng)用程序中的服務(wù))實(shí)例化一個(gè) MBean 并用可讀懂的名稱(chēng)注冊(cè)它。支持 JMX 的應(yīng)用程序依賴(lài)于 MBeanServer,它充當(dāng) MBean 的容器,提供遠(yuǎn)程訪問(wèn)、命名空間管理和安全服務(wù)。在客戶端,jconsole 工具可以充當(dāng)統(tǒng)一的 JMX 客戶機(jī)。結(jié)合兩者,對(duì) JMX 的平臺(tái)支持極大地降低了使應(yīng)用程序支持外部管理接口所需的工作和努力。

    除了提供 MBeanServer 實(shí)現(xiàn),Java SE 5.0 還提供 JVM 以更方便地了解內(nèi)存管 理、類(lèi)裝入、活動(dòng)線程、日志和平臺(tái)配置的狀態(tài)。多數(shù)平臺(tái)服務(wù)的監(jiān)視和管理在默認(rèn)情況下都是開(kāi)啟的(性能影響最小),所以只需要連接應(yīng)用程序與 JMX 客戶機(jī)即可。圖 1 給出了 jconsole JMX 客戶機(jī)(JDK 的一部分) ,它顯示了其中一個(gè)內(nèi)存管理視圖——一段時(shí)間內(nèi)的堆使用情況。Perform GC 按鈕則證明了 JMX 可以提供 除了查看操作統(tǒng)計(jì)值之外的初始化操作的功能。



    圖 1. 用 jconsole 查看堆使用情況
    傳輸和安全性

    JMX 指定了在 MBeanServer 和 JMX 客戶之間通信所 使用的協(xié)議,協(xié)議可以在各種傳輸機(jī)制上運(yùn)行。可以使用針對(duì)本地連接的內(nèi)置傳輸,及通過(guò) RMI、socket 或 SSL 的遠(yuǎn)程傳輸(可以通過(guò) JMX Connector API 創(chuàng)建新的傳輸)。認(rèn)證是由傳輸執(zhí)行的;本地傳輸允許用相同的用戶 ID 連接到運(yùn)行在本地系統(tǒng)上的 JVM;遠(yuǎn)程傳輸可以用口令或證書(shū)進(jìn)行認(rèn)證。本地傳輸在 Java 6 下默認(rèn)就是啟用的。要在 Java 5.0 下啟用它,需要在 JVM 啟動(dòng)時(shí)定義系統(tǒng)屬性 com.sun.management.jmxremote。“Monitoring and Management using JMX” 這份文檔描述了啟用和配置傳輸?shù)呐渲貌襟E。

    檢測(cè) Web 服務(wù)器

    檢測(cè)應(yīng)用程序來(lái)使用 JMX 很容易。像其他許多遠(yuǎn)程調(diào)用框架(RMI、EJB 和 JAX-RPC)一樣,JMX 也是基于接口的。要?jiǎng)?chuàng)建管理服務(wù),需要?jiǎng)?chuàng)建指定管理方法的 MBean 接口。然后可以創(chuàng)建一個(gè) MBean 來(lái)實(shí)現(xiàn)此接口、實(shí)例化它及把它注冊(cè)到 MBeanServer。

    清單 1 顯示了網(wǎng)絡(luò)服 務(wù)(例如 Web 服務(wù)器)的 MBean 接口。它提供了檢索配置信息(例如端口號(hào))和操作性信息(例如服務(wù)是否啟動(dòng))的 getter。它還包含查看和修改可配置參數(shù)(例如當(dāng)前日志級(jí)別)的 getter 和 setter,還有調(diào)用管理操作(例如 start() 和 stop())的方法。

    清單 1. 某個(gè) Web 服務(wù)器的 MBean 接口

    public interface WebServerMBean {
    public int getPort();

    public String getLogLevel();
    public void setLogLevel(String level);

    public boolean isStarted();
    public void stop();
    public void start();
    }

      實(shí)現(xiàn) MBean 類(lèi)通常非常直接明了,因?yàn)?MBean 接口要反映現(xiàn)有實(shí)體或服務(wù)的屬性和管理操作。例如,MBean 中的 getLogLevel() 和 setLogLevel() 方法會(huì)直接轉(zhuǎn)給被 Web 服務(wù)器使用的 Logger 上的 getLevel() 和 setLevel() 方法。JMX 做了一些命名限制。例如,MBean 接口名稱(chēng)必須以 MBean 結(jié)尾,F(xiàn)ooMBean 接口的 MBean 類(lèi)必須叫作 Foo。(可以用更高級(jí)的 JMX 特性——?jiǎng)討B(tài) MBean 來(lái)去除這個(gè)限制。)把 MBean 注冊(cè)到默認(rèn)的 MBeanServer 也很容易,如清單 2 所示:

    清單 2. 用內(nèi)置的 JMX 實(shí)現(xiàn)注冊(cè) MBean

    public class WebServer implements WebServerMBean { ... }

    ...

    WebServer ws = new WebServer(...);
    MBeanServer server = ManagementFactory.getPlatformMBeanServer();
    server.registerMBean(ws, new ObjectName("myapp:type=webserver,name=Port 8080"));

      傳遞給 registerMBean() 的 ObjectName 標(biāo)識(shí)了受管實(shí)體。因?yàn)轭A(yù)見(jiàn)到指定應(yīng)用程序可能包含許多受管實(shí)體,所以名稱(chēng)包含域(清單 2 中的 “myapp”)和許多標(biāo)識(shí)域中的受管資源的鍵-值對(duì)。“name” 和 “type” 這兩個(gè)鍵是常用的,在使用的時(shí)候,name 應(yīng)當(dāng)在域中所有的同類(lèi) MBean 中能夠唯一地標(biāo)識(shí)受管實(shí)體。也可以指定其他鍵-值對(duì),而且 JMX API 還包含進(jìn)行對(duì)象名稱(chēng)通配匹配的工具。

    創(chuàng)建并注冊(cè)了 MBean 之后,立即就可以把 jconsole 指向應(yīng)用程序(在命令行輸入 jconsole)并在 “MBeans” 視圖中查看它的管理屬性和操作。圖 2 顯示了 jconsole 中針對(duì)新 MBean 的 Attributes 標(biāo)簽,圖 3 顯示了 Operations 標(biāo)簽。使用反射,JMX 可以指出哪個(gè)屬性是只讀的(Started、Port),哪個(gè)屬性是可讀寫(xiě)的(LogLevel),而且 jconsole 允許修改讀寫(xiě)屬性。如果讀寫(xiě)屬性的 setter 拋出異常(例如 IllegalArgumentException),JMX 就把異常報(bào)告給客戶機(jī)。



    圖 2. jconsole 中 MBean 的 Attributes 標(biāo)簽



    圖 3. jconsole 中 MBean 的 Operations 標(biāo)簽

    數(shù)據(jù)類(lèi)型

      MBean 中的訪問(wèn)器和操作能夠用任何其簽名形式的原語(yǔ)類(lèi)型,以及 String、Date 和其他標(biāo)準(zhǔn)庫(kù)類(lèi)。也可以使用這些允許的類(lèi)型的數(shù)組和集合。MBean 方法也可以使用其他可以序列化的數(shù)據(jù)類(lèi)型,但是這樣做會(huì)造成互操作性問(wèn)題,因?yàn)轭?lèi)文件也必須對(duì) JMX 客戶機(jī)可用。(如果使用 RMI 傳輸,可以使用 RMI 的自動(dòng)類(lèi)下載特性完成這項(xiàng)任務(wù)。)如果想在管理接口中使用結(jié)構(gòu)化數(shù)據(jù)類(lèi)型,還想避免與類(lèi)可用性相關(guān)的互操作性問(wèn)題,可以使用 JMX 的開(kāi)放 MBean 特性來(lái)表達(dá)復(fù)合或表格數(shù)據(jù)。

    檢測(cè)服務(wù)器應(yīng)用程序

    在創(chuàng)建管理接口時(shí),某些參數(shù)和操作的特點(diǎn)很自然地就表明這些參數(shù)和數(shù)據(jù)應(yīng)當(dāng)被包含在內(nèi),例如配置參數(shù)、操作統(tǒng)計(jì)值、調(diào)試操作(例如修改日志級(jí)別或把應(yīng)用 程序狀態(tài)導(dǎo)出到文件)、生命周期操作(啟動(dòng)、停止)。檢測(cè)一個(gè)應(yīng)用程序,讓它支持對(duì)這些屬性和操作的訪問(wèn),通常相當(dāng)容易。但是,要從 JMX 獲得最大價(jià)值,就要在設(shè)計(jì)時(shí)考慮什么數(shù)據(jù)在運(yùn)行時(shí)對(duì)用戶和操作員有用。

    如果用 JMX 了解服務(wù)器應(yīng) 用程序的工作情況,需要一種標(biāo)識(shí)和跟蹤工作單元的機(jī)制。如果使用標(biāo)準(zhǔn)的 Runnable 和 Callable 接口描述任務(wù),通過(guò)讓任務(wù)類(lèi)自描述(例如實(shí)現(xiàn)toString() 方法),可以在任務(wù)生命周期內(nèi)跟蹤它們,并提供 MBean 方法來(lái)返回等候中、處理中和完成的任務(wù)列表。

    清單 3 中的 TrackingThreadPool 演示的是 ThreadPoolExecutor 的一個(gè)子類(lèi),它及時(shí)給出正在處理中的是哪些任務(wù),以及已經(jīng)完成的任務(wù)的時(shí)間統(tǒng)計(jì)值。它通過(guò)覆蓋 beforeExecute() 和 afterExecute() 掛鉤,并提供能檢索所搜集數(shù)據(jù)的 getter,實(shí)現(xiàn)這些任務(wù)。

    清單 3. 搜集處理中的任務(wù)和平均的任務(wù)時(shí)間統(tǒng)計(jì)值的線程池類(lèi)

    public class TrackingThreadPool extends ThreadPoolExecutor {
    private final Map<Runnable, Boolean>
    inProgress
    = new ConcurrentHashMap<Runnable,Boolean>
    ();
    private final ThreadLocal<Long> startTime = new ThreadLocal<Long>
    ();
    private long
    totalTime;
    private int
    totalTasks;
    public TrackingThreadPool(int corePoolSize, int maximumPoolSize, long
    keepAliveTime,
    TimeUnit unit, BlockingQueue
    <Runnable>
    workQueue) {
    super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue);
    }
    protected void
    beforeExecute(Thread t, Runnable r) {
    super.beforeExecute(t, r);
    inProgress.put(r, Boolean.TRUE);
    startTime.
    set(new
    Long(System.currentTimeMillis()));
    }
    protected void
    afterExecute(Runnable r, Throwable t) {
    long time = System.currentTimeMillis() - startTime.get
    ().longValue();
    synchronized (
    this
    ) {
    totalTime
    +=
    time;
    ++
    totalTasks;
    }
    inProgress.remove(r);
    super.afterExecute(r, t);
    }
    public Set<Runnable>
    getInProgressTasks() {
    return
    Collections.unmodifiableSet(inProgress.keySet());
    }
    public synchronized int
    getTotalTasks() {
    return
    totalTasks;
    }
    public synchronized double
    getAverageTaskTime() {
    return (totalTasks == 0) ? 0 : totalTime /
    totalTasks;
    }
    }

    清單 4 中的 ThreadPoolStatusMBean 顯示了 TrackingThreadPool 的 MBean 接口,它提供了活動(dòng)任務(wù)、活動(dòng)線程、完成任務(wù)、等候任務(wù)的計(jì)數(shù),還提供了當(dāng)前等候執(zhí)行和正在執(zhí)行的任務(wù)的列表。在管理接口中包含等候和執(zhí)行任務(wù)的列表,讓 您既可以看到應(yīng)用程序的工作難度,又可以看到它目前的工作內(nèi)容。這個(gè)特性不僅讓您可以洞察應(yīng)用程序的行為,還能洞察它正在操作的數(shù)據(jù)集的性質(zhì)。

    清單 4. TrackingThreadPool 的 MBean 接口

    public interface ThreadPoolStatusMBean {
    public int getActiveThreads();
    public int getActiveTasks();
    public int getTotalTasks();
    public int getQueuedTasks();
    public double getAverageTaskTime();
    public String[] getActiveTaskNames();
    public String[] getQueuedTaskNames();
    }

      如果任務(wù)的重量級(jí)足夠,那么甚至可以再進(jìn)一步,在每個(gè)任務(wù)提交時(shí)都為它注冊(cè)一個(gè) MBean (然后在任務(wù)完成時(shí)再取消注冊(cè))。然后可以用管理接口查詢每個(gè)任務(wù)的當(dāng)前狀態(tài)、運(yùn)行了多長(zhǎng)時(shí)間,或者請(qǐng)求取消任務(wù)。

    清單 5 中的 ThreadPoolStatus 實(shí)現(xiàn)了 ThreadPoolStatusMBean 接口,它提供了每個(gè)訪問(wèn)器的明顯實(shí)現(xiàn)。與 MBean 實(shí)現(xiàn)類(lèi)中的典型情況一樣,每個(gè)操作實(shí)現(xiàn)起來(lái)都很細(xì)碎,所以把實(shí)現(xiàn)委托給了底層受管對(duì)象。在這個(gè)示例中,JMX 代碼完全獨(dú)立于受管實(shí)體的代碼。TrackingThreadPool 對(duì)于 JMX 一無(wú)所知;通過(guò)為相關(guān)的屬性提供管理方法和訪問(wèn)器,它提供了自己的編程管理接口。 還可以選擇在實(shí)現(xiàn)類(lèi)中直接實(shí)現(xiàn)管理功能(讓 TrackingThreadPool 實(shí)現(xiàn) TrackingThreadPoolMBean 接口),或者單獨(dú)實(shí)現(xiàn)(如清單 4 和 5 所示)。

    清單 5. TrackingThreadpool 的 MBean 實(shí)現(xiàn)

    public class ThreadPoolStatus implements ThreadPoolStatusMBean {
    private
    final TrackingThreadPool pool;
    public
    ThreadPoolStatus(TrackingThreadPool pool) {
    this.pool =
    pool;
    }
    public int
    getActiveThreads() {
    return
    pool.getPoolSize();
    }
    public int
    getActiveTasks() {
    return
    pool.getActiveCount();
    }
    public int
    getTotalTasks() {
    return
    pool.getTotalTasks();
    }
    public int
    getQueuedTasks() {
    return
    pool.getQueue().size();
    }
    public double
    getAverageTaskTime() {
    return
    pool.getAverageTaskTime();
    }
    public
    String[] getActiveTaskNames() {
    return
    toStringArray(pool.getInProgressTasks());
    }
    public
    String[] getQueuedTaskNames() {
    return
    toStringArray(pool.getQueue());
    }
    private String[] toStringArray(Collection<Runnable>
    collection) {
    ArrayList
    <String> list = new ArrayList<String>
    ();
    for
    (Runnable r : collection)
    list.add(r.toString());
    return list.toArray(new String[0
    ]);
    }
    }

    為了演示這些類(lèi)如何提供對(duì)應(yīng)用程序操作的內(nèi)容的了解,請(qǐng)考慮這樣一個(gè) Web 搜尋應(yīng)用程序,它把工作分成兩類(lèi)任務(wù):獲取遠(yuǎn)程頁(yè)面,對(duì)頁(yè)面進(jìn)行索引。每個(gè)任務(wù)分別用清單 6 所示的 FetchTask 或 IndexTask 描述。可以創(chuàng)建 ThreadPoolStatus MBean,提供處理這些任務(wù)所使用的線程池的管理接口,并把它用 JMX 注冊(cè)。

    清單 6. Web 搜尋應(yīng)用程序中使用的 FetchTask 類(lèi)

    public class FetchTask implements Runnable {
    private final String name;

    public FetchTask(String name) {
    this.name = name;
    }

    public String toString() {
    return "FetchTask: " + name;
    }

    public void run() { /* Fetch remote resource */ }
    }

      當(dāng)此程序處理每個(gè)頁(yè)面時(shí),可能還會(huì)對(duì)新任務(wù)進(jìn)行排隊(duì)以獲取這個(gè)頁(yè)面上鏈接的頁(yè)面,所以在指定時(shí)間內(nèi),可能會(huì)既 有獲取任務(wù)又有尚未完成的索引任務(wù)。能夠正確地判斷正在處理哪個(gè)頁(yè)面,或者正在等候處理哪個(gè)頁(yè)面,不僅讓您可以理解應(yīng)用程序的性能特征,還可以理解應(yīng)用程 序所操作的數(shù)據(jù)的特征。

    圖 4 顯示了正在處理 whitehouse.gov 站點(diǎn)的 Web 搜尋程序的快照。從圖中可以看到已經(jīng)獲取并索引了主頁(yè),程序現(xiàn)在的工作是獲取和索引直接從該主頁(yè)鏈接出的頁(yè)面。單擊 Refresh 按鈕,可以對(duì)應(yīng)用程序的工作流程進(jìn)行取樣,它可以提供許多關(guān)于應(yīng)用程序工作情況的信息,卻不需引入大量日志或者在調(diào)試器中運(yùn)行應(yīng)用程序。



    圖 4. Web 搜尋應(yīng)用程序中的活動(dòng)任務(wù)和排隊(duì)任務(wù)

    結(jié)束語(yǔ)

    結(jié)合平臺(tái)內(nèi)的 JMX 支持和 jconsole JMX 客戶機(jī)可以提供一種向應(yīng)用程序添加管理和監(jiān)視功能的輕松方式。即使是沒(méi)有具體管理需求的應(yīng)用程序,為它們構(gòu)建這些功能也會(huì)讓您對(duì)程序的運(yùn)行及其所處理的數(shù) 據(jù)的性質(zhì)獲得深入了解,而且不需太多的工作和努力。如果應(yīng)用程序?qū)С龉芾斫涌冢私涌谧屇梢圆榭此僮鞯膬?nèi)容,那么您就會(huì)更加了解它的運(yùn)行狀態(tài)——對(duì)它 是否按預(yù)期的方式工作也會(huì)更有信心——而不必求助于額外的工具(例如添加日志代碼或使用調(diào)試器或分析器)。

    posted on 2008-07-22 16:37 找個(gè)美女做老婆 閱讀(430) 評(píng)論(0)  編輯  收藏


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


    網(wǎng)站導(dǎo)航:
     

    導(dǎo)航

    統(tǒng)計(jì)

    公告

    本blog已經(jīng)搬到新家了, 新家:www.javaly.cn
     http://www.javaly.cn

    常用鏈接

    留言簿(6)

    隨筆檔案

    文章檔案

    搜索

    最新評(píng)論

    閱讀排行榜

    評(píng)論排行榜

    主站蜘蛛池模板: 亚洲午夜成人精品无码色欲| 亚洲av丰满熟妇在线播放| 亚洲六月丁香婷婷综合| 曰批全过程免费视频网址| 久久国产精品亚洲一区二区| 99久久精品毛片免费播放| 亚洲国产精彩中文乱码AV| 中文字幕无码毛片免费看| 亚洲日本va中文字幕久久| 成全在线观看免费观看大全| 国产亚洲色婷婷久久99精品| 97人妻精品全国免费视频| 亚洲成人动漫在线| 国产精品视频免费观看| 亚洲精品无码av片| 亚洲国产精品自产在线播放| 亚洲视频在线免费| 日产亚洲一区二区三区| 国产三级在线观看免费| 免费无码午夜福利片| 亚洲综合国产一区二区三区| 亚欧免费无码aⅴ在线观看| 亚洲电影在线免费观看| 四虎永久在线精品免费网址 | 亚洲精品无码成人片久久不卡 | 免费无码不卡视频在线观看| 春暖花开亚洲性无区一区二区| 亚洲免费在线观看| 一级毛片在线免费看| 中国亚洲呦女专区| JLZZJLZZ亚洲乱熟无码| 2020因为爱你带字幕免费观看全集| 亚洲AV日韩综合一区尤物| 亚洲精品无码成人片在线观看| 久久精品视频免费看| 亚洲国产精品99久久久久久| 国产亚洲精品久久久久秋霞| 97国产免费全部免费观看| 免费无码午夜福利片| 亚洲成人福利网站| 亚洲午夜福利AV一区二区无码|