jmxsflowagent停止从aspectj检测的WebSphereApplicationServer收集jvm度量

uajslkp6  于 2021-05-30  发布在  Hadoop
关注(0)|答案(1)|浏览(485)

项目:
我使用sflow+ganglia来监视websphereapplicationserver(was)的jvm度量。was使用aspectj方面进行检测。我添加了一个方面来度量所有应用程序方法运行时。
我使用hsflowd作为jvm度量收集器。hsflowd在内部使用jmxsflowagent javaagent钩住jvm,使用mxbean(runtimemxbean、garbagecollectormxbean、compilationmxbean和threadmxbean)收集度量。
问题:
当我在没有aspectjweaverhook的情况下运行was时,我可以连续地看到gangliaweb中的所有指标(cpu、桌面、内存、进程等)。但是当aspectjweaver被添加到jvm参数中并且在重启服务器之后,我可以看到10分钟的指标,但是在那之后它不会在gangliaweb中报告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 .

wfsdck30

wfsdck301#

免责声明:这是一个答案,但还不是一个解决方案。写更多的评论是没有意义的,所以我宁愿在这里完善我的答案,因为我从 vim 勒那里收集了更多的信息。
好吧,仅仅用一个方面而不是一个真正的sscce来显示问题行为是不可能重现你的问题的。有很多悬而未决的问题:
我不知道这方面应用到多少类,
应用程序服务器和服务器中有多少线程
jmx结果不再显示之前10分钟和之后10分钟的内存消耗情况。
你说sflow代理只运行一次,而不是每10秒运行一次。你怎么知道的?您能否提供一些信息来解释您是如何发现的,以及如何在没有应用服务器但使用普通javasevm的情况下最佳地再现这种行为?
我还想知道为什么方面收集有关空闲内存的信息。这不是另一个java代理应该做的吗?为什么要做两次?
我觉得奇怪的是 logWriter 是的示例 AppInformationReader . 那它是什么,读者还是作家?这个班是做什么的?方面使用它,但它没有显示。
你究竟为什么要创造 UUID 在方面中,每个线程使用的是什么?它们似乎没有增加任何价值,正如我在你先前发布的另一个问题中所说的那样。你当时没有回答这个问题,现在能回答吗?头顶看起来没用。
切入点太过分了。例如 execution(* com.foo.*(..)) 只捕获直接在包下的类中的方法执行 com.foo ,但不在任何子包中。因此,从子包中排除类是无用的。也许你真正想要的是 execution(* com.foo..*(..)) -注意下面的两点 foo..* 表示子包。
您误解了我在另一个问题中的回答,因为您没有选择我的解决方案之一来排除方面及其内部使用的匿名 ThreadLocal 子类,但用 && . 这并不能使它更好或更可读。
你试图排除 call( * com.sflow.jmx.SFlowAgent(..)) 但有两个原因:第一, SFlowAgent 不在目标包中 com.foo . 其次,一个 execution() joinpoint永远不能是 call() 同时连接点,因此交叉集必须为空-无需从执行中排除调用。
此语法无效: !within(&& !within(*..*Aspect)) -可能是有关嵌套对象的复制和粘贴错误 within() 条款。
话虽如此,你可能想要这个切入点:

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

这应该够了。
在修复了切入点之后,您可以尝试停止收集和记录方面的信息,以提高效率。至于另一个java代理,不需要将其排除在方面编织之外,但是可能需要将方面排除在对象的目标之外 SFlowAgent . 也许sflow代理检测方面代码时有问题,但这只是猜测。也许你的配置不对,也许是别的什么。在我看来,你似乎在试图挥舞两种你从未学好的武器(工具)。没有sscce,很难诊断问题的根本原因。
更新:您还可以尝试将aspectjweaver列为jvm命令行上的第一个java代理,即在sflow代理之前。测试是否有任何区别。

相关问题