业务出错,怀疑上游接口问题,但是线上又没有打印接口返回数据
业务出错,怀疑代码业务逻辑有问题,需要代码逻辑环节输出相应参数定位
线上有业务数据异常,需要直接数据库操作修复
上游接口偶尔异常,但是由于没有日志,没有证据
需要对上游接口做各种场景测试
想要执行线上某段业务代码逻辑
解决办法
对于只能在线上环境(生产环境)定位的问题:
新增相应的info日志,然后打包、上线,查看日志。
新增调试代码逻辑,然后打包、上线,再次调用得到需要的结果。
可以在预发环境(测试环境)重现或者定位的问题:
新增对应代码逻辑,然后打包、发布到测试环境,再次调用得到需要的结果。
无论怎么处理,最终都需要重新打包、发布,甚至是上线。整个过程不复杂,但是很繁琐。那么有没有一种方法可以不打包,不上线,不发布,不重启就能够在线上直接执行某段代码,或者打印相应的日志呢?
原理介绍—类加载查看
获取类所在位置:
使用类加载器的 getResource()
方法。 使用类的getProtectionDomain().getCodeSource(). getLocation()
方法。
找到类所在位置后进行反编译:
使用FernFlower
反编译。 使用jd-core
反编译。
原理介绍—代码执行器
原理介绍—代码执行器(Java)
先在 IDE 中编写 Java 源码,源码中可以引用任意线上 JVM 里已经加载的类。
通过 JavaCompiler 对源码进行编译,并将当前线程上下文类加载器设置为编译时的父类加载器
编译完成后会得到一个自定义类加载器,从其中得到 Class 类,并实例化。
通过反射调用实例的方法。
将运行结果返回给前端和苍穹系统
原理介绍—代码执行器(js)
先编写 js 脚本(Rhino, Nashorn,KScript),脚本中可以引用任意线上已部署的类。
将 java 对象注入到脚本中。
调用 js 引擎执行脚本。
将运行结果返回给前端和苍穹系统。
具体实现
使用的苍穹特性
应用迁移
源码地址
https://www.github.com/lzpeng723/servicetools
应用使用到开源 jar 包对应的 maven 仓库:
https://mvnrepository.com/artifact/cn.hutool/hutool-all/5.8.20
https://mvnrepository.com/artifact/org.jd/jd-core/1.1.3
https://mvnrepository.com/artifact/com.github.adedayo.intellij.sdk/java-decompiler-engine/142.1
导入应用
从 MC 或 开发平台导入 sys_lzp_servicetools.zip
将 jar 包部署到服务器对应位置:
sys_lzp_servicetools.zip\jar\common.zip
(第三方开源 jar 包) sys_lzp_servicetools.zip\jar\servicetools.zip
(苍穹插件)
若 sql 未执行成功可自行执行一下 sql :
sys_lzp_servicetools.zip\dm\sys-lzp_service_helper-dm.zip\datamodel\1.5.0\main\lzp_service_helper\preinsdata\servicetools.sql
(本应用初始化数据------扩展开发库下执行)
sys_lzp_servicetools.zip\dm\sys-lzp_service_helper-dm.zip\datamodel\1.5.0\main\lzp_service_helper\preinsdata\permission.sql
元数据及代码.zip(3.07MB)
推荐阅读