百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术资源 > 正文

如何在线上为所欲为 时间停止我为所欲为时间暂停怀表

lipiwang 2024-10-31 15:23 17 浏览 0 评论

概述

如果你看到这个标题想到的是 Arthas ,那么恭喜你,你想的跟我一样~

如果你看到这个标题一点想法的没有,那你可能真的需要系统性学习一下 arthas 了。arthas 是一款线上监控诊断工具,可以在不修改应用的情况下,对业务问题进行诊断。现在不用上几手 arthas ,都不好意思出门跟人调 bug了。

如果你想到的是 bpf,bcc 之类的,那你是真个大佬,大哥带带弟弟.jpg

准备工作

首先写一段简单的 java 代码,用来测试

import java.util.Arrays;
import java.util.Random;
import java.util.concurrent.TimeUnit;

/**
 * 求和测试类
 *
 * @author xisha
 * @date 2022/5/9 7:33 下午
 */
public class SumDemo {

    public static void main(String[] args) throws Exception {
        SumDemo demo = new SumDemo();
        while (true) {
            demo.test();
            TimeUnit.SECONDS.sleep(3);
        }
    }

    public void test() {
        Random random = new Random(System.currentTimeMillis());
        int numberSize = random.nextInt(5);

        int[] numbers = new int[numberSize];
        for (int i = 0; i < numberSize; i++) {
            numbers[i] = random.nextInt(10);
        }
        System.out.println(sum(numbers));
    }

    public Integer sum(int... numbers) {
        return Arrays.stream(numbers).sum();
    }

}

代码很简单,就是一直生成几个随机数,然后求和,跑起来的效果大概如下



然后下载 arthas curl -O arthas.aliyun.com/arthas-boot…

更多下载方式见 arthas.aliyun.com/doc/install…

然后 java -jar arthas-boot.jar 选择我们的 SumDemo 进行 attach

成功之后的界面大概如下图



常用功能

  1. 查看 sum 方法每次传入的参数都是啥。
  2. 修改sum方法的返回,使其返回一个固定的值。
  3. 查看 SumDemo 类的代码。

如果大佬对上面三个功能了如指掌,那么直接跳到下一章节即可。

watch 参数

watch SumDemo sum '{params,returnObj,throwExp}' -n 5 -x 3



反编译

有时候我们想看看线上的代码是不是我们想要的,我们可以通过 jad 命令进行在线反编译。 jad SumDemo

效果大概如下图所示,我们可以可以方便的看到这个类的代码,类加载器,类文件的路径(这个在确定线上包的版本的时候十分有用)



更多 jad 的用法可以查看 arthas.aliyun.com/doc/jad.htm…

热更新一条龙

