2014-09-11 47 views
0

項目:JMX-SflowAgent停止從AspectJ的收集JVM度量儀表的WebSphere Application Server

我使用的sFlow +神經節來監視的WebSphere Application Server的JVM度量(WAS)。 WAS使用AspectJ方面進行檢測。我添加了一個方面來衡量所有應用程序的運行時間。

我使用Hsflowd作爲JVM度量收集器。 Hsflowd內部使用javaagent鉤入JVM,以使用MXBeans(RuntimeMXBean,GarbageCollectorMXBean,CompilationMXBean和ThreadMXBean)收集指標。

問題:

當我運行是沒有aspectjweaver鉤我可以連續看在神經節網所有指標(CPU,書桌,內存,進程等)。但是,當aspectjweaver被添加到JVM參數中,並且在重新啓動服務器之後,我可以看到10分鐘的指標,但是之後它不會在Ganglia網站中報告JVM指標。

在Aspectj編織日誌中,我可以看到AspectJ正在編織JMXsflowAgent代碼。儘管它通過!call(* com.sflow.JMX.SFlowAgent(..))被排除。

看點:

package com.foo.main; 

import java.io.*; 
import java.lang.reflect.Method; 
import java.security.Signature; 
import java.util.*; 

import org.aspectj.lang.ProceedingJoinPoint; 
import org.aspectj.lang.annotation.*; 
import org.osgi.service.application.ApplicationAdminPermission; 

@Aspect 
public class ResponseTimeAspect { 
    @Pointcut(
     "execution(* com.foo.*(..)) && " + 
     "!within(com.foo.main.ResponseTimeAspect) && " + 
     "!within(ThreadLocal+) && " + 
     "!within(&& !within(*..*Aspect)) && " + 
     "!within(com.foo.main.AppInformationReader) && " + 
     "!within(@org.aspectj.lang.annotation.Aspect *) && " + 
     "!within(com.sflow.jmx.SFlowAgent) && " + 
     "!(call(* com.sflow.jmx.SFlowAgent(..)))" 
    ) 
    public void loggingResponseTime() {} 

    private static ThreadLocal<String> uuidContainer = new ThreadLocal<String>() { 
     @Override 
     protected String initialValue(){ 
      return UUID.randomUUID().toString(); 
     } 
    }; 

    AppInformationReader logWriter = AppInformationReader.getInstance(); 

    @Around("loggingResponseTime()") 
    public Object tracing(ProceedingJoinPoint thisJoinPoint) throws Throwable { 

     Long startTime= System.currentTimeMillis(); 
     Long startTotalMemory = Runtime.getRuntime().totalMemory(); 
     Long startFreeMemory = Runtime.getRuntime().freeMemory(); 

     Object ret = thisJoinPoint.proceed(); 

     Long elapsedTime=System.currentTimeMillis() - startTime; 
     Long endTotalMemory = Runtime.getRuntime().totalMemory(); 
     Long endFreeMemory = Runtime.getRuntime().freeMemory(); 
     String methodSignature=thisJoinPoint.getSignature().toString(); 
     String classname=methodSignature.split("\\.")[thisJoinPoint.getSignature().toString().split("\\.").length-1]; 
     String methodName =thisJoinPoint.getSignature().getDeclaringType().getCanonicalName(); 
     logWriter.writeLog(uuidContainer.get().toString(), startTime, System.currentTimeMillis(), elapsedTime, classname, methodName); 
     return ret; 
    } 
} 

的JMX包com.sflow.jmx.SFlowAgent下。

+0

對於我們無法看到的AspectJ或Java代碼以及我們無法看到的配置,我們有點難以說出任何智能。也許你想考慮提供更多的細節,因爲這裏沒有人擁有魔幻水晶球。 – kriegaex 2014-09-13 09:27:30

+0

@ Kriegaex-不需要進一步的配置..我認爲JMX和AspectJ不能在我們的桌面上一起工作。 – 2014-09-16 08:24:40

+0

他們爲什麼不應該? – kriegaex 2014-09-16 11:23:19

回答

0

聲明:這是一個答案,但還不是一個解決方案。寫更多的評論是沒有意義的,所以當我從Vimlesh收集更多信息時,我寧願在此細化我的答案。

