1. 简介
CRaSH(Commands Running in SHell)是一个可嵌入 JVM 的交互式命令行工具,允许开发者在运行时直接与 JVM 实例进行交互。它支持通过 Telnet、SSH 等方式接入,常用于监控、调试和执行自定义运维命令。
本文将带你完成以下内容:
- ✅ 独立部署 CRaSH
- ✅ 将其嵌入 Spring Web 应用
- ✅ 编写基于 Groovy 和 Java 的自定义命令
⚠️ 注意:虽然 Spring Boot 曾内置支持 CRaSH 远程 Shell,但该功能已被弃用。我们会在后续章节说明替代方案。
2. 独立安装 CRaSH
最简单的使用方式是将其作为独立应用运行。你可以从 CRaSH 官方网站 下载最新发行包。
解压后目录结构如下,重点关注三个核心目录:
bin/
:包含启动脚本(crash.sh
/crash.bat
)cmd/
:存放所有命令脚本(内置 + 自定义)conf/
:配置文件目录
进入 bin
目录,执行:
./crash.sh
即可启动本地 CLI:
此时你已经进入交互式 shell,可以尝试输入 help
查看内置命令。
3. 在 Spring Web 应用中集成 CRaSH
要将 CRaSH 嵌入传统 Spring Web 项目(非 Boot),需添加以下依赖:
<dependency>
<groupId>org.crashub</groupId>
<artifactId>crash.embed.spring</artifactId>
<version>1.3.2</version>
</dependency>
<dependency>
<groupId>org.crashub</groupId>
<artifactId>crash.cli</artifactId>
<version>1.3.2</version>
</dependency>
<dependency>
<groupId>org.crashub</groupId>
<artifactId>crash.connectors.telnet</artifactId>
<version>1.3.2</version>
</dependency>
💡 最新版可在 Maven Central 查询。
CRaSH 支持 Groovy 脚本编写命令,因此还需引入 Groovy:
<dependency>
<groupId>org.codehaus.groovy</groupId>
<artifactId>groovy</artifactId>
<version>3.0.0-rc-3</version>
</dependency>
配置 web.xml
在 web.xml
中注册 CRaSH 生命周期监听器:
<listener>
<listener-class>org.crsh.plugin.WebPluginLifeCycle</listener-class>
</listener>
创建命令与配置目录
在 WEB-INF
下新建 crash
目录,结构如下:
WEB-INF/
└── crash/
├── commands/
└── crash.properties
修改 Telnet 端口(可选)
默认监听 5000 端口,可通过 crash.properties
修改:
crash.telnet.port=6000
使用 Spring Bean 替代配置(高级用法)
若想更灵活控制路径或参数,可通过 Spring Bean 注入配置:
<bean class="org.crsh.spring.SpringWebBootstrap">
<property name="cmdMountPointConfig" value="war:/WEB-INF/crash/commands/" />
<property name="confMountPointConfig" value="war:/WEB-INF/crash/" />
<property name="config">
<props>
<prop key="crash.telnet.port">5000</prop>
</props>
</property>
</bean>
部署后,使用 Telnet 连接即可:
telnet localhost 5000
✅ 成功连接后即可执行内置命令如 jvm
, thread
, gc
等。
4. CRaSH 与 Spring Boot 的集成现状
Spring Boot 曾通过 spring-boot-starter-remote-shell
提供对 CRaSH 的原生支持:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-remote-shell</artifactId>
</dependency>
❌ 但该模块已在较新版本中被标记为废弃,不再推荐使用。
替代方案:Attach 模式
你可以使用 CRaSH 的 attach
模式直接连接到正在运行的 Spring Boot 应用进程:
./crash.sh <PID>
其中 <PID>
是目标 JVM 进程 ID,可通过 jps
命令获取:
jps -l
# 输出示例:
# 12345 org.example.MySpringBootApplication
然后执行:
./crash.sh 12345
⚠️ 踩坑提示:确保运行 crash.sh
的用户有权限访问目标 JVM 进程(通常需同一用户启动)。
5. 编写自定义命令
CRaSH 支持两种方式编写命令:Groovy 脚本(推荐快速开发)和 Java 类(适合复杂逻辑)。两者均可热加载,无需重启应用。
5.1 使用 Groovy 编写命令
在 WEB-INF/crash/commands/
下创建 message.groovy
:
class message {
@Usage("show my own message")
@Command
Object main(@Usage("custom message") @Option(names=["m","message"]) String message) {
if (message == null) {
message = "No message given...";
}
return message;
}
}
关键注解说明:
注解 | 作用 |
---|---|
@Command |
标记该方法为一个可调用命令 |
@Usage |
提供命令或参数的描述信息 |
@Option |
定义命令行参数,支持短名(-m )和长名(--message ) |
保存后,在 Telnet 终端中测试:
message -m "Hello CRaSH"
# 输出:Hello CRaSH
message
# 输出:No message given...
5.2 使用 Java 编写命令
创建 Java 类 message2.java
,需继承 BaseCommand
:
public class message2 extends BaseCommand {
@Usage("show my own message using java")
@Command
public Object main(@Usage("custom message")
@Option(names = { "m", "message" }) String message) {
if (message == null) {
message = "No message given...";
}
return message;
}
}
⚠️ 注意:
- 类必须
public
- 必须继承
org.crash.command.BaseCommand
- 编译后的
.class
文件需放在WEB-INF/classes
路径下(Maven 默认target/classes
)
重新部署后测试:
message2 -m "From Java"
# 输出:From Java
✅ 效果一致,Java 更适合封装复杂业务逻辑或复用已有工具类。
6. 总结
本文涵盖了 CRaSH 的核心使用场景:
- ✅ 独立部署与基本使用
- ✅ 集成到传统 Spring Web 项目
- ✅ 编写 Groovy/Java 自定义命令
- ⚠️ Spring Boot 用户应使用
attach
模式而非旧版 starter
尽管 CRaSH 社区活跃度有所下降,但在某些需要轻量级运行时诊断能力的场景下,仍是简单粗暴的有效方案。
所有示例代码已上传至 GitHub:
🔗 https://github.com/eugenp/tutorials/tree/master/spring-web-modules/spring-mvc-crash