gravity是满帮基于java agent自研的一款字节码层面AOP框架,目的是基于满帮业务场景,为插件开发同学降低字节码增强难度,目前满帮内部基于gravity开发出了六十余款插件,大致覆盖的业务场景如下:
场景名称 | 简介 | 业务场景 |
---|---|---|
ironman | 满帮mesh方案 | 涵盖rpc,mq,redis,config等多种中间件组件,彻底隔离api与实现,让开发同学无痛无感升级,后续也将开源,敬请期待 |
venom | 满帮混沌场景 | 故障演练,模拟测试,涵盖多种中间件,可模拟多场景异常 |
mock | 满帮测试框架 | mock演练测试,涵盖多场景,多种组件的模拟 |
hubble | 满帮APM解决方案 | 业务系统性能实时监控,链路埋点 |
common | 常规增强 | 一些常规场景的增强,比如TTL集成 |
首先简单模拟一笔发货订单场景
/**
* 货主
*/
public class Shippers {
/**
* 发布订单
*/
public String postOrder() {
return "南京市 雨花台区 万博科技园 运满满总部 50立方 10吨";
}
}
/**
* 司机
*/
public class Driver {
/**
* 接单
*/
public boolean acceptOrder(String address) {
if (Objects.nonNull(address) && address.startsWith("南京市")) {
return true;
}
return false;
}
/**
* 装货
*/
public String loadCargo() {
return "load cargo success.";
}
/**
* 运货
*/
public String deliverCargo() {
return "deliver cargo success.";
}
}
/**
* 发货订单
*/
public class Order {
public static void main(String[] args) {
new Order().trade();
}
public void trade() {
final Shippers shippers = new Shippers();
final Driver driver = new Driver();
final String address = shippers.postOrder();
driver.acceptOrder(address);
driver.loadCargo();
driver.deliverCargo();
}
}
这时候,我们希望可以监控该笔订单的行为,决定通过无侵入方式打印出入参
首先引入pom依賴:
<dependency>
<groupId>io.manbang</groupId>
<artifactId>gravity-plugin-api</artifactId>
<version>1.0.0</version>
</dependency>
插件定义,描述目标的织入点:
/**
* @since 2022/05/19 10:55
*/
public class AopPluginDefine implements PluginDefine {
@Override
public ElementMatcher<TypeDescription> getTypeMatcher() {
return ElementMatchers.named("io.manbang.gravity.trade.Driver")
.or(ElementMatchers.named("io.manbang.gravity.trade.Shippers"));
}
@Override
public Plugin[] getPlugins() {
return new Plugin[]{Plugin.advice(ElementMatchers.isMethod(), "io.manbang.gravity.plugin.monitor.AopAdvice").withMethod()};
}
}
具体织入的逻辑:
/**
* @since 2022/05/19 11:05
*/
public class AopAdvice implements Advice {
private static final java.util.logging.Logger log = java.util.logging.Logger.getLogger(AopAdvice.class.getName());
@Override
public void enterMethod(ExecuteContext context) {
final Method method = context.getMethod();
final Object[] argument = context.getArguments();
final StringBuilder builder = new StringBuilder();
builder.append("method enter:").append(method.getName());
for (int i = 0; i < argument.length; i++) {
builder.append(" arg number:").append(i).append(" arg :").append(argument[i]);
}
log.info(builder.toString());
}
@Override
public void exitMethod(ExecuteContext context) {
final Method method = context.getMethod();
final Object result = context.getResult();
final StringBuilder builder = new StringBuilder();
builder.append("method exit:").append(method.getName());
builder.append("result:").append(result);
log.info(builder.toString());
}
}
新建SPI
文件:/META-INF/services/io.manbang.gravity.plugin.PluginDefine
,内容为新创建的插件定义AopPluginDefine
打包该插件,并将打包好的插件放置于{user.home}/.gravity/cargo-publish-app/agent
目录下(user.home
路径可以通过执行java -XshowSettings:properties -version
得到,cargo-publish-app
为应用名,可以自行定义)
执行Order
的main
方法在启动时,新增VM
命令:-javaagent:XXXX/XXXX/gravity-agent.jar=appName=cargo-publish-app
,gravity-agent.jar
下载路径:agent
可以观察到控制台输出预期想要的业务出入参:
五月 19, 2022 4:49:05 下午 io.manbang.gravity.agent.GravityAgent instrument
信息: 加载插件:AopPluginDefine
五月 19, 2022 4:49:05 下午 io.manbang.gravity.agent.PluginTransformer transform
信息: io.manbang.gravity.trade.Shippers
五月 19, 2022 4:49:05 下午 io.manbang.gravity.agent.PluginTransformer getClassLoader
信息: The current classLoader is sun.misc.Launcher$AppClassLoader@18b4aac2 , pluginDefine: AopPluginDefine , transform: io.manbang.gravity.trade.Shippers
五月 19, 2022 4:49:06 下午 io.manbang.gravity.agent.GravityServiceBoot startServices
信息: 开始启动重力服务……
五月 19, 2022 4:49:06 下午 io.manbang.gravity.agent.PluginTransformer transform
信息: io.manbang.gravity.trade.Driver
五月 19, 2022 4:49:06 下午 io.manbang.gravity.agent.PluginTransformer getClassLoader
信息: The current classLoader is sun.misc.Launcher$AppClassLoader@18b4aac2 , pluginDefine: AopPluginDefine , transform: io.manbang.gravity.trade.Driver
五月 19, 2022 4:49:06 下午 io.manbang.gravity.plugin.monitor.AopAdvice enterMethod
信息: method enter:postOrder
五月 19, 2022 4:49:06 下午 io.manbang.gravity.plugin.monitor.AopAdvice exitMethod
信息: method exit:postOrderresult:南京市 雨花台区 万博科技园 运满满总部 50立方 10吨
五月 19, 2022 4:49:06 下午 io.manbang.gravity.plugin.monitor.AopAdvice enterMethod
信息: method enter:acceptOrder arg number:0 arg :南京市 雨花台区 万博科技园 运满满总部 50立方 10吨
五月 19, 2022 4:49:06 下午 io.manbang.gravity.plugin.monitor.AopAdvice exitMethod
信息: method exit:acceptOrderresult:true
五月 19, 2022 4:49:06 下午 io.manbang.gravity.plugin.monitor.AopAdvice enterMethod
信息: method enter:loadCargo
五月 19, 2022 4:49:06 下午 io.manbang.gravity.plugin.monitor.AopAdvice exitMethod
信息: method exit:loadCargoresult:load cargo success.
五月 19, 2022 4:49:06 下午 io.manbang.gravity.plugin.monitor.AopAdvice enterMethod
信息: method enter:deliverCargo
五月 19, 2022 4:49:06 下午 io.manbang.gravity.plugin.monitor.AopAdvice exitMethod
信息: method exit:deliverCargoresult:deliver cargo success.
具体示例已经放在gravity-demo
和gravity-plugin
中