Java 运行环境与启动¶
运维首先要确认应用需要的 Java 主版本,而不是看到 .jar 就直接运行。构建时使用的字节码版本高于运行环境时,应用会报 UnsupportedClassVersionError;不同 CPU 架构、时区、字符集和系统库也可能造成“开发环境正常、生产异常”。
JDK、JRE 与容器镜像¶
| 类型 | 包含内容 | 使用场景 |
|---|---|---|
| JDK | JVM、运行库以及 jcmd、jstack、编译器等工具 |
构建、需要现场诊断的运行环境 |
| JRE/Runtime | 运行 Java 所需的精简组件 | 生产运行镜像,体积和攻击面较小 |
精简 JRE 镜像可能没有 jcmd、jstack 等诊断工具。上线前要确定取证方案:使用带工具的受控诊断镜像、同版本 JDK 宿主工具,或者提前启用 JFR/GC 日志,而不是故障发生后才发现无工具可用。
启动前检查¶
记录 Java 发行版与完整版本、CPU 架构、JAR 校验值和部署版本。滚动发布时,新旧实例必须能明确对应到同一个 Git 提交与制品。
推荐启动结构¶
java \
-XX:MaxRAMPercentage=70 \
-XX:+ExitOnOutOfMemoryError \
-Xlog:gc*:file=/data/logs/gc.log:time,uptime,level,tags:filecount=5,filesize=20M \
-Duser.timezone=Asia/Shanghai \
-Dfile.encoding=UTF-8 \
-jar /app/app.jar \
--spring.profiles.active=prod \
--spring.config.additional-location=optional:file:/app/config/
参数要根据所用 Java 版本验证。容器内不建议盲目把 -Xmx 设置成容器内存上限:Heap 之外还有 Metaspace、线程栈、直接内存、代码缓存和本地库,需要留出余量。
参数分层¶
| 层次 | 示例 | 说明 |
|---|---|---|
| JVM 参数 | -Xmx、-XX:、-Duser.timezone |
必须放在 -jar 前面 |
| Spring 参数 | --server.port=8080 |
放在 JAR 后面,覆盖优先级高 |
| 环境变量 | SPRING_PROFILES_ACTIVE=prod |
适合容器平台注入 |
| 外部文件 | /app/config/application-prod.yml |
适合结构化配置,Secret 单独管理 |
systemd 运行要点¶
[Service]
User=app
Group=app
WorkingDirectory=/data/app
EnvironmentFile=-/etc/sysconfig/myapp
ExecStart=/usr/bin/java -jar /data/app/app.jar --spring.config.additional-location=optional:file:/data/app/config/
Restart=on-failure
RestartSec=5
SuccessExitStatus=143
TimeoutStopSec=60
不要使用 nohup 代替进程管理。systemd 应明确运行用户、工作目录、环境文件、停止超时和重启策略;修改后执行 daemon-reload、restart,并检查状态和 journal 日志。
启动失败的第一轮证据¶
先保留完整的第一段异常及最底层 Caused by,再判断是 Java 版本、配置解析、端口占用、权限、磁盘、数据库连接还是证书问题。