1. ognl获取bean

SpringContextUtil,通常代码中会有类似这样的工具类用来获取 bean 实例

@Component
public class SpringContextUtil implements ApplicationContextAware { private static ApplicationContext applicationContext; @Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
SpringContextUtil.applicationContext = applicationContext;
} public static Object getBean(String beanName) {
return applicationContext.getBean(beanName);
} public static <T> T getBean(Class<T> clazz) {
return applicationContext.getBean(clazz);
}
}

UserController

@RestController
public class UserController { private static final Logger LOGGER = LoggerFactory.getLogger(UserController.class); @GetMapping("/user/{id}")
public User getUser(@PathVariable Integer id) { if (null == id) {
throw new IllegalArgumentException("id can not be null");
}
if (id < 1) {
throw new IllegalArgumentException("id must be greater than 1");
} return new User(id, "zhangsan");
}
}

使用 arthas 连接 spring 应用,执行如下操作:

  1. 查找全类名

    sc *SpringContextUtil
  2. 查找类加载器

    sc -d *SpringContextUtil | grep classLoaderHash
  3. 使用ognl表达式获取bean,并调用方法

    > ognl -c 18b4aac2 '@com.soulballad.usage.arthasdemo.util.SpringContextUtil@getBean("userController").getUser(2)'

2. watch观测方法调用

# 查看 UserController 下所有方法的 参数、对象、返回值
watch com.soulballad.usage.arthasdemo.web.UserController * '{params,target,returnObj}'

watch 支持方法调用前、调用后、异常抛出等多个场景观测,同时还可以在第四个参数中使用条件进行过滤,比如:

watch com.soulballad.usage.arthasdemo.web.UserController * '{returnObj}' 'params[0]>10'
watch com.soulballad.usage.arthasdemo.web.UserController * '{returnObj}' '#cost>10'

3. 热更新

步骤:使用jad反编译 -> 修改文件 -> 使用mc重新编译修改后的文件->使用redefine加载重新编译后的类

上述 UserController 访问 user/0,会出现如下错误:

There was an unexpected error (type=Internal Server Error, status=500).

id must be greater than 1

现对其进行热更新

  1. 反编译 UserController

    # --source-only 只输出源码
    jad --source-only com.soulballad.usage.arthasdemo.web.UserController > UserController.java
  2. 修改编译后的文件

    package com.soulballad.usage.arthasdemo.web;
    
    import com.soulballad.usage.arthasdemo.model.User;
    import com.soulballad.usage.arthasdemo.util.SpringContextUtil;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.PathVariable;
    import org.springframework.web.bind.annotation.RestController; @RestController
    public class UserController {
    private static final Logger LOGGER = LoggerFactory.getLogger(UserController.class); @GetMapping(value={"/user/{id}"})
    public User getUser(@PathVariable Integer id) {
    if (null == id) {
    throw new IllegalArgumentException("id can not be null");
    }
    if (id < 1) {
    // throw new IllegalArgumentException("id must be greater than 1");
    return new User(id, "lisi"+id);
    }
    return new User(id, "zhangsan");
    }
    }
  3. 重新编译

    # 使用mc重新编译修改后的文件,这里需要使用 -c 指定类加载器
    sc -d com.soulballad.usage.arthasdemo.web.UserController | grep classLoaderHash
    mc -c 18b4aac2 UserController.java

    编译完成会出现一个路径,这个路径就是编译后class文件的位置

  4. 使用redefine重新加载

    # redefine 后面使用上一步的路径,需要将 \ 转成 /
    redefine ../UserController.class

  5. 更新后结果

4. 更新日志级别

查找类加载器

sc -d *UserController | grep classLoaderHas

查看更新前日志级别

ognl -c 18b4aac2 '@com.soulballad.usage.arthasdemo.web.UserController@LOGGER'

更新日志级别为 DEBUG

ognl -c 18b4aac2 '@com.soulballad.usage.arthasdemo.web.UserController@LOGGER.setLevel(@ch.qos.logback.classic.Level@DEBUG)'

查看更新后日志级别

5. tt获取spring上下文

执行 tt 命令来记录 RequestMappingHandlerAdapter#invokeHandlerMethod 的请求

tt -t org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter invokeHandlerMethod

然后访问 user/1,arthas 会记录访问时间片(time fragment)

可以用 tt 命令的 -i 参数来指定index,并且用 -w 参数来执行ognl表达式来获取spring context:

tt -i 1000 -w 'target.getApplicationContext()'

可以从 applicationContext 中获取 bean,触发方法调用

tt -i 1000 -w 'target.getApplicationContext().getBean("userController").getUser(2)'

6. 链接

