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. Java创建对象时的简单内存分析

    简单创建对象的内存分析 主程序: 1 public class Application { 2 public static void main(String[] args) { 3 Animal do ...

  2. Docker安装yapi

    安装docker 1.安装依赖包: yum install -y yum-utils device-mapper-persistent-data lvm2 2.安装 Yum -y install do ...

  3. How to permit SSH root Login in Ubuntu 18.04

    https://www.ubuntu18.com/ssh-permitrootlogin/ SSH root login is disabled by default in Ubuntu 18.04. ...

  4. AtomineerUtils使用说明

    AtomineerUtils使用说明 VS2015PluginCrackAtomineer 介绍 AtomineerUtils 是国外的一款用于生成源代码注释的一款 VS 插件工具. 这款插件,支持 ...

  5. css之单位

    css之单位 角度<angle> 用于<gradient>s和某些transform功能中 deg表示以度为单位的角度.一整圈就是360deg. 例如:0deg,90deg,1 ...

  6. C++ 模板(template) 的定义

    定义: 模板(template)是实现代码重用机制的一种工具,它可以实现类型参数化,把类型定义为参数(模板元编程),从而实现了真正的代码可重用性. 模板是用来批量生成功能和形式都几乎相同的代码的.编译 ...

  7. Nginx模块开发(3)————使用upstream访问第三方服务

    该模块可以完成如下的功能,当我们输入http://你的ip/lcwupstream时,会使用upstream方式访问淘宝搜索,打开淘宝搜索的主页面,代码如下: //start from the ver ...

  8. 慎用ToLower和ToUpper,小心把你的系统给拖垮了

    不知道何时开始,很多程序员喜欢用ToLower,ToUpper去实现忽略大小写模式的字符串相等性比较,有可能这个习惯是从别的语言引进的,大胆猜测下是JS,为了不引起争论,我指的JS是技师的意思~ 一: ...

  9. U盘安装Proxmox VE(一)

    转自我的个人博客:U盘安装Proxmox VE(一) 年前搞了个星际蜗牛B款机箱,利用手头之前海淘dq77kb组装了个四盘位的Server. 组装完毕后,直接在实体机安装了centos 7.使用这几个 ...

  10. HTML 页面跳转的五种方法

    H方法TML 页面跳转的五种方法 下面列了五个例子来详细说明,这几个例子的主要功能是:在5秒后,自动跳转到同目录下的hello.html(根据自己需要自行修改)文件.1) html的实现 <he ...