2014-09-11 14 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

相关问题