同步操作将从 Gitee 极速下载/Jarboot 强制同步,此操作会覆盖自 Fork 仓库以来所做的任何修改,且无法恢复!!!
确定后同步将在后台操作,完成时将刷新页面,请耐心等待。
Jarboot
是一个Java进程启停、管理、诊断的平台,可以管理、守护、监控及诊断本地和远程的Java进程。
在测试环境、每日构建的集成环境,可以把一系列编译输出等jar文件放入约定的目录,由Jarboot
提供友好的浏览器ui界面和http
接口,统一管理它的启动、停止及状态的监控,以及执行命令对目标进程进行调试。
English version goes here.
📚 文档:https://www.yuque.com/jarboot
🍏 最佳实践 🔥 : Jarboot with Spring Cloud Alibaba Example ⭐️
🐳 可扩展: 同时支持JDK SPI
和Spring SPI
,支持插件式开发。
Jarboot
使用Java Agent
和ASM
技术往目标Java进程注入代码,无业务侵入性,注入的代码仅用于和
Jarboot
的服务实现命令交互,部分命令会修改类的字节码用于类增强,加入了与Arthas
类似的命令系统,如获取JVM信息、
监控线程状态、获取线程栈信息等。
SPI
自定义调试命令实现,支持开发插件详细架构设计查看
前端界面采用React
技术,脚手架使用UmiJs
,组件库使用UmiJs内置等antd
。
后端服务主要由SpringBoot
实现,提供http接口和静态资源代理。通过WebSocket
向前端界面实时推送进程信息,同时与启动的Java进程维持一个长连接,以监控其状态。
Docker
使用Docker
sudo docker run -itd --name jarboot -p 9899:9899 mazheng0908/jarboot
使用压缩包安装或者Docker
的时候忽略此步骤
编译Jarboot源代码
#首先编译前端
$ cd jarboot-ui
#首次时需要先安装依赖,执行yarn或npm install
$ yarn
#执行编译,yarn build或npm run build,开发模式可执行yarn start或npm run start
$ yarn build
#切换到代码根目录,编译Java代码
$ cd ../
$ mvn clean install
Jarboot
服务如果是使用的Docker
忽略此步骤。
#执行 startup.sh 启动, 在Windows系统上使用startup.cmd。
$ sh startup.sh
进入登录界面,初始的用户名:jarboot
,默认密码:jarboot
使用扩展可以自己实现命令,自己定义一个命令如何执行。并且,可以时应用启动完成快速的通知Jarboot服务,不需要等待没有控制台输出的时间。
spring-boot-starter-jarboot
依赖<dependency>
<groupId>io.github.majianzheng</groupId>
<artifactId>spring-boot-starter-jarboot</artifactId>
<version>${jarboot.version}</version>
</dependency>
CommandProcessor
SPI接口同样的, 你也可以在方法上使用 @Bean
注解来定义命令处理器。
如果没有使用@Name
注解的话,将会默认使用Bean的名称作为命令的名称。
@Name("spring.command.name")
@Summary("The command summary")
@Description("The command usage detail")
@Component
public class DemoServiceImpl implements DemoService, CommandProcessor {
@Override
public String process(CommandSession session, String[] args) {
return "Spring boot Demo user-defined command using Spring SPI";
}
//implement other method...
}
当引入了spring-boot-starter-jarboot
依赖后,将会增加2个Spring调试命令,spring.bean
和spring.env
#spring.bean 用法:
$ spring.bean [-b <name>] [-d]
#示例:
# 获取所有的bean name
$ spring.bean
# 获取bean的信息
$ spring.bean -b beanName
# 获取bean的详细信息
$ spring.bean -b beanName -d
#sping.env 用法:
$ spring.env <name>
#示例:
$ spring.env spring.application.name
演示普通的非SpringBoot的应用如何使用。
<dependency>
<groupId>io.github.majianzheng</groupId>
<artifactId>jarboot-api</artifactId>
<scope>provided</scope>
<version>${jarboot.version}</version>
</dependency>
/**
* 使用Name注解来定义一个命令的名字
*/
@Name("demo")
@Summary("The command summary")
@Description("The command usage detail")
public class DemoCommandProcessor implements CommandProcessor {
@Override
public String process(CommandSession session, String[] args) {
return "demo SPI command result.";
}
}
在目录resources
/META-INF
/services
中创建名为
com.mz.jarboot.api.cmd.spi.CommandProcessor
的文件,内容为类的全名。
public class DemoApplication {
public static void main(String[] args) {
// do something
try {
//Notify completion
JarbootFactory.createAgentService().setStarted();
} catch (Exception e) {
log(e.getMessage());
}
}
}
查看类的字节码,用法:
jarboot$ bytes com.mz.jarboot.demo.DemoServerApplication
ClassLoader: org.springframework.boot.loader.LaunchedURLClassLoader@31221be2
------
getUser
L0
LINENUMBER 27 L0
...
ILOAD 1
ILOAD 2
IADD
IRETURN
L8
开启或关闭标准输出流的实时显示(默认开启),将会在Web的前端ui界面上实时显示,输出流包括代码中的System.out.println
、System.err.println
以及日志打印信息如logger.info("hello")
。
注:该功能的实现机制经过精心设计,建议一直开启,对性能没有影响还可加速启动。
#开启标准输出流实时显示
jarboot$ stdout on
#关闭标准输出流实时显示
jarboot$ stdout off
#获取当前的状态,启动或关闭
jarboot$ stdout
当前系统的实时数据面板,点击按钮取消
反编译
jarboot$ jad [-c] java.lang.String
查看进程JVM属性信息
jarboot$ jvm
查找JVM中已经加载的类
$ sc -d org.springframework.web.context.support.XmlWebApplicationContext
class-info org.springframework.web.context.support.XmlWebApplicationContext
code-source /Users/xxx/work/test/WEB-INF/lib/spring-web-3.2.11.RELEASE.jar
name org.springframework.web.context.support.XmlWebApplicationContext
isInterface false
isAnnotation false
isEnum false
isAnonymousClass false
isArray false
isLocalClass false
isMemberClass false
isPrimitive false
isSynthetic false
simple-name XmlWebApplicationContext
modifier public
annotation
interfaces
super-class +-org.springframework.web.context.support.AbstractRefreshableWebApplicationContext
+-org.springframework.context.support.AbstractRefreshableConfigApplicationContext
+-org.springframework.context.support.AbstractRefreshableApplicationContext
+-org.springframework.context.support.AbstractApplicationContext
+-org.springframework.core.io.DefaultResourceLoader
+-java.lang.Object
class-loader +-org.apache.catalina.loader.ParallelWebappClassLoader
+-java.net.URLClassLoader@6108b2d7
+-sun.misc.Launcher$AppClassLoader@18b4aac2
+-sun.misc.Launcher$ExtClassLoader@1ddf84b8
classLoaderHash 25131501
方法执行监控
jarboot$ trace com.mz.jarboot.demo.DemoServerApplication add
Affect(class count: 2 , method count: 1) cost in 63 ms, listenerId: 2
`---ts=2021-06-15 23:34:20;thread_name=http-nio-9900-exec-3;id=13;is_daemon=true;priority=5;TCCL=org.springframework.boot.web.embedded.tomcat.TomcatEmbeddedWebappClassLoader@4690b489
`---[0.053485ms] com.mz.jarboot.demo.DemoServerApplication:add()
方法执行数据监测
观察方法 com.mz.jarboot.demo.DemoServerApplicatio#add
执行的入参,仅当方法抛出异常时才输出。
jarboot$ watch com.mz.jarboot.demo.DemoServerApplicatio add {params[0], throwExp} -e
Press Ctrl+C to abort.
Affect(class-cnt:1 , method-cnt:1) cost in 65 ms.
ts=2018-09-18 10:26:28;result=@ArrayList[
@RequestFacade[org.apache.catalina.connector.RequestFacade@79f922b2],
@NullPointerException[java.lang.NullPointerException],
]
查看当前线程信息,查看线程的堆栈
jarboot$ thread -n 3
"nioEventLoopGroup-2-1" Id=31 cpuUsage=0.37% deltaTime=0ms time=880ms RUNNABLE
at sun.management.ThreadImpl.dumpThreads0(Native Method)
at sun.management.ThreadImpl.getThreadInfo(ThreadImpl.java:448)
at com.mz.jarboot.core.cmd.impl.ThreadCommand.processTopBusyThreads(ThreadCommand.java:209)
at com.mz.jarboot.core.cmd.impl.ThreadCommand.run(ThreadCommand.java:120)
at com.mz.jarboot.core.basic.EnvironmentContext.runCommand(EnvironmentContext.java:162)
at com.mz.jarboot.core.cmd.CommandRequestSubscriber.execute(CommandDispatcher.java:35)
at com.mz.jarboot.core.server.JarbootBootstrap$1.onText(JarbootBootstrap.java:94)
at com.mz.jarboot.core.ws.WebSocketClientHandler.channelRead0(WebSocketClientHandler.java:83)
at io.netty.channel.SimpleChannelInboundHandler.channelRead(SimpleChannelInboundHandler.java:99)
"C2 CompilerThread1" [Internal] cpuUsage=3.14% deltaTime=6ms time=4599ms
"C2 CompilerThread0" [Internal] cpuUsage=2.28% deltaTime=4ms time=4692ms
查看classloader的继承树,urls,类加载信息
jarboot$ classloader
name numberOfInstances loadedCountTotal
org.springframework.boot.loader.LaunchedURLClassLoader 1 3929
BootstrapClassLoader 1 2623
com.mz.jarboot.agent.JarbootClassLoader 1 1780
sun.misc.Launcher$AppClassLoader 1 59
sun.reflect.DelegatingClassLoader 58 58
sun.misc.Launcher$ExtClassLoader 1 18
Affect(row-cnt:6) cost in 35 ms.
dump java heap, 类似jmap命令的heap dump功能。
jarboot$ heapdump
查看进程系统属性信息
#获取全部
jarboot$ sysprop
#获取指定的属性
jarboot$ sysprop user.home
1: 可以配置优先级级别,从整数值1开始,越大约先启动,停止的顺序则相反。
2: 开发中可以由gitlab runner
、Jenkins
等工具自动构建后通过脚本拷贝到Jarboot指定的目录下,Jarboot监控到文件的更新会自动重启服务,目录监控实现了防抖设计
(在一定时间内的多次更新只会触发一次重启)。
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。