Java服务在Linux上线需严控四点:核对JDK与系统glibc/内核兼容性;统一用/etc/profile.d/java.sh配置JAVA_HOME;JVM堆内存按物理资源合理设置且编码时区显式指定;确保JDK权限、证书及SELinux策略合规。

Java版本与Linux发行版的兼容性必须核对清楚
很多线上问题源于JDK版本和系统glibc、内核版本不匹配。比如OpenJDK 17+在CentOS 6上根本无法启动,报错 GLIBC_2.14 not found;而某些国产Linux发行版(如统信UOS、麒麟)预装的JDK可能被深度定制过,java -version 显示正常,但运行Spring Boot时抛出 UnsupportedClassVersionError——实际是JVM底层ABI不兼容。
- 生产环境优先选LTS版本:JDK 11(
openjdk-11-jdk)或JDK 17(temurin-17-jdk),避免用JDK 21+做主力 - Debian/Ubuntu系建议用
apt install openjdk-17-jdk,而非手动解压tar.gz;RHEL/CentOS 8+用dnf install java-17-temurin-devel - 手动安装JDK时,务必检查
/lib64/libc.so.6版本是否 ≥ JDK要求的最低glibc(可用ldd --version查)
JAVA_HOME和PATH配置必须由profile统一管理
很多人在~/.bashrc里设JAVA_HOME,结果systemd服务、crontab或Jenkins agent启动的Java进程全找不到JDK——因为这些场景不读用户级shell配置。
- 把JDK路径写进
/etc/profile.d/java.sh(内容只需两行):export JAVA_HOME=/usr/lib/jvm/temurin-17-jdk-amd64 export PATH=$JAVA_HOME/bin:$PATH
- 确认
which java输出路径与$JAVA_HOME/bin/java一致,且readlink -f $(which java)指向真实JDK bin目录 - systemd服务中不要依赖全局环境变量,显式指定
Environment="JAVA_HOME=/path/to/jdk"
JVM参数在服务器上不能照搬开发机配置
开发机8GB内存配-Xmx4g没问题,但2核4GB的云服务器上这么设,会触发频繁GC甚至OOM——尤其当应用本身还跑着Nginx、MySQL等其他进程时。
- 初始堆(
-Xms)和最大堆(-Xmx)必须设为相同值,避免运行时扩容卡顿 - 服务器物理内存≤4GB时,
-Xmx别超过1.5G;同时加-XX:+UseSerialGC(小内存更稳),而非默认的G1 - 务必加
-Dfile.encoding=UTF-8 -Duser.timezone=Asia/Shanghai,否则日志中文乱码、定时任务时间偏移
权限与安全策略常被忽略导致启动失败
Java进程以非root用户运行是基本要求,但很多人没注意JDK自身文件权限或java.security策略限制。典型现象:应用能启动,但连不上数据库(java.net.SocketPermission denied),或读不到/etc/ssl/certs下的CA证书。
立即学习“Java免费学习笔记(深入)”;
- 确保JDK安装目录归属正确:
chown -R appuser:appgroup /usr/lib/jvm/temurin-17-jdk-amd64,且appuser对bin/有执行权、对jre/lib/security/java.security有读权 - 若用自签名证书,别只改应用代码,还要把证书导入JDK信任库:
$JAVA_HOME/bin/keytool -import -trustcacerts -keystore $JAVA_HOME/jre/lib/security/cacerts -storepass changeit -alias myca -file myca.crt - SELinux启用状态下,Java进程可能被阻止访问网络或文件,临时验证可执行
setenforce 0;长期方案是写对应policy模块










