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. JWT验证机制【刘新宇】【Django REST framework中使用JWT】

    JWT 在用户注册或登录后,我们想记录用户的登录状态,或者为用户创建身份认证的凭证.我们不再使用Session认证机制,而使用Json Web Token认证机制. 什么是JWT Json web t ...

  2. shll脚本常用格式和规则使用

    shll脚本格式和规则 脚本文件必须已 .sh 结尾(yuan.sh) 脚本第一行必须是:#!/bin/bash 激活脚本的二种方式(sh yuan.sh)(给脚本X权限,以绝对路径执行脚本) 逻辑与 ...

  3. 面试官:你对Redis缓存了解吗?面对这11道面试题你是否有很多问号?

    前言 关于Redis的知识,总结了一个脑图分享给大家 1.在项目中缓存是如何使用的?为什么要用缓存?缓存使用不当会造成什么后果? 面试官心理分析 这个问题,互联网公司必问,要是一个人连缓存都不太清楚, ...

  4. JavaScript学习笔记(1)字符串方法

    字符串方法 length 属性返回字符串的长度 var txt = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; var sln = txt.length; inde ...

  5. JDK14的新特性

    文章目录 虽然JDK13在今年的9月17号才发布,但是丝毫不会影响到下一个版本JDK14的开发工作.听说官方定的新功能马上就要官宣了,我们这里不妨来提前推断一下. 在9月17号的发布中,Oracle提 ...

  6. 009.Ansible模板管理 Jinja2

    一 Jinja2简介 Jinja2是基于python的模板引擎. 假设说现在我们需要一次性在10台主机上安装redis,这个通过playbook现在已经很容易实现.默认情况下,所有的redis安装完成 ...

  7. 字符串translate方式实现

    在爬取百度图片的时候,发现百度图片做了反爬虫处理,在网上找到当前还能跑通的教程实例:python3多线程下载百度图片搜索结果. 在分析代码的过程中,发现作者对爬取的objURL的解码是通过字符串的tr ...

  8. 解决Vue-cli3.0下scss文件编译过慢、卡顿问题

    在使用Vue-cli 3.0构建的项目中,可能存在项目编译过慢的问题,具体表现在编译时会在某一进度比如40%时停顿,等好一会儿才能够编译完成.这使得浏览器中的实时预览也会卡顿,不利于我们快速查看效果, ...

  9. 在独立的 Root 和 Home 硬盘驱动器上安装 Ubuntu

    安装 Linux 系统时,可以有两种不同的方式.第一种方式是在一个超快的固态硬盘上进行安装,这样可以保证迅速开机和高速访问数据.第二种方式是在一个较慢但很强大的普通硬盘驱动器上安装,这样的硬盘转速快并 ...

  10. Native Boot 从一个 VHD 引导系统的相关说明

    Native Boot 是 Windows 7 和 Windows Server 2008 R2 提供的一个新的功能,它允许从一个 VHD 文件引导一个操作系统,但是需要注意的是目前的 Windows ...