文档章节

优雅的给线上环境打补丁

xpbob
 xpbob
发布于 2018/11/06 00:45
字数 766
阅读 18
收藏 0

场景

在线上往往会遇到一些比较尴尬的异常,例如空指针。这种操作往往是某些情况校验不完善,客户输入了各种奇怪的内容导致的。当遇到这种情况的时候,修改都很方便,但是如何更新到线上是个问题了。为一个小问题,重新更换环境就动作有点大了,还得晚上派人值守。

更新方式

我们主要利用了2中java的外挂技术来完成这种不重启更新环境。这两种技术分别是javaagent以及 Vitural Machine attach。attach主要是为了把javaagent给attach到目标进程上。javaagent里主要写类的重新转化工作。

public class Transform implements ClassFileTransformer {

	@Override
	public byte[] transform(ClassLoader loader, String className, Class<?> classBeingRedefined,
			ProtectionDomain protectionDomain, byte[] classfileBuffer) throws IllegalClassFormatException {

		if (className.contains(Main.CLASS_NAME)) {//过滤类
			byte[] readAllBytes = null;
			try {
			//读取修改后的字节码
				readAllBytes = Files.readAllBytes(Paths.get("E:\\delete\\Nep.class"));
			} catch (IOException e) {
				e.printStackTrace();
			}
			return readAllBytes;
		}
		return null;
	}

}

当类加载或者重新转化的时候会经过ClassFileTransformer的 transform方法,返回null表示字节码没有任何修改,如果返回一个新的数组,就可以替换加载到内存的字节码了。

	public static void agentmain(String args, Instrumentation ins) throws UnmodifiableClassException {
		//第二个参数表示是否能重新定义
		ins.addTransformer(new Transform(), true);
		List<Class> transformClass =new ArrayList<Class>();
		Class[] allLoadedClasses = ins.getAllLoadedClasses();
		for (Class clazz : allLoadedClasses) {
			if (clazz.getName() != null && clazz.getName().contains(CLASS_NAME)) {
				transformClass.add(clazz);
			}
		}
		if(!transformClass.isEmpty()){
			ins.retransformClasses(transformClass.toArray(new Class[0]));
		}
}

agentmain是一个入口函数。当agent加载以后,会从这里执行。Instrumentation 可以帮我们获取到所有加载到内存的类。然后根据要求筛选出合适的类进行重新转化。(省略掉attach代码) 利用这种方式。我们就可以把编译好的字节码准备好,然后以文件流的形式读取到内存中,进行动态的替换类的实现。

适用场景

重转换可能会更改方法体、常量池和属性。重转换不得添加、移除、重命名字段或方法;不得更改方法签名、继承关系。在以后的版本中,可能会取消这些限制。在应用转换之前,类文件字节不会被检查、验证和安装。如果结果字节错误,此方法将抛出异常。

这里是jdk文档里说明的,你的类如果是加了字段,那就不行了。文档中说可能会取消这些限制,现在是可以新增或删除方法,必须是private static以及private final。替换的过程会STW。这个过程非常短暂,相比替换版本而言,这个已经是代价非常小了。

© 著作权归作者所有

上一篇: 聊聊LinkedHashMap
下一篇: 从classloader说起
xpbob

xpbob

粉丝 98
博文 98
码字总数 80029
作品 0
高级程序员
私信 提问
Windows Server 2012 R2修复MS15-034漏洞

环境: windows Server 2012 R2 要求: 要求尽量少的打补丁,最好只打这一个 方案: 1.MS15-034漏洞的补丁是KB3042553;2.如果在一台Windows Server 2012 R2的服务器上直接安装补丁文件KB304...

董志勇
2017/10/10
0
0
问题定位方法

1.1 问题原因分析 从问题发生的环境,大致可分为线上环境问题、测试环境问题、本地环境问题。 1.1.1 线上环境问题 线上环境问题大致可分为阻塞性问题和非阻塞性问题。其中,阻塞性问题是影响...

Fraud
2018/01/11
0
0
mysql设计之开发规范

原则 数据库就是数据库,不是计算器 读写分离,缓解在线库压力 合并写入、瞬间压力,分多次批量提交 本地写队列,防止意外崩溃丢失数据 垂直拆分,大数据字段独立拆分 水平拆分,冷热数据分离...

落叶刀
2016/06/06
19
0
玩转迭代开发

玩转迭代开发 现在互联网开发都处于快速迭代开发的状态。这里我们来讨论一下迭代开发中的生命周期,代码版本,兼容性设计等话题。 生命周期 通常,一个产品都具有两个环境: 测试环境:用于开...

精通吹水
2016/04/24
236
0
美团 Android 热更新方案 Robust 开源,包含自动化补丁工具

美团 Android 热更新方案 Robust 开源了。 Robust 是新一代热更新系统,对 Android 版本无差别兼容,无需发版就可以做到随时修改线上 bug,快速对重大线上问题作出反应。Robust 热更新系统借...

王练
2017/03/20
5.7K
15

没有更多内容

加载失败,请刷新页面

加载更多

Linux的基本命令

目录的操作命令(增删改查) 增: mkdir 目录名称; 查: ls 可以看到该目录下的所有的目录和文件 ls -a,可以看到该目录下的所有文件和目录,包括隐藏的 ls -l,可以看到该目录下的所有目录和...

凹凸凸
今天
2
0
在古老unix中增加新用户

Installing 4.3 BSD Quasijarus on SIMH 目标:要在4.3BSD中新增加用户dmr,指定目录/home/dmr,uid为10 gid=31(guest组,系统已建立) 4.3BSD还没有adduser或useradd 直接修改/etc/passwd...

wangxuwei
今天
2
0
Bootstrap(六)表单样式

基本样式 所有设置了 .form-control 类的 <input>、<textarea> 和 <select> 元素都将被默认设置宽度属性为 width: 100%;。 将 label 元素和前面提到的控件包裹在 .form-group 中可以获得最好...

ZeroBit
昨天
3
0
SSL 证书格式转换

SSL 证书格式转换 不同服务器情况下,需要不同的证书格式。 比如 pem 转 pfx。 pem在window 平台下可以导入,但是无法正常使用。 需要转换成pfx。 推荐在线转换工具,由中国数字证书网站提供...

DrChenXX
昨天
2
0
HAProxy

xx

Canaan_
昨天
2
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部