Arthas 使用(二) —— 应用场景的更多相关文章

  1. 【Unity】实验二 游戏场景搭建

    实验要求 实验二 游戏场景搭建 实验目的:掌握游戏场景搭建. 实验要求:能够使用Unity的地形引擎创建地形,熟悉场景中的光照与阴影,掌握天空盒和雾化效果等. 实验内容: 地形的绘制:使用高度图绘制: ...

  2. Qt开发技术:图形视图框架(二)场景QGraphicsScene、QGraphicsItem与QGraphicsView详解

    前话   Qt的图形视图框架,最核心的三个类为:QGraphicsScene.QGraphicsItem与QGraphicsView.   基于图形框架的高级白板软件Demo QGraphicsSce ...

  3. 【英宝通Unity4.0公开课学习 】(二)场景创建

    本讲共四节,貌似讲课老师的速度变快了,2倍速听不清了...调成了1.7倍...老师果然越来越熟练了啊! 而且最开始的萌妹纸也不再出现在视频里了,我当时还想着完全可以换成老师自己提问嘛! 不过有妹纸声音 ...

  4. LoadRunner测试场景中添加负载生成器

    如何在LoadRunner测试场景中添加负载生成器 本文对如何在LoadRunner的测试场景中添加负载生成器,如何使用负载生成器的方法,总结形成操作指导手册,以指导测试人员指导开展相关工作. 1.什 ...

  5. scrapy 的三个入门应用场景

    说明: 本文参照了官网的 dmoz 爬虫例子. 不过这个例子有些年头了,而 dmoz.org 的网页结构已经不同以前.所以我对xpath也相应地进行了修改. 概要: 本文提出了scrapy 的三个入门 ...

  6. ARPG客户端中场景对象体系设计

    一.场景对象体系 二.场景对象生命周期管理 场景对象的生命周期,不适合采用原始的c++管理方式, 即由使用者自己负责删除.而应该采用引用计数方式, 自动负责删除. 采用引用计数方式, 目前用法比较广的 ...

  7. 3D场景优化

    一) 有效的性能评测 对于任何一个3D应用程序来说,追求场景画面真实感是一个无止尽的目标,其结果就是让我们的场景越来越复杂,模型更加精细,这必然给图形硬件带来极大的负荷以致于无法达到实时绘制帧率.因此 ...

  8. Numpy中Meshgrid函数介绍及2种应用场景

    近期在好几个地方都看到meshgrid的使用,虽然之前也注意到meshgrid的用法.但总觉得印象不深刻,不是太了解meshgrid的应用场景.所以,本文将进一步介绍Numpy中meshgrid的用法 ...

  9. PhiloGL学习(1)——场景创建及方块欲露还羞出水面

    前言 上一篇文章中介绍了我认识PhiloGL框架的机缘以及初步的探讨(见JS前端三维地球渲染--中国各城市航空路线展示),在此文中仅仅对此框架进行了简单介绍并初步介绍了一些该框架的知识.首先三维这个东 ...

随机推荐

  1. .NET Core 使用MediatR CQRS模式

    前言 CQRS(Command Query Responsibility Segregation)命令查询职责分离模式,它主要从我们业务系统中进行分离出我们(Command 增.删.改)和(Query ...

  2. 20199308《Linux内核原理与分析》第十一周作业

    缓冲区溢出漏洞实验 实验步骤 一.初始设置 1.Ubuntu 和其他一些 Linux 系统中,使用地址空间随机化来随机堆(heap)和栈(stack)的初始地址,这使得猜测准确的内存地址变得十分困难, ...

  3. 2019-2020-1 20199308《Linux内核原理与分析》第六周作业

    <Linux内核分析> 第五章 系统调用的三层机制(下) 5.1 给MenuOS增加命令 强制删除当前menu目录,用get clone重新克隆一个新版本的menu,运行make root ...

  4. [Linux] 检查是否已有进程在运行

    出处:sblim-sfcb-1.4.9 / sfcBroker.c int process_is_running() { #define STRBUF_LEN 512 #define BUF_LEN ...

  5. Floyd-Warshall算法正确性证明

    以下所有讨论,都是基于有向无负权回路的图上的.因为这一性质,任何最短路径都不会含有环,所以也不讨论路径中包含环的情形!并且为避免混淆,将"最短路径"称为权值最小的路径,将路径经过的 ...

  6. 【Linux常见命令】tail命令

    tail - output the last part of files tail 命令可用于查看文件的内容,有一个常用的参数 -f 常用于查阅正在改变的日志文件. tail -f filename  ...

  7. 13.Python中的命名空间是什么

    Python中的命名空间是什么? In Python,every name introduced has a place where it lives and can be hooked for. T ...

  8. CentOS配置Tomcat监听80端口,虚拟主机

    2019独角兽企业重金招聘Python工程师标准>>> Tomcat更改默认端口为80 更改的配置文件是: /usr/local/tomcat/conf/server.xml [ro ...

  9. Lucene的FuzzyQuery中用到的Levenshtein Distance(LD)算法

    2019独角兽企业重金招聘Python工程师标准>>> Lucene的FuzzyQuery中用到的Levenshtein Distance(LD)算法 博客分类: java 搜索引擎 ...

  10. 03 Django下载和使用 三板斧httpresponse render redirect

    简介 是一个为完美主义者设计的web框架 The web framework for perfectionists with deadlines. Django可以使你能够用更少的代码,更加轻松且快速 ...