使用Arthas获取Spring应用上下文的2种方法 - cdfive

博客园 · · 542 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

背景

项目中有时我们需要对应用进行诊断和调试,如调用某个接口进行业务验证、业务执行、数据修复、刷新缓存、查询数据、跑批量任务等等。

  • 微服务项目
    如基于Dubbo搭建的微服务,我们可使用Dubbo支持的telnet运维管理,其中invoke命令方便直接调用Dubbo接口;
    也可整合swagger-dubbo,方便在网页界面上直接调用Dubbo接口。

  • web项目
    如使用了SpringMVC、Jersey等框架,可考虑暴露一些运维相关的内部rest api,里面调用业务方法,用于某些场景下人工操作处理。

有些情况下以上条件不具备,如不能修改代码、希望不修改代码、不方便修改代码、没有源代码等原因。

Arthas

Arthas 是Alibaba开源的Java诊断工具,可以用于快速诊断Java应用和定位分析问题。
官网:https://arthas.aliyun.com

实战

项目一般都是基于Spring/SpringBoot来构建,如果我们能获取spring的ApplicationContext,就能方便获取spring容器的Bean,然后调用里面的方法。
启动Arthas:java -jar arthas-boot.jar,选择应用。

  • 方法1
    通过Dubbo的SpringExtensionFactory来获取

(1). 先扫描类,-d参数表示获取详细信息
sc -d com.alibaba.dubbo.config.spring.extension.SpringExtensionFactory
注意结果里的classLoaderHash值。

(2). 通过ognl命令,-c参数指定ClassLoader的hash值,即上一步的classLoaderHash值。
ognl -c 6b884d57 '@com.alibaba.dubbo.config.spring.extension.SpringExtensionFactory@contexts.iterator.next'
观察输出结果,此时已成功获取到Spring的ApplicationContext,接下来可以根据场景和需要灵活使用了。

例如,调用某service方法:
ognl -c 6b884d57 '#context=@com.alibaba.dubbo.config.spring.extension.SpringExtensionFactory@contexts.iterator.next,#context.getBean("songService").findRandomSongList(5)'

  • 方法2
    通过实现ApplicationContextAware接口来获取
    (1). 项目中有一个实现了ApplicationContextAware接口的类
    例如:
package com.cdfive.common.util;

import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;

/**
 * @author cdfive
 */
public class SpringContextUtil implements ApplicationContextAware {

    private static ApplicationContext APPLICATION_CONTEXT;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        APPLICATION_CONTEXT = applicationContext;
    }

    public static ApplicationContext getApplicationContext() {
        return APPLICATION_CONTEXT;
    }

    public static <T> T getBean(Class<T> beanType) {
        return getApplicationContext() != null ? getApplicationContext().getBean(beanType) : null;
    }

    public static Object getBean(String beanName) {
        return getApplicationContext() != null ? getApplicationContext().getBean(beanName) : null;
    }
}

(2). 扫描类,-d参数表示获取详细信息
sc -d com.xxx.SpringContextUtil

(3). 调用类里获取ApplicationContext的方法
ognl -c 6b884d57 '@com.cdfive.common.util.SpringContextUtil@getApplicationContext()'
观察输出结果,此时已成功获取到Spring的ApplicationContext,接下来可以根据场景和需要灵活使用了。

例如,调用某service方法:
ognl -c 6b884d57 '#context=@com.cdfive.common.util.SpringContextUtil@getApplicationContext(),#context.getBean("songService").findRandomSongList(5)'

注:方法1需要应用使用了Dubbo框架,方法2则应用范围更广,应用使用了Spring框架即可。

思考

通过Arthas,我们可方便的对Java应用进行分析和诊断,对于测试和线上问题分析和定位很有帮助,并且很大提高了效率;
同时也应注意到安全因素,开发、测试环境还好,线上环境由于正在被使用,开发人员直接操作线上接口有一定风险;
操作失误可能破坏线上数据的完整性,影响系统稳定等等,因此使用上需要有所限制。比如分析线上疑难问题,限制仅调用查询数据的接口;
当有更新数据的需求时,考虑接口的幂等性、做好数据备份、二次确认等,避免在分析线上问题反而造成新的问题,要有严防线上事故的高度警惕。

此外,基于Arthas定制二次开发的系统,或者跟开发IDE结合的插件,可以更好的满足需求,使用上也会更加高效、安全、智能。
参考业内已有的技术分享:

本文来自:博客园

感谢作者:博客园

查看原文:使用Arthas获取Spring应用上下文的2种方法 - cdfive

542 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传