好的,不可能只是重現問題的方面,而不是真正的SSCCE顯示有問題的行爲。還有很多懸而未決的問題:

  • 我不知道這個方面有多少類被應用到
  • 有多少線程都在應用服務器和
  • 什麼與內存消耗情況JMX結果之前10分鐘和之後的時間不再顯示。
  • 你說過,SFlow代理只運行一次而不是每10秒運行一次。你怎麼知道的?您能否提供解釋您如何找到並如何重現行爲的信息,最好是在沒有應用程序服務器的情況下使用普通的Java SE VM?
  • 我也想知道爲什麼方面收集有關可用內存的信息。這不是其他Java代理所期望的嗎?爲什麼做兩次?
  • 令我感到奇怪的是,名爲logWriter的變量是AppInformationReader的實例。那麼,讀者或作家是什麼?這個班是做什麼的?該方面使用它,但沒有顯示。
  • 爲什麼你在每個線程中創建了UUID s並且它們用於什麼?他們似乎沒有增加任何價值,正如我在之前發佈的其他問題中所說的那樣。你沒有回答這個問題,你現在可以做嗎?它看起來像無用的開銷。
  • 切入點是矯枉過正。例如,
    • execution(* com.foo.*(..))只捕獲包com.foo下的類中的方法執行,但不包含在任何子包中。所以從子包中排除類是沒有用的。可能你真正想要的是execution(* com.foo..*(..)) - 注意foo..*中的兩個點代表子包。
    • 你誤會我的答案中的其他問題,因爲你沒有選擇我的解決方案,以排除方面和它的內部使用匿名ThreadLocal子類一個,但它們連接在一起的所有&&。這並沒有讓它變得更好或更具可讀性。
    • 您嘗試排除call(* com.sflow.jmx.SFlowAgent(..)),但有兩個原因不是必需的:首先,SFlowAgent不在目標包com.foo中。其次,execution()連接點不能同時爲call()連接點,所以交集必須爲空 - 無需從執行中排除調用。
    • 此語法無效:!within(&& !within(*..*Aspect)) - 可能是一個副本&粘貼有關嵌套within()子句的錯誤。

說了這麼多,你可能想這個切入點:

execution(* com.foo..*(..)) && 
!within(@org.aspectj.lang.annotation.Aspect *) && 
!within(com.foo.main.AppInformationReader) 

這應該是足夠的。

修復了您的切入點後,您可以嘗試停止收集和記錄該方面的信息,以使其更有效。至於其他Java代理,不需要將其從方面編織中排除,但可能需要排除SFlowAgent的目標方面。也許在由SFlow代理程序檢測的方面代碼中存在問題,但這只是一個猜測。也許你的配置是錯的,也許是別的。它看起來好像你正在試圖使用兩種你從未學會使用得足夠好的武器(工具)。如果沒有SSCCE,就很難診斷問題的根本原因。

更新:您還可以嘗試列出AspectJ weaver作爲JVM命令行上的第一個Java代理,即在SFlow代理之前。測試它是否有所作爲。

+0

非常感謝kriegaex指出我的切入點中的錯誤。我一定會學習並糾正它。我修改了我的工作副本,但是由於代碼很大,而且粘貼了一些錯誤,所以發生了一些錯誤。使用-loadersToSkip選項解決了問題,我避免了爲加載Sflowagent類的加載器編織。現在它的工作正常。非常感謝幫助。請更新答案 – 2014-09-18 05:49:44

+0

我應該在我的答案中編輯哪些內容?你沒有回答我的任何問題或遵循我的建議。相反,你告訴我你找到了一個解決方法,這很好。但是根本原因肯定是不同的,因爲你在這裏展示的切入點不應該與其他代理編織在一起。也許你有另一個這樣做,我不知道。請分享一個SSCCE,這樣我們都可以重現原來的問題並學習一些東西。我花了很多時間試圖幫助你最近,但你似乎忽略了我的大部分提示,從不分享全部信息,也無助於使問題重現。 – kriegaex 2014-09-18 09:20:35

+0

讓我試着回答你的問題 - 它應該編織com.foo .. *包下的所有類。由於這方面是針對APM工具的,並且我們對代碼沒有任何概念,所以應用服務器中沒有線程。目標是編織com.foo .. *包下的所有類,並獲取爲1個呼叫流執行的所有方法的響應時間。在10分鐘之前和JMX結果不再顯示後的時間內沒有消耗內存。 我已經下載了代碼中添加的調試代碼並使用此自定義代碼執行。我可以看到ru()下的調試只被調用一次。 – 2014-09-18 12:39:14

相關問題