在 Debian 或 Ubuntu 服务器上预装 JDK,最稳妥且符合“云原生”规范的做法,绝不是去 Oracle 官网下载 .tar.gz 手动解压配置环境变量(除非你有特殊的商业授权需求),而是直接使用系统包管理器安装开源发行版。
目前业界主流、合规且零成本的选择是 OpenJDK。以下分两种场景说明:自动化部署(镜像构建)和手动服务器配置。
一、 核心原则:为什么选 OpenJDK?
- 合规性:Oracle JDK 8u161 之后版本需要订阅协议,企业商用需付费。OpenJDK 完全开源免费,无法律风险。
- 维护性:通过
apt安装的包,后续安全补丁由 Ubuntu/Debian 官方源自动推送,无需人工干预。 - 兼容性:Java 应用对 OpenJDK 和 Oracle JDK 的二进制兼容性极高,绝大多数业务代码无感知切换。
推荐版本:
- Java 8 (LTS):
openjdk-8-jdk- Java 11 (LTS):
openjdk-11-jdk- Java 17 (LTS):
openjdk-17-jdk- Java 21 (最新 LTS):
openjdk-21-jdk
二、 场景一:制作自定义云服务器镜像(预装)
如果你在使用阿里云、腾讯云、AWS 等云平台,希望创建自己的自定义镜像(Custom Image),让所有基于该镜像启动的 ECS/CVM 实例都自带 JDK,请按以下步骤操作:
步骤 1:在一台干净的 Debian/Ubuntu 虚拟机中执行安装
登录到用于制作镜像的基础系统,执行以下命令:
# 更新软件源
sudo apt update
# 安装 OpenJDK 17(根据实际需求替换版本号)
sudo apt install -y openjdk-17-jdk-headless
# 验证安装
java -version
javac -version
注意:生产环境建议安装
-jre-headless或-jdk-headless版本,避免安装不必要的 GUI 库,减小镜像体积并提升安全性。
步骤 2:清理痕迹(关键!)
在打包镜像前,必须清理系统日志、临时文件、SSH host keys 等敏感信息,否则会导致每台新机器 SSH 警告或泄露历史数据。
# 清理 apt 缓存
sudo apt clean
# 删除 SSH host keys(新机器启动时会重新生成)
sudo rm -f /etc/ssh/ssh_host_*
# 清空历史记录
history -c
cat /dev/null > ~/.bash_history
# 可选:使用 cloud-init 清理工具(如果使用了 cloud-init)
sudo cloud-init clean --logs
步骤 3:制作镜像
- 阿里云:控制台 -> 镜像与实例 -> 自定义镜像 -> 创建自定义镜像。
- 腾讯云:控制台 -> 镜像 -> 自定义镜像 -> 创建自定义镜像。
- 本地 KVM/QEMU:使用
virt-sysprep工具清理后打包。
这样生成的镜像,每次启动时都会自动包含已配置的 JDK 环境。
三、 场景二:手动在已有服务器上安装 JDK
如果你已经有一台运行中的服务器,想快速部署 JDK:
方法 A:使用默认仓库(推荐)
sudo apt update
sudo apt install -y openjdk-17-jdk
安装完成后,java 和 javac 命令通常会自动加入 PATH,无需手动配置环境变量。
方法 B:使用 SDKMAN!(适合多版本共存开发)
如果你需要在同一台机器上切换多个 JDK 版本(如测试 Java 8 和 Java 17),推荐使用 SDKMAN!:
# 安装 SDKMAN
curl -s "https://get.sdkman.io" | bash
source "$HOME/.sdkman/bin/sdkman-init.sh"
# 安装特定版本
sdk install java 17.0.9-tem
# 切换默认版本
sdk default java 17.0.9-tem
这种方式更灵活,适合开发者个人环境或 CI/CD 节点。
四、 常见坑与排查指南
1. “command not found: java” 怎么办?
大多数情况下,apt install openjdk-xx-jdk 会自动配置 /usr/bin/java 软链接。如果出现找不到命令,可能是:
- PATH 未刷新:新开一个终端窗口,或执行
source ~/.bashrc。 - 安装了 JRE 而非 JDK:确保安装的是
openjdk-xx-jdk,而不是openjdk-xx-jre。 - 替代机制问题:Debian/Ubuntu 使用
update-alternatives管理多个 Java 实现。检查当前激活的是否是你安装的版本:
update-alternatives --list java
update-alternatives --display java
如果需要手动指定,可以运行:
sudo update-alternatives --config java
2. 如何设置 JAVA_HOME?
虽然现代应用(如 Spring Boot 内嵌 Tomcat)不依赖 JAVA_HOME,但某些老项目或工具链(如 Maven、Gradle、Ant)仍需要它。
编辑用户级配置文件:
nano ~/.bashrc
添加以下内容(以 OpenJDK 17 为例):
export JAVA_HOME=$(dirname $(dirname $(readlink -f $(which java))))
export PATH=$JAVA_HOME/bin:$PATH
然后生效:
source ~/.bashrc
echo $JAVA_HOME
技巧:
$(dirname $(dirname $(readlink -f $(which java))))这个表达式能自动定位到 JDK 安装根目录,比硬编码路径更安全。
3. 内存不足导致安装失败?
小内存实例(如 512MB)在安装 JDK 时可能因编译头文件或缺乏 swap 而失败。解决方案:
- 增加 Swap 分区:
sudo fallocate -l 1G /swapfile sudo chmod 600 /swapfile sudo mkswap /swapfile sudo swapon /swapfile - 或者先安装最小化运行时
openjdk-17-jre-headless,再按需扩展。
五、 总结建议
| 场景 | 推荐方案 | 理由 |
|---|---|---|
| 云服务器镜像预装 | apt install openjdk-17-jdk-headless |
体积小、无 GUI、易维护 |
| 开发机多版本管理 | SDKMAN! | 一键切换,不影响系统全局 |
| 生产环境容器化 | Docker 基础镜像选用 eclipse-temurin 或 amazoncorretto |
官方维护,持续安全更新 |
最后提醒:不要从第三方 PPA 或非官方源下载 JDK,优先使用 Ubuntu/Debian 官方源提供的 openjdk-* 包,这是最稳定、最安全的做法。
云技术博客