Arthas 使用(二) —— 应用场景
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 应用,执行如下操作:
查找全类名
sc *SpringContextUtil
查找类加载器
sc -d *SpringContextUtil | grep classLoaderHash
使用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
现对其进行热更新
反编译 UserController
# --source-only 只输出源码
jad --source-only com.soulballad.usage.arthasdemo.web.UserController > UserController.java
修改编译后的文件
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");
}
}
重新编译
# 使用mc重新编译修改后的文件,这里需要使用 -c 指定类加载器
sc -d com.soulballad.usage.arthasdemo.web.UserController | grep classLoaderHash
mc -c 18b4aac2 UserController.java
编译完成会出现一个路径,这个路径就是编译后class文件的位置
使用redefine重新加载
# redefine 后面使用上一步的路径,需要将 \ 转成 /
redefine ../UserController.class
更新后结果
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: https://github.com/alibaba/arthas
- https://alibaba.github.io/arthas/tt.html
- https://alibaba.github.io/arthas/ognl.html
- https://alibaba.github.io/arthas/redefine.html
- https://alibaba.github.io/arthas/watch.html
Arthas 使用(二) —— 应用场景的更多相关文章
- 【Unity】实验二 游戏场景搭建
实验要求 实验二 游戏场景搭建 实验目的:掌握游戏场景搭建. 实验要求:能够使用Unity的地形引擎创建地形,熟悉场景中的光照与阴影,掌握天空盒和雾化效果等. 实验内容: 地形的绘制:使用高度图绘制: ...
- Qt开发技术:图形视图框架(二)场景QGraphicsScene、QGraphicsItem与QGraphicsView详解
前话 Qt的图形视图框架,最核心的三个类为:QGraphicsScene.QGraphicsItem与QGraphicsView. 基于图形框架的高级白板软件Demo QGraphicsSce ...
- 【英宝通Unity4.0公开课学习 】(二)场景创建
本讲共四节,貌似讲课老师的速度变快了,2倍速听不清了...调成了1.7倍...老师果然越来越熟练了啊! 而且最开始的萌妹纸也不再出现在视频里了,我当时还想着完全可以换成老师自己提问嘛! 不过有妹纸声音 ...
- LoadRunner测试场景中添加负载生成器
如何在LoadRunner测试场景中添加负载生成器 本文对如何在LoadRunner的测试场景中添加负载生成器,如何使用负载生成器的方法,总结形成操作指导手册,以指导测试人员指导开展相关工作. 1.什 ...
- scrapy 的三个入门应用场景
说明: 本文参照了官网的 dmoz 爬虫例子. 不过这个例子有些年头了,而 dmoz.org 的网页结构已经不同以前.所以我对xpath也相应地进行了修改. 概要: 本文提出了scrapy 的三个入门 ...
- ARPG客户端中场景对象体系设计
一.场景对象体系 二.场景对象生命周期管理 场景对象的生命周期,不适合采用原始的c++管理方式, 即由使用者自己负责删除.而应该采用引用计数方式, 自动负责删除. 采用引用计数方式, 目前用法比较广的 ...
- 3D场景优化
一) 有效的性能评测 对于任何一个3D应用程序来说,追求场景画面真实感是一个无止尽的目标,其结果就是让我们的场景越来越复杂,模型更加精细,这必然给图形硬件带来极大的负荷以致于无法达到实时绘制帧率.因此 ...
- Numpy中Meshgrid函数介绍及2种应用场景
近期在好几个地方都看到meshgrid的使用,虽然之前也注意到meshgrid的用法.但总觉得印象不深刻,不是太了解meshgrid的应用场景.所以,本文将进一步介绍Numpy中meshgrid的用法 ...
- PhiloGL学习(1)——场景创建及方块欲露还羞出水面
前言 上一篇文章中介绍了我认识PhiloGL框架的机缘以及初步的探讨(见JS前端三维地球渲染--中国各城市航空路线展示),在此文中仅仅对此框架进行了简单介绍并初步介绍了一些该框架的知识.首先三维这个东 ...
随机推荐
- application/x-www-form-urlencoded ,multipart/form-data, text/plain
APPLICATION/X-WWW-FORM-URLENCODED MULTIPART/FORM-DATA TEXT/PLAIN 后台返回的数据响应的格式类型 application/x-www-fo ...
- Selenium常见报错问题(2)- 解决和分析StaleElementReferenceException异常
如果你在跑selenium脚本时,需要某些异常不知道怎么解决时,可以看看这一系列的文章,看看有没有你需要的答案 https://www.cnblogs.com/poloyy/category/1749 ...
- 基于jenkins自动打包并部署Tomcat环境
传统网站部署的流程 在运维过程中,网站部署是运维的工作之一.传统的网站部署的流程大致分为:需求分析->原型设计->开发代码->提交代码->内网部署->内网测试->确 ...
- vue-cli3.0 gui初体验
为什么80%的码农都做不了架构师?>>> 介绍 新版的vuecli3.0提供了一个vue ui这个命令,这个命令是做什么的呢,这里引用官网的一段介绍 vue ui 你可以通过 v ...
- java集合的简单用法
typora-root-url: iamge [TOC] 1.集合接口 1.1将集合的接口与实现分离 与现代的数据结构类库的常见情况一样,Java集合类库也将接口(interface)与实现(im ...
- ELSE 技术周刊(2017.12.25期)
业界动态 V8 release v6.4 V8引擎发布v6.4,在速度和内存优化上又带来了一些提升.对于instanceof操作符的优化,带来了3.6x速度提升,同时使得uglify-js提高了15- ...
- Egg Dropping Puzzle
The Two Egg Problem 曾经是Google的一道经典题. 题意:有一个百层高楼,鸡蛋在\(L\)层及以下扔都不碎,在\(L\)层以上都会碎.现在某人有\(k\)个鸡蛋,问在最坏情况下, ...
- 数据结构--栈(附上STL栈)
定义: 栈是一种只能在某一端插入和删除数据的特殊线性表.他按照先进先出的原则存储数据,先进的数据被压入栈底,最后进入的数据在栈顶,需要读数据的时候从栈顶开始弹出数据(最后被压入栈的,最先弹出).因此栈 ...
- Linux下创建软、硬链接
在linux系统中,内核为每一个新创建的文件分配一个Inode(索引节点),每个文件都有唯一的inode号.文件属性保存在索引节点里,在访问文件时,索引节点被复制到内存,从而实现文件的快速访问. 链接 ...
- basicRF双向灯光控制
题目: 实现基于BasicRF无线点对点通信的双向灯光控制,具体要求如下: 1> 节点A 和节点B 的PANID设置为0x1234,通道号设置为17,节点地址自定义.<2> 按下节点 ...