现在让我们尝试修改 sum 函数的返回值,使其返回一个固定的值 public Integer sum(int... numbers) { return 49; //return Arrays.stream(numbers).sum(); } 改完之后通过 arthas 编译一个 class

首先我们需要找到 SumDemo 的类加载器的hash值 输入 sc -d *SumDemo , 对应的 classLoaderHash 就是我们需要的hash值,如图所示,我这边的 hash 值是 277050dc



然后用这个类加载编译一下刚才改好的 java 文件 mc -c 277050dc ./SumDemo.java



如上图所示,编译就算是成功了,如果不成功的话,可能是有些特殊情况,比如用了lombok,泛型对不上等等,要是失败了…… 那就算了,你跟这个命令莫得缘分。

然后我们使用 redefine 命令,

redefine classpath ,就可以热更新这个类了。





可以看到,热更新之后,我们的代码就只返回 49了。

注意,这里为什么先讲 jad 再讲 热更新呢? 因为 jad 命令跟 redefine 命令是冲突的,jad 会还原 redefine 产生的字节码,详见文档arthas.aliyun.com/doc/redefin…

为所欲为

上面讲了这么多,都是一些问题调试的功能,怎么就为所欲为了呢?

使用spring context 为所欲为

在 spring 的项目中,如果你有【保存 spring 上下文,以便自己下次使用】的习惯(如下代码),

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

@Component
public class SpringBeanUtil implements ApplicationContextAware {

    private static ApplicationContext applicationContext;

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

    public static <T> T getBean(Class<T> clazz) {
        return (T) applicationContext.getBean(clazz);
    }

    public static Object getBean(String name) throws BeansException {
        return applicationContext.getBean(name);
    }
}

那么你可以用 arthas 获取这个上下文,然后再获取相应的bean,然后就可以为所欲为了。对应的 arthas 代码如下

ognl '#context=@SpringBeanUtil@applicationContext, #context.getBean("yourbeanName").doSomething()'

注意:加载对应的类可能需要对应的类加载器Hash,可以使用 sc -d *SpringBeanUtil 命令来获取类加载器 Hash,然后再使用 ognl 的时候加上 -c 选项即可。

使用 tt 为所欲为

如果没有【保存 spring 上下文】也不打紧,一般的 spring项目 都会有 http 接口(甚至健康检查的接口就是 http 接口),这个时候我们可以使用 tt 命令为所欲为。原理是找一个调用链路里有 spring 上下文的类,然后基于这个类记录这个请求,然后通过重放这个请求,达到执行任意 bean 代码的目的。比如 RequestMappingHandlerAdapter#invokeHandlerMethod 这个就很合适。具体过程如下:

我们先使用 tt 命令记录这个请求

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

然后等一个请求



大概像这样,然后再用 tt 命令,-i 可以指定重放的请求,-w 可以执行ognl,然后为所欲为的代码大概如下

tt -i 1000 -w 'target.getApplicationContext().getBean('yourbeanName').doSomething()'

基于 dubbo 为所欲为

有人说我莫得 http 接口,全是 dubbo 的调用,那这个咋整?不慌的,dubbo 某个拓展里自动为我们保存了 spring 上下文,直接为所欲为即可。代码如下:

ognl '#context=@com.alibaba.dubbo.config.spring.extension.SpringExtensionFactory@contexts.iterator.next, #context.getBean("yourBeanName").doSomeThing()'

vmtool 获取实例为所欲为

如果我的应用啥也没有,没有dubbo,甚至都不是 spring 的,那我要如何为所欲为呢? 这个时候我们可以使用 vmtool,直接获取对象进行为所欲为。当我看到这个工具的时候真是直呼好家伙!太强了简直! 以我们的SumDemo 为例,我们可以直接获取这个类进行函数调用,示例代码如下 vmtool --action getInstances --className SumDemo --express 'instances[0].test()'

相关推荐

一个简单便捷搭建个人知识库的开源项目(MDwiki)

这里我通过自动翻译软件,搬运总结MDwiki官网的部署和使用方法。第一步:下载编译好的后MDwiki文件,只有一个HTML文件“mdwiki.html”。第二步:在mdwiki.html同级目录创建“...

强大、简洁、快速、持续更新 PandaWiki新一代 AI 驱动的开源知识库

PandaWiki是什么PandaWiki是一款AI大模型驱动的开源知识库搭建系统,帮助你快速构建智能化的产品文档、技术文档、FAQ、博客系统,借助大模型的力量为你提供AI创作、AI问答...

DeepWiki-Open: 开源版Deepwiki,可自己构建github文档库

Deepwiki是Devin团队开发的github文档库,用户能免费使用,但代码不是开源,而DeepWiki-Open侧是开源版本的实现。DeepWiki-Open旨在为GitHub和GitLa...

最近爆火的wiki知识管理开源项目PandaWiki

项目介绍PandaWiki是一款AI大模型驱动的开源知识库搭建系统,帮助你快速构建智能化的产品文档、技术文档、FAQ、博客系统,借助大模型的力量为你提供AI创作、AI问答、AI搜索等...

轻量级开源wiki系统介绍(轻量开源论坛系统)

wiki系统有很多DokuWiki、MediaWiki、MinDoc等等都是开源的wiki系统。商业版的wiki,像很多企业在用的confluence等。今天我们讲的是一款轻量级且开源的文档管理系统:...

DNS解析错误要怎么处理(dns解析状态异常怎么办)

在互联网时代,网络已经成为人们生活和工作中不可或缺的一部分。然而,当遇到DNS解析错误时,原本畅通无阻的网络访问会突然陷入困境,让人感到十分困扰。DNS,即域名系统,它如同互联网的电话簿,将人们易于...

网页加载慢?这些方法让你秒开网页!

打开浏览器,信心满满地准备查资料、看视频或者追剧,却发现网页怎么都打不开!是不是瞬间感觉手足无措?别慌,这个问题其实挺常见,而且解决起来并没有你想象的那么复杂。今天就来聊聊网页打不开究竟是怎么回事,以...

windows11 常用CMD命令大全(windows11msdn)

Windows11中的命令提示符(CMD)是一个强大的工具,可以通过命令行执行各种系统操作和管理任务。以下是一些常用的CMD命令,按功能分类整理,供你参考:一、系统信息与状态systeminfo显...

电脑提示DNS服务器未响应怎么解决?

我们在使用电脑的时候经常会遇到各种各样的网络问题,例如最近就有Win11电脑用户在使用的时候遇到了DNS未响应的问题,遇到这种情况我们应该怎么解决呢?  方法一:刷新DNS缓存  1、打开运行(W...

宽带拨号错误 651 全解析:故障定位与修复方案

在使用PPPoE拨号连接互联网时,错误651提示「调制解调器或其他连接设备报告错误」,通常表明从用户终端到运营商机房的链路中存在异常。以下从硬件、系统、网络三层维度展开排查:一、故障成因分类图...

如何正确清除 DNS 缓存吗?(解决你访问延时 )

DNS缓存是一个临时数据库,用于存储有关以前的DNS查找的信息。换句话说,每当你访问网站时,你的操作系统和网络浏览器都会保留该域和相应IP地址的记录。这消除了对远程DNS服务器重复查询的...

网络配置命令:ipconfig和ifconfig,两者有啥区别?

在计算机网络的世界里,网络接口就像是连接你电脑和外部网络的桥梁,而网络配置则是确保这座桥梁稳固、通信顺畅的关键。提到网络配置工具,ipconfig和ifconfig绝对是两个绕不开的名字。它们一...

救急的命令 你会几个?(救急一下)

很多人都说小编是注册表狂魔,其实不完全是,小编常用的命令行才是重点。其实所谓的命令行都是当初DOS时代的标准操作方式,随着Windows不断演化,DOS的命令早已成为Windows的一部分了——开始菜...

电脑有网却访问不了GitHub原来是这样

当满心欢喜打开电脑,准备在GitHub这个“开源宝藏库”里挖掘点超酷的项目,却遭遇了网页无法访问的尴尬。看着屏幕上那令人无奈的提示,原本高涨的热情瞬间被泼了一盆冷水,是不是感觉世界都不美好了...

rockstargames更新慢| r星更新速度 怎么办 解决办法

rockstargames更新慢|r星更新速度怎么办解决办法说到RockstarGames,那可是游戏界的大佬,作品个顶个的经典。但话说回来,每当新内容更新时,那蜗牛般的下载速度,真是让人急得...

取消回复欢迎 发表评论: