漫画:Java如何实现热更新?

Arthas(阿尔萨斯)是 Alibaba 开源的一款 Java 诊断工具,使用它我们可以监控和排查 Java 程序,然而它还提供了非常实用的 Java 热更新功能。

所谓的 Java 热更新是指在不重启项目的情况下实现代码的更新与替换。使用它可以实现不停机更新 Java 程序,尤其是对那些启动非常耗时的 Java 项目来说,更是效果显著。

Arthas 的使用其实非常简单,它为我们提供了一个 Jar 包,我们只需要把这个 Jar 下载到本地,然后运行这个 Jar 包就可以正常使用它的功能了。

Arthas 功能简述

当你遇到以下类似问题而束手无策时,Arthas 可以帮助你解决(来自官方):

  1. 这个类从哪个 jar 包加载的?为什么会报各种类相关的 Exception?

  2. 我改的代码为什么没有执行到?难道是我没 commit?分支搞错了?

  3. 遇到问题无法在线上 debug,难道只能通过加日志再重新发布吗?

  4. 线上遇到某个用户的数据处理有问题,但线上同样无法 debug,线下无法重现!

  5. 是否有一个全局视角来查看系统的运行状况?

  6. 有什么办法可以监控到JVM的实时运行状态?

  7. 怎么快速定位应用的热点,生成火焰图?

Arthas 支持 JDK 6+,支持 Linux/Mac/Winodws,它采用命令行交互模式,同时提供丰富的 Tab 自动补全功能,进一步方便进行问题的定位和诊断。

Arthas 使用

Arthas 的使用步骤如下。

步骤一:下载 Arthas

首先,我们先把 Arthas 的 Jar 包下载到本地,它的下载地址是:https://alibaba.github.io/arthas/arthas-boot.jar

步骤二:启动 Arthas

我们只需要使用普通的 jar 包启动命令:java -jar arthas-boot.jar 来启动 Arthas 即可,启动成功之后的运行界面如下:


如上图所示则表示 Arthas 启动成功。

小贴士:当我们运行 java -jar arthas-boot.jar 命令时,首先需要先切换目录至该 jar 包的位置,才能正常的启动 Arthas。

步骤三:运行 Arthas

当我们启动完 Arthas 之后,根据上图的提示,我们需要选择一个要调试的 Java 进程,例如我们输入“4”来监测我自己写的一个 Java 测试程序,执行结果如下:


当出现 Arthas 的 logo 之后,表示 Arthas 正常加载了 Java 进程。

步骤四:操作 Arthas

当 Arthas 加载 Java 进程成功之后,我们就可以输入相关的命令来查看相关的信息了。

假如我们把本地环境视为生产服务器,我们此时需要查看某个运行的 Java 程序是否为最新版的。

在没有 Arthas 之前,我们通常的步骤是这样的:

  1. 找到相应的 jar 包(或者 war 包);

  2. 将 jar 包(或者 war 包)下载到本地;

  3. 找出相应的类进行解压操作;

  4. 然后将解压的 class 文件拖拽到 Java 编译器(Idea 或 Eclipse)中,查看是否为最新的代码。

但如果使用的是 Arthas,那么我们就可以直接通过反编译命令,将字节码编译为正常的 Java 代码,然后再确认是否为最新的代码即可。我们只需要执行 jad 命令即可,实现示例如下:


这样我们就可以直接来查看这个发布的程序是否为最新版本了。

不仅如此,我们还可以使用 Arthas 来监测整个程序的运行情况,如下图所示:

我们还可以用 Arthas 来查看一些 JVM 的相关信息,如下图所示:


更多 Arthas 的功能,请访问:https://alibaba.github.io/arthas/commands.html

热更新 Java 代码

假如我们原来的代码是这样的:

package com.example;import java.util.concurrent.TimeUnit;public class App {public static void main(String[] args) throws InterruptedException {while (true) { // 每两秒钟打印一条信息TimeUnit.SECONDS.sleep(3);sayHi();}}private static void sayHi() {// 需要修改的标识boolean flag = true;if (flag) {System.out.println("Hello,Java.");} else {System.out.println("Hello,Java中文社群.");}}
}

我们现在想要把 flag 变量改为 false 就可以这样来做:

  1. 使用 Arthas 的内存编译工具将新的 Java 代码编译为字节码;

  2. 使用 Arthas 的 redefine 命令实现热更新。

1.编译字节码

首先,我们需要将新的 Java 代码编译为字节码,我们可以通过 Arthas 提供的 mc 命令实现,mc 是 Memory Compiler(内存编译器)的缩写。

实现示例如下:

[arthas@3478]$ mc /Users/admin/Desktop/App.java -d /Users/admin/Desktop
Memory compiler output:
/Users/admin/Desktop/com/example/App.class
Affect(row-cnt:1) cost in 390 ms.

其中 -d 表示编译文件的存放位置。

小贴士:我们也可以使用 javac App.java 生成的字节码,它与此步骤执行的结果相同。

2.执行热更新

有了字节码文件之后,我们就可以使用 redefine 命令来实现热更新了,实现示例如下:

[arthas@51787]$ redefine /Users/admin/Desktop/com/example/App.class
redefine success, size: 1

从上述结果可以看出,热更新执行成功,此时我们去控制台查看执行结果,如下图所示:

这说明热更新执行确实成功了。

Arthas 热更新注意事项

使用热更新功能有一些条件限制,我们只能用它来修改方法内部的一些业务代码,如果我们出现了以下任意一种情况,那么热更新就会执行失败:

  1. 增加类属性(类字段);

  2. 增加或删除方法;

  3. 替换正在运行的方法。

最后一条我们需要单独说明一下,假如我们把上面的示例改为如下代码:

package com.example;import java.util.concurrent.TimeUnit;public class App {public static void main(String[] args) throws InterruptedException {while (true) { // 每两秒钟打印一条信息TimeUnit.SECONDS.sleep(3);boolean flag = true;if (flag) {System.out.println("Hello,Java.");} else {System.out.println("Hello,Java中文社群.");}}}
}

那么此时我们再进行热更新操作修改 flag 的值,那么就会执行失败,因为我们替换的是正在运行中的方法,而我们正常示例中的代码之所以能成功,是因为我们在 while 无线循环中调用了另一个方法,而那个方法是被间歇性使用的,因此可以替换成功。

总结

本文我们讲了 Arthas 的概念以及具体的使用流程,Arthas 其实就是一个普通的 Java 程序,我们可以使用 java -jar arthas-boot.jar 来启动它,然后再选择我们要操作的 Java 进程,这样就可以实现状态监控和其他操作。

文章的后半部分,我们介绍了 Arthas 的热更新功能,而热更新本质上只需要使用一个 redefine 命令来加载新的字节码文件就可以实现热更新了,但需要注意热更新不能替换正在运行的方法,它只能修改方法内部的业务代码,如果修改了类字段或者是更改了类方法,那么热更新就会执行失败。

最后的话原创不易,斥资找人画了漫画,看着老王认真的份上,点个「在看」再走呗,这是对我最大的支持与鼓励,谢谢!往期推荐

我写了10年博客,却被人说“不火”?我是这样怼回去的?

链表竟然比数组慢了1000多倍?(动图+性能评测)

关注下方二维码,每一天都有干货!

点亮“在看”,助我写出更多好文!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/546065.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

自动化运维工具Saltstack详细介绍

Saltstack是一个新的基础设施管理工具。目前处于快速发展阶段,可以看做是pssh弱化的Puppet的组合。间接的反映出了saltstack的两大功能:远程执行和配置管理。Saltstack使用Python开发,是一个非常简单易用和轻量级的管理工具。由Master和Minio…

为什么建议你使用枚举?

枚举是 JDK 1.5 新增的数据类型,使用枚举我们可以很好的描述一些特定的业务场景,比如一年中的春、夏、秋、冬,还有每周的周一到周天,还有各种颜色,以及可以用它来描述一些状态信息,比如错误码等。枚举类型不…

数据结构树二叉树计算节点_查找二叉树中叶节点的数量 数据结构

数据结构树二叉树计算节点Algorithm: 算法: One of the popular traversal techniques to solve this kind of problems is level order tree traversal (Read: Level Order Traversal on a Binary Tree) where we use the concept of BFS. 解决此类问题的一种流行…

重磅!阿里推出国产开源JDK!

简介Alibaba Dragonwell 是一款免费的, 生产就绪型Open JDK 发行版,提供长期支持,包括性能增强和安全修复。阿里巴巴拥有最丰富的Java应用场景,覆盖电商,金融,物流等众多领域,世界上最大的Java用户之一。Al…

安装TPCC-MySQL报错

2019独角兽企业重金招聘Python工程师标准>>> 安装TPCC-MySQL做压力测试,由于TPCC-MySQL是bzr工具进行版本控制的,所以要先安装bzr [rootmha_backup /root] #rpm -Uvh http://dl.fedoraproject.org/pub/epel/5/i386/epel-release-5-4.noarch.r…

自由职业的前半年,我是如何度过的?

生活中所受的苦,终会以一种形式回归。我是一个后知后觉的人,从 2009 年毕业到现在,已经有 11 年的光景了,参加工作的前几年我从没想过要快速的提升自己的技能,对待工作也没有全力以赴,这样的迷茫和随大流的…

Eucalyptus常用查询命令

前言: Elastic Utility Computing Architecture for Linking Your Programs To Useful Systems (Eucalyptus) 是一种开源的软件基础结构,用来通过计算集群或工作站群实现弹性的、实用的云计算。它最初是美国加利福尼亚大学 Santa …

调整灰度图像的大小,而无需在Python中使用任何内置函数

In this program, we will be using two functions of OpenCV-python (cv2) module. Lets see their syntax and descriptions first. 在此程序中,我们将使用OpenCV-python(cv2)模块的两个功能。 首先让我们看看它们的语法和说明。 1) imread():It takes an absolu…

漫画:对象是如何被找到的?句柄 OR 直接指针?

小贴士:想要使用并定位 Java 对象,就要用到 Java 虚拟机栈(Java Virtual Machine Stack),它描述的是 Java 方法执行的线程内存模型:每个方法被执行的时候,Java 虚拟机都会同步创建一个栈帧&…

IDEA 不为人知的 5 个骚技巧!真香!

工欲善其事,必先利其器,磊哥最近发现了几个特别棒的 IDEA“骚”技巧,已经迫不及待的想要分享给你了,快上车...1.快速补全行末分号使用快捷键 Shfit Ctrl Enter 轻松实现。2.自带的 HTTP 请求工具IDEA 自带了 HTTP 的测试工具&am…

漫画:Integer 竟然有 4 种比较方法?

代码测试public class IntegerTest {public static void main(String[] args) {Integer i1 127;Integer i2 127;System.out.println(i1 i2);Integer i3 128;Integer i4 128;System.out.println(i3 i4);} }以上代码的执行结果为:truefalse首先,当我…

6种快速统计代码执行时间的方法,真香!(史上最全)

我们在日常开发中经常需要测试一些代码的执行时间,但又不想使用向 JMH(Java Microbenchmark Harness,Java 微基准测试套件)这么重的测试框架,所以本文就汇总了一些 Java 中比较常用的执行时间统计方法,总共…

连夜整理了几个开源项目,毕设/练手/私活一条龙!

一直以来,总有小伙伴问说:诶,有没有什么好的项目推荐啊,想参考使用。一般用途无非如下几种情况:自学练手:从书本和博客的理论学习,过渡到实践练手吸收项目经验,找工作写简历时能参考…

MPI编程简单介绍

第三章 MPI编程 3.1 MPI简单介绍 多线程是一种便捷的模型,当中每一个线程都能够訪问其他线程的存储空间。因此,这样的模型仅仅能在共享存储系统之间移植。一般来讲,并行机不一定在各处理器之间共享存储,当面向非共享存储系统开发…

最简单的6种防止数据重复提交的方法!(干货)

有位朋友,某天突然问磊哥:在 Java 中,防止重复提交最简单的方案是什么?这句话中包含了两个关键信息,第一:防止重复提交;第二:最简单。于是磊哥问他,是单机环境还是分布式…

漫画:如何证明sleep不释放锁,而wait释放锁?

wait 加锁示例public class WaitDemo {private static Object locker new Object();public static void main(String[] args) throws InterruptedException {WaitDemo waitDemo new WaitDemo();// 启动新线程,防止主线程被休眠new Thread(() -> {try {waitDemo…

设计模式 之 建造者

建造者模式(Builder Pattern) 一听这个名字,你可能就会猜到一二分了。建造者简单理解就是造东西,仅仅只是建造者模式建造的不是一个简单的东西,是一个比較复杂的东西。就好像盖房子,须要打地基、砌墙、灌…

支付宝上市,让我损失了2000万(盘点这些年错过的机会)

选择大于努力!这句话在之前,我只是用排除法来解释它(如果你的选择是错的,那么走的越快就离目标越远),而如今几次亲身的经历,却给了我不同的答案...近几天支付宝上市的事儿,传的沸沸扬…

(转)深入理解最强桌面地图控件GMAP.NET --- 原理篇

前几篇介绍了一些国内地图的案例, 深入理解最强桌面地图控件GMAP.NET --- SOSO地图 深入理解最强桌面地图控件GMAP.NET --- 百度地图 我们以Google地图为例,这章介绍下地图加载的原理。 投影(Projection) 谷歌地图采用的是墨卡托投影法,这里转载(http://…

LeetCode刷题--- 字母大小写全排列

个人主页:元清加油_【C】,【C语言】,【数据结构与算法】-CSDN博客 个人专栏 力扣递归算法题 http://t.csdnimg.cn/yUl2I 【C】 http://t.csdnimg.cn/6AbpV 数据结构与算法 http://t.csdnimg.cn/hKh2l 前言:这个专栏主要讲述递归递归、搜索与回…