资讯动态

Linux服务器用yum安装配置JDK:从环境变量到多版本管理

发布时间:2026/10/14 19:48:51 来源:尧图企业网站定制
拿到一台新服务器先把 Java 环境搞定几乎是每个后端开发者都绕不过去的事。yum 安装配置 JDK 这件事我前前后后操作了不下几十次踩过的坑包括 javac 莫名找不到、JAVA_HOME 配错导致构建工具罢工、多版本切换后版本对不上号。这篇文章就把我实际用过的一套流程完整写出来也把那些“常规文档里不会写”的坑一并说清楚适合刚接手服务器、想在几分钟内把 JDK 装好并且之后少折腾的人。先说明一下我这里讲的是红帽系 Linux 发行版上的 yum 用法这类系统在企业服务器里非常常见。如果你手里是 Debian 系的机器把 yum 换成 apt 就行但整体思路是一样的。JDK 版本我以目前存量最大的 Java 8 为主线同时会提一下 Java 11、Java 17 的切换方法因为现在新老项目并存的场景太普遍了。1. 先用 yum 而不是手动解压图的是什么1.1 yum 装 JDK 的一站式优势很多初学者习惯去官网下载 tar.gz然后手动解压到 /usr/local再自己配 PATH。这个流程本身不难但后续的麻烦事不少升级要重新下载覆盖、卸载要手动清理、依赖关系全靠人工记。yum 装 JDK 的本质是把 JDK 纳入系统的包管理数据库装、卸、升级、查版本都有据可依和操作普通软件包没有任何区别。拿我自己遇到过的一个场景举例。某个项目的编译环境需要特定的依赖包手动解压 JDK 的时候这个包有没有被别的程序引用、会不会冲突完全靠猜。用 yum 之后yum 会在安装前自动检查依赖关系把缺的包一起装上冲突的包提前告诉你这比手动管理靠谱得多。还有一个隐性好处是安全性。yum 安装的 JDK 来自发行版官方仓库或可信的第三方仓库这些包经过打包方的测试并且源里保留了版本信息和修复记录。手动从网上下载的包来源五花八门很难保证校验值没被篡改。对于生产服务器来说能少引入一个“不可控变量”就少一个。1.2 开源 JDK 与商业版 JDK 怎么选yum 仓库里默认提供的是开源 JDK 的构建版本也就是大家常说的 OpenJDK 系列。很多人担心开源版本“不够正式”实际上主流的企业级 Linux 发行版默认集成的就是这套东西绝大多数 Java 应用跑在它上面没有任何问题。商业版 JDK 的区别主要在于提供方不同多了一些长期支持承诺和商业服务比如某些定制特性、补丁发布节奏更快。但这些能力在大部分业务场景里用不上。我个人的选择原则很简单中小团队、普通业务系统直接用仓库里的开源 JDK如果公司有明确合规要求采购了商业 JDK那就把它单独安装到独立目录尽量别和系统包混在一起避免两个 JDK 互相干扰。另外给大家一个提醒不要因为某篇文章说“某个 JDK 更快”就盲目换版本。JDK 的性能差异在绝大多数业务里根本不是瓶颈瓶颈通常在数据库、网络、GC 参数和代码质量上。稳定的版本管理比“理论上的更快”重要得多。1.3 版本选择别一上来就装最新版不少新手上来就想装最新版 JDK觉得版本越高越好。实际在企业环境里版本选择的第一原则是“看项目需求”而不是“追新”。目前存量业务里 Java 8 依然占很大比例很多老项目的依赖库、框架在 Java 8 上经过反复验证直接上 Java 11 或 17 可能出现意想不到的兼容问题比如某些反射代码在新版本被模块系统限制、旧版内存参数不识别等。建议这样选接手老项目先看项目里用的构建工具和框架要求如果写的是 Java 8 或更早老老实实装 Java 8。新项目且没有历史包袱优先考虑 Java 11 或 17。Java 17 是长期支持版本生命周期更长。确定版本之前用一行命令检查一下项目配置文件里的编译级别例如构建文件里的 source/target 值别凭记忆乱猜。yum 仓库里的包名也很有意思它把版本号直接写进包名里比如 java-1.8.0-openjdk、java-11-openjdk。所以你想装什么版本基本一眼就能看出来。2. 安装前必须摸清的四个关键信息2.1 确认系统环境与包管理器第一步不是急着敲 yum而是先知道你面对的系统到底是什么样的。执行cat /etc/os-release或cat /etc/redhat-release确认发行版版本和包管理器类型。老版本系统默认用 yum新版本系统可能已经用 dnf但 dnf 的用法和 yum 高度兼容命令基本不用改。还要确认网络和仓库状态。yum 安装需要访问配置好的软件仓库如果服务器是内网隔离环境可能配置了本地 mirror 仓库这时候要确认 source 列表是否可用。我处理过的环境里有相当一部分“yum install 报错”就是仓库源配置不对导致的和 JDK 本身没有关系。另外安装前养成一个好习惯先执行yum check-update或yum update -y吗这里我不建议贸然 update生产服务器上大批量升级依赖包风险很高。稳妥做法是先yum clean all yum makecache把仓库索引刷新一下再查看可用安装包。2.2 找到当前仓库里可用的 JDK 包版本和源确认之后先用搜索命令看看仓库里到底有哪些包不要凭感觉直接安装一个名字。yum search openjdk这个命令会列出所有名称或描述中包含 openjdk 的包输出会区分 JRE 和 JDK 相关包。注意看包描述里的版本号和特性比如 java-1.8.0-openjdk 和 java-1.8.0-openjdk-devel前者是运行环境后者是完整的开发环境。还有一个常见操作是yum list available | grep jdk可以查看所有可用包的状态。这样做的好处是避免装完才发现版本不对回头还得卸载重来。2.3 理解 JRE 与 JDK 的差异运行和编译是两回事很多坑都出在没搞清楚 JRE 和 JDK 的区别。JRE 是运行时环境只包含 java 命令和运行所需的类库能跑已经编译好的 class 文件或 jar 包JDK 是开发套件在 JRE 基础上增加了 javac 编译器、jar 打包工具、javadoc 文档工具等。你想在服务器上编译 Java 代码光装 JRE 是不够的。我见过有人装完 java-1.8.0-openjdk 之后执行java -version正常但执行javac -version直接提示 command not found然后一脸蒙圈地来问我。其实原因很简单默认不带 devel 的包只解决了“运行”的问题没有解决“编译”的问题。如果只部署编译好的应用比如直接把 jar 包丢到服务器上跑装 JRE 就够了如果服务器兼做构建机或者你想本地验证一下代码必须把 devel 包一起装上。这个选择直接决定你少踩一个坑。2.4 锁定 devel 包编译 javac 的必要条件继续上面的说开发环境里最常用的安装组合是两个包一起装java-1.8.0-openjdkjava-1.8.0-openjdk-develdevel 包不仅提供 javac还提供一些头文件和附加库。很多自动化部署脚本、构建工具在编译阶段会调用javac或检查$JAVA_HOME下的bin/javac如果这个文件不存在构建直接失败。所以我的建议是在服务器环境里除非你已经明确知道自己永远不需要编译代码否则就带上 devel 包一起装安装体积多几十兆省掉后面一堆麻烦。装完以后可以用rpm -ql java-1.8.0-openjdk-devel | head查看这个包装了哪些文件如果看到 javac、jar 这些工具说明包安装到位了。3. 完整实操从搜索到验证的九个步骤3.1 第一步刷新仓库索引直接安装之前先保证本地软件源索引是最新的。这一步看似多余但很有效。我遇到过明明仓库里已经有新版本却因为索引没刷新而搜不到包的情况。yum clean all yum makecache这两步做完以后makecache会把仓库元数据下载到本地之后的 yum search 和多装几个包。3.2 第二步搜索并确认包名接着执行搜索命令把最终要装的包名确认全。为了看清全貌可以把 search 和 list 结合使用yum search openjdk yum list available | grep -i jdk注意看输出中包的完整名特别是版本号中间的数字和架构后缀比如 x86_64。机器架构是 x86_64包名也是 x86_64别在中途看到不合的包名就装错了。3.3 第三步执行安装命令确认好包名以后执行安装。一般我会同时装 base 包和 devel 包yum install -y java-1.8.0-openjdk java-1.8.0-openjdk-devel-y参数的作用是跳过确认提示让安装过程自动继续。如果你不放心也可以去掉-y手动按 y 确认。生产环境脚本化操作时我更推荐带上-y避免脚本卡在交互确认上。这里有个小细节安装命令会把依赖的包一起拉进来比如 fontconfig、某些基础库。这些东西不用太关心yum 会自动处理。3.4 第四步观察安装日志与依赖处理安装过程中会输出大量信息包括正在安装的包、依赖解决情况、事务校验等。不要一直盯着进度条发呆留意两个关键信息事务中是否包含你想要的包和依赖包。是否出现Nothing to do这个提示表示包已经安装过或者包名写错了。有一次我眼瞎把包名写成了 java-1.8.0-openjdk-devel.x86_64 之外的一个不存在的包名结果 yum 直接报错。遇到No package ... available第一反应应该是去yum list available | grep查真实包名而不是反复重试同一个错误命令。3.5 第五步验证 java 和 javac 是否可用安装完成后第一个验证命令是java -version javac -version正常情况下两个命令都会输出版本号和运行时信息。如果 java 有输出而 javac 提示 command not found说明 devel 包没装上或没有正确关联回去检查上一步的包名。如果 java 都提示 command not found可能安装过程失败也可能是 PATH 环境变量里没有包含新命令所在目录。这个环节是最容易自我怀疑的明明显示安装成功为什么 java 还是找不到别急往下看。3.6 第六步定位 JDK 真实安装路径yum 安装的 JDK默认并不在 /usr/local 下而是放在 /usr/lib/jvm 目录里。这个目录可能是很多刚接触的人比较陌生的。ls -l /usr/lib/jvm/你会看到类似java-1.8.0-openjdk-1.8.0.x86_64这样的目录或者一个更短的符号链接。为什么要强调“真实路径”因为配置 JAVA_HOME 时必须写对路径很多人直接复制网上某篇文章里的路径结果目录名对不上环境变量全白配。不要凭记忆猜用一条命令找路径which java readlink -f $(which java)which java通常显示 /usr/bin/java而 /usr/bin/java 本身是一个符号链接指向 /etc/alternatives/java再指向 /usr/lib/jvm 下的实际文件。readlink -f可以把这条链全部展开得到最终的真实路径。根据这个路径向上推导出 JDK 的根目录JAVA_HOME 就配到那里。3.7 第七步配置 JAVA_HOME 与 PATH定位到路径之后就该配置环境变量了。最简单的办法是新建一个独立的配置文件放在 /etc/profile.d 下例如 java.sh。这样所有用户登录时都会自动加载比直接改 /etc/profile 更清晰也好备份、好回滚。sudo vi /etc/profile.d/java.sh内容如下export JAVA_HOME/usr/lib/jvm/java-1.8.0-openjdk export PATH$JAVA_HOME/bin:$PATH注意 JAVA_HOME 不要带 binPATH 里要带 bin。这个错误非常隐蔽JAVA_HOME 写错会导致某些构建工具虽然能找到 java但找不到 javac甚至提示“Cannot find Java”。保存退出后当前会话执行source /etc/profile.d/java.sh新开的终端窗口会自动加载无需手动 source。3.8 第八步验证环境变量是否生效配置完以后不要急着写代码先验证三个点echo $JAVA_HOME echo $PATH java -version javac -version如果 JAVA_HOME 为空大概率是配置文件没被加载或者当前 shell 还是老的登录会话。这时候先source一下如果 source 后还是没有检查文件内容是否有语法错误比如 export 拼写、路径引号问题。另外java -version的输出默认打印到 stderr属于正常现象不要以为系统报错了。3.9 第九步多版本 JDK 的切换管理服务器上同时存在 Java 8 和 Java 11是现实中最常见的情况之一。红帽系系统用 alternatives 机制管理同一命令的多个版本。先确认有哪些版本ls /usr/lib/jvm/ alternatives --config java alternatives --config javacalternatives 会弹出一个交互式列表输入数字选择默认版本。这里容易忽略一个事情alternatives 只切换命令本身不切换 JAVA_HOME 环境变量。如果你在 /etc/profile.d/java.sh 里写死了 Java 8 的路径通过 alternatives 切到 Java 11 后命令行执行java -version可能显示 Java 11但 JAVA_HOME 还是 Java 8构建工具买账。”我自己的处理方式是在 java.sh 里不硬编码某个版本路径而是配合 alternatives 的动态链接来完成。例如先获取当前实际生效的 JDK 路径export JAVA_HOME$(dirname $(dirname $(readlink -f $(which java)))) export PATH$JAVA_HOME/bin:$PATH这种方式会把 /etc/alternatives/java 的真实链接解析出来再去掉 bin 目录得到当前版本的实际根路径。每次切换版本后新登录的会话拿到的 JAVA_HOME 就是对应版本。缺点是不能做到同一个会话里动态切换但绝大多数场景下够用。4. 配置环境变量不同方式的取舍与常见坑4.1 系统级与用户级配置怎么选环境变量写在哪里是很多新手纠结的问题。常见位置有三个/etc/profile、/etc/profile.d、~/.bashrc。我的建议是优先用 /etc/profile.d 下的独立文件理由很简单独立文件只干一件事不污染系统主配置文件多人共用的服务器大家都能加载出了问题删一个文件就恢复比改坏 /etc/profile 后慢慢找问题要快得多。~/.bashrc 只对当前用户生效适合个人开发机不适合共享服务器。因为其他人登录时看不到这些变量而 JDK 是全局公共环境放用户级别容易造成“我这边能跑、别人那边不行”的诡异现象。如果你用 sudo 修改了 /etc/profile.d 下的文件普通用户重新登录后才会生效。已经在线的用户需要重新加载一次或者退出终端重新登录。4.2 JAVA_HOME 为什么必须配有人会问java 命令能跑不配 JAVA_HOME 不也行吗短时间看确实行但构建工具、应用服务器、自动化部署脚本往往不是通过 PATH 找 java而是直接读 JAVA_HOME 环境变量。比如某主流构建工具脚本里写$JAVA_HOME/bin/java如果 JAVA_HOME 没配它就直接报错。我自己调试过一个应用启动失败的问题日志里没有任何异常最后发现启动脚本里引用了 $JAVA_HOME而服务器上根本没有定义这个变量导致启动命令被解析成不完整的路径。这种问题很隐蔽因为它不是 Java 程序本身抛出来的而是 shell 先挂了。所以java 命令能用不等于环境完整。只要是跑 Java 应用的服务器JAVA_HOME 和 PATH 两个都得配上这不是可选项。4.3 配置后没生效的排查链路配置完环境变量后不生效是高频问题。我通常会按这个顺序排查当前终端是不是新开的老终端不会自动读取新加的配置先重新登录或手动 source。配置文件是否真的有执行权限/etc/profile.d 下的脚本会被当作 shell 脚本加载如果权限异常可能加载失败。文件里有没有多余的空格、引号比如export JAVA_HOME /path这种写法等号两边多了空格变量定义会失败。检查实际生效的变量值echo $JAVA_HOME如果为空说明配置没进到当前环境。还有一个我踩过的坑是用 nano 编辑文件时误加了非 UTF-8 的字符导致脚本解析异常。这类问题在文本编辑器不显示控制字符时特别难发现我现在的习惯是编辑完之后先bash -n 文件路径检查一下语法确认无措再加载。4.4 命令行工具与图形工具读不到 JDK 的常见原因命令行里java -version正常但某些图形化集成开发环境或桌面应用还是找不到 JDK这种情况在带图形界面的个人机器上很常见。原因是图形程序不是从 shell 登录会话启动的不一定会读取 /etc/profile.d 下配置的环境变量。如果是桌面环境可以把环境变量写进系统级的环境文件里常见的是 /etc/environment这个文件在图形登录时也会被读取。但要注意/etc/environment 不支持 shell 变量扩展必须写成固定路径不能写$(dirname ...)这类动态表达式。如果是某个应用自己的启动脚本那就在脚本开头显式声明export JAVA_HOME/usr/lib/jvm/java-1.8.0-openjdk这个做法虽然重复但最可靠。别指望所有应用都能自动感知系统环境变量很多时候“读不到”只是因为启动方式绕过了常规加载链。5. 常见问题与现场排障记录5.1 找不到 javac90% 是 devel 包没装这个问题出现频率极高我把它单独拿出来说。javac: command not found的最常见原因就是你只装了运行环境包没有装开发包。解决办法很简单yum install -y java-1.8.0-openjdk-devel装完之后再执行javac -version。如果你已经装了 devel 包但还是找不到检查一下 alternatives 里 javac 是否被关联alternatives --config javac把当前使用的 javac 切换到正确版本。还有一种可能是你配置的 PATH 没有包含实际的 bin 目录比如 JAVA_HOME 写到了 JRE 目录那个目录下没有 javac自然找不到。重新核对路径就好。5.2 依赖缺失与仓库不可用的处理yum 安装报错最常见的一类是仓库不可用或包找不到。报错信息通常包含“Cannot retrieve repository metadata”或“No package ... available”。处理思路分三步检查网络和 DNSping 仓库地址或者curl -I看仓库地址是否可达内网环境尤其需要关注。刷新仓库信息yum clean all yum makecache清掉可能损坏的缓存。查看仓库配置/etc/yum.repos.d/ 下的 .repo 文件确认启用的仓库enabled1。有时迁移系统或更换源地址后配置里写的老地址早就失效了。注意不要为了快速解决而随意禁用安全相关的仓库也别一次性把 base/update 仓库全关了那会留下更大的坑。如果某个 JDK 包在默认仓库里确实没有可以看一下是不是发行版源把相关包放到了单独的模块里需要先启用对应的模块流。这种情况在较新的发行版里更常见处理方式是通过模块相关命令切换到指定 JDK 流然后再安装。5.3 卸载旧 JDK 的正确姿势想换版本或清理残留很多人第一反应是去 /usr/lib/jvm 下rm -rf。这个做法非常危险因为系统包数据库里已经记录了这个目录你还可能破坏了 alternatives 的符号链接。正确的做法是用包管理器卸载yum list installed | grep -i jdk yum remove java-1.8.0-openjdk java-1.8.0-openjdk-develyum remove 会同时清理掉安装时生成的 alternatives 链接之后which java就会回到系统最初的“无 Java”状态干净利落。如果只是想让某个版本不被使用不一定非要卸载用 alternatives 切换默认版本就行。保留着另一个版本之后某个旧项目需要的时候还能切回来这也是多版本管理的常用思路。卸载之后/etc/profile.d/java.sh 里残留的配置建议同步清理或注释掉。我见过一台服务器上 JDK 版本早就换了但旧的环境变量还留在配置文件里导致新装软件反复读到错误路径。5.4 容器镜像内 yum 安装的特殊注意点现在很多应用直接跑在容器里容器镜像内用 yum 装 JDK 也是常见操作。容器内的玩法有几点和物理机不同一是基础镜像往往很精简yum 或 dnf 的命令路径可能各不相同先确认基础镜像里是否带包管理器二是环境变量最好写进镜像的 ENV 配置而不是靠 /etc/profile.d因为容器启动时不一定执行完整的登录流程。在构建容器镜像时可以用类似这样的方式ENV JAVA_HOME/usr/lib/jvm/java-1.8.0-openjdk ENV PATH$JAVA_HOME/bin:$PATH这样容器启动后应用进程直接就能读到正确的环境变量。这种方式比在容器内手动 source 更可控也更容易排查。还有一点容器里尽量保持镜像层的整洁。安装 JDK 时不要随便执行大范围升级避免把基础镜像里的依赖大换血这会让镜像体积暴增也可能引入与宿主机内核不兼容的库版本。5.5 影响范围分析配好 JDK 之后哪些东西会被盘活环境变量配好、多版本管理理顺之后不只是 java -version 能用整个 Java 生态的工具链都会跟着正常运转。比如构建工具会通过 JAVA_HOME 找到 javac 和 jar应用服务器在启动时能正确加载运行环境监控脚本能稳定拿到版本信息后续再装其他 Java 组件时系统依赖检查也会更加顺利。我见过不少线上事故根因都特别基础不是代码写错了不是框架选型有问题而是服务器上 JDK 环境本身就七零八落。有人为了给某个应用换内置的 JDK直接在宿主机上乱改符号链接最后把另一个正常应用的运行环境也搞坏了。这说明一件事JDK 的安装和配置表面上只是几条命令实际上是对整台机器 Java 生态的底层治理。最后再说一条个人习惯每装完一台机器的 JDK我会把以下信息记到运维备注里安装的包名和版本、JAVA_HOME 实际路径、配置文件名、默认版本切换方式。下次任何人问起“这台机器 Java 是怎么装的”不用猜翻一下记录就一目了然。这个习惯救过我很多次也建议你养成。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