Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

使用Arthas显式执行代码,避免重启应用,10倍提升本地研发效率 #1823

Closed
liuzhiguo630 opened this issue Jun 14, 2021 · 6 comments

Comments

@liuzhiguo630
Copy link

(用户案例)

前提

本方法最适用于 Spring Boot 项目。

谁拖垮了效率?

本地开发时有两个操作最耗时:

  1. 每次代码变更都要重启一次项目,重启的时间相对较长。
  2. 代码深层次的一个方法,也需要有类似 HTTP 的触发入口一层一层调用过来,这是非常麻烦的事。

所以我在寻找一种可以不停机的开发方法,所有变更都能随时生效,代码随写随测。

探索

代码热变更方面,我使用了久负盛名的 IDEA 插件 JRebel。该插件可以做到绝大部分的新增/修改代码,安装使用方式可以在网上搜索。

但有了 JRebel 之后,我发现仍然很难调用看到的方法,如果通过 HTTP 接口调用过来很麻烦,过程很长,并且前后的一些操作的结果也是我不想要的。再比如写着写着突然对某个资源的响应内容不确定。
我希望能随时调用看到的每一个方法。后来看了一些 arthas 的 user case 和文档,大脑中最后几块拼图也终于拼上了。

准备工作

随意调用方法,其实是指 Spring 上下文中的方法。否则直接写 main 方法或 Tester 代码就可以随写随测。以 Spring 的上下文进行调用才是我们想要的。以下是准备工作:

  1. 安装 IDEA Arthas 插件:https://arthas.aliyun.com/doc/idea-plugin.html
  2. 项目中增加依赖 Arthas Spring Boot Starterhttps://arthas.aliyun.com/doc/spring-boot-starter.html ,担心安全问题的话可以只在本地开启,其他环境配置 spring.arthas.enabled = false
  3. 代码中提供获取 Spring ApplicationContext 的变量的方法,参考 https://github.com/WangJi92/arthas-plugin-demo/blob/master/src/main/java/com/wangji92/arthas/plugin/demo/common/ApplicationContextProvider.java,并配置好插件获取 Spring Context 的路径:

截屏2021-06-14 下午1 39 34

开始起飞

使用 JRebel 的方式启动项目,启动后浏览器打开 Arthas 控制台 http://localhost:8563 ,在要调用的方法上选择复制Static Spring Context Invoke Method Field
截屏2021-06-14 下午1 44 03

随后到 Arthas 控制台粘贴即可:
截屏2021-06-14 下午1 46 21
截屏2021-06-14 下午1 46 30

整个开发过程中 Arthas 控制台不用关,随时想测某个方法时,复制命令 -> 控制台执行 -> 观察 即可。

此方法对以下一些场景有奇效:

  1. XXL-Job 任务执行。本地不希望任务在跑,就可以在启动时关闭任务注册功能。测试时也可以不依赖 xxl-job admin 随时调试任务。
  2. Dubbo 服务。不用模拟客户端或者泛化调用之类的,直接用 arthas 整。Arthas 命令不方便设置复杂的入参,这种情况可以在方法中自行覆盖参数,用 JRebel 热更新一下就行。
@hengyunabc hengyunabc changed the title 本地通过 arthas 零停机开发,提高 10x 效率 使用Arthas显式执行代码,避免重启应用,10倍提升本地研发效率 Jun 16, 2021
@zxfxpower
Copy link

不用JRebel启动,获取的context就是null。

@liuzhiguo630
Copy link
Author

不用JRebel启动,获取的context就是null。
这个应该跟 JRebel 没关系,context 是在 arthas idea 里配好的。你看下来 ognl 命令里的 context 路径对不对。

@zxfxpower
Copy link

不用JRebel启动,获取的context就是null。
这个应该跟 JRebel 没关系,context 是在 arthas idea 里配好的。你看下来 ognl 命令里的 context 路径对不对。

试了好多次都是这样,用JRebel启动才行
工程:https://github.com/WangJi92/arthas-plugin-demo.git
ognl setting:@com.wangji92.arthas.plugin.demo.common.ApplicationContextProvider@context
方法调用:ognl -x 3 '#springContext=@com.wangji92.arthas.plugin.demo.common.ApplicationContextProvider@context,#springContext.getBean("commonController").userOgnlX()'

另外运行环境如下:
java 9
macos
idea

@ShuChangCloud
Copy link

大佬 遇到另外一个问题 就是用jrebel的debug模式启动后, 是可以使用TT watch trace等命令的, 可是一改代码, jrebel重新reload以后, 再次使用这些命令后就会报Enhance error! exception: java.lang.NoClassDefFoundError: class names don't match这个错误。 请问下有什么好的解决方案吗

@ZhangMuZhiYa
Copy link

cool

@Raxcl
Copy link

Raxcl commented Sep 23, 2024

不错不错,亲测可用

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants