新服务器要跑起 Java 服务,我会检查这 20 项
JDK装好了JAR也能启动。这台服务器就可以上生产了吗不一定。很多线上事故和业务代码没有关系服务用root运行 服务器重启后应用没有自动启动 时区错误导致定时任务提前执行 文件句柄太小导致无法建立新连接 日志没有轮转写满磁盘 Heap Dump目录没有写权限 DNS配置错误导致偶发请求超时 回滚时才发现旧版本已经被覆盖下面这20项是我接手一台新Linux服务器、准备部署Java服务时会做的基础检查。它和“Spring Boot应用上线检查”不完全相同。这篇重点看的是服务器本身是否具备长期、稳定、安全地运行Java服务的条件。说明命令以常见Linux发行版为例不同系统的包管理器、服务名称和安全策略可能不同。涉及防火墙、内核参数、用户权限和时间同步的修改应先经过测试与变更审批。一、账号与基础环境1. 不要长期使用root运行Java服务先确认进程准备使用哪个账号idorderapp如果没有专用账号可以按团队规范创建系统用户sudouseradd--system\--home/opt/order-service\--shell/usr/sbin/nologin\orderapp业务应用一旦存在命令执行、文件写入或依赖漏洞root权限会把影响范围放大到整台服务器。专用用户至少要做到不能交互登录 只拥有应用所需目录权限 不能随意读取其他服务配置 不能直接修改系统文件2. 固定部署、配置和日志目录建议把目录职责分开/opt/order-service/releases/ 版本目录 /opt/order-service/current 当前版本软链接 /etc/order-service/ 配置目录 /var/log/order-service/ 日志目录 /var/lib/order-service/ 持久化工作数据检查namei-l/opt/order-service/current namei-l/var/log/order-service不要把JAR、配置、上传文件、日志和Heap Dump全部堆在同一个临时目录。目录清晰才能回答哪个文件可以覆盖 哪个目录需要备份 哪个目录允许应用写入 磁盘满了应该清理哪里3. 检查目录所有者和写入权限sudo-uorderapp\test-r/opt/order-service/current/app.jar\echojar readablesudo-uorderapp\test-w/var/log/order-service\echolog writable还要验证临时目录 上传目录 导出目录 Heap Dump目录 日志目录最常见的问题不是“没有权限”而是部分目录由root在发布时创建应用运行几天后才在某个异常分支写入失败。4. 确认时区和时间同步timedatectl重点看Time zone System clock synchronized NTP service服务器、JVM、数据库和日志平台的时间需要能够对齐。时钟错误会影响定时任务 订单过期 Token有效期 证书校验 分布式锁 故障时间线 HikariCP定时行为不要只依赖虚拟化平台“顺便同步”应确认操作系统里的时间同步服务实际工作。5. 检查主机名和DNS解析hostnamectlcat/etc/resolv.conf getent hosts db.internal.example确认主机名符合资产规范 DNS服务器正确 内部域名能稳定解析 正向解析不会偶发超时有些“数据库偶发连接超时”最后并不是数据库问题而是内部DNS响应不稳定。如果使用/etc/hosts临时绑定地址要记录原因和维护责任避免目标IP变化后长期指向旧节点。二、CPU、内存与磁盘6. 确认CPU和系统负载基线lscpu nprocuptime记录逻辑CPU数量 NUMA情况 虚拟化类型 上线前Load Average不要拿到“8核服务器”就直接给所有业务线程池配成64。还要考虑同机其他进程 数据库连接数 容器CPU限制 任务是否CPU密集7. 确认物理内存、Swap和JVM预算free-hswapon--show内存预算不能只计算-Xmx。Java进程还会使用Metaspace 线程栈 直接内存 Code Cache GC结构 JIT Agent 本地库 文件页缓存例如一台8GB服务器不应该因为-Xmx8g看起来正好就把全部内存交给Java堆。Swap是否启用、如何使用要结合业务延迟要求和团队规范决定但必须提前知道当前状态而不是发生长时间卡顿后才发现机器一直在换页。8. 检查磁盘容量、文件系统和inodedf-hTdf-ilsblk-f确认应用目录在哪个分区 日志目录在哪个分区 Heap Dump可能写到哪里 剩余空间和inode是否充足 文件系统类型是否符合要求Heap Dump大小可能接近Java堆的实际占用。如果-Xmx4g但Dump目录只剩2GB真正OOM时可能连诊断文件都写不出来。还要给日志、发布包、临时文件和旧版本保留空间。9. 检查磁盘性能基线iostat-xz15新服务器“磁盘有500GB”不代表磁盘性能一定正常。上线前至少记录await 队列长度 读写吞吐 设备忙碌程度云盘规格、共享存储、突发额度和挂载方式都可能影响延迟。有了空载基线线上出现I/O告警时才知道偏离了多少。10. 检查文件句柄和进程限制当前Shell限制ulimit-nulimit-usystemd服务的实际限制systemctl show order-service\-pLimitNOFILE\-pLimitNPROC需要注意登录Shell里的ulimit不一定等于systemd服务实际拿到的限制。Java服务会使用文件句柄承载Socket连接 日志文件 JAR和类文件 临时文件 监控Agent限制过低时可能报Too many open files具体数值要结合并发连接和系统容量评估不要盲目全部改成无限。这20项更适合在发布前逐项核对。可以先收藏等真正上服务器时照着检查后面的网络、进程托管、日志和回滚才最容易在事故里暴露问题。三、网络与运行时11. 检查端口占用和监听地址ss-lntp发布前确认目标端口未被占用ss-lntp|grep:8080启动后确认监听端口正确 监听进程正确 监听地址符合网络拓扑127.0.0.1:8080和0.0.0.0:8080的含义不同。如果Nginx和应用不在同一网络空间监听地址错误会造成“本机能访问网关一直502”。12. 检查防火墙和安全组根据发行版查看sudofirewall-cmd --list-all或者sudonft list ruleset云服务器还要检查云平台安全组。原则是只开放必要端口 管理端口只允许受控来源 数据库和Redis不直接暴露公网 Actuator不全量暴露公网不要为了快速联调临时开放全部端口然后忘记收回。13. 验证关键依赖的网络连通性例如nc-vzdb.internal.example3306nc-vzredis.internal.example6379curl-fsShttps://config.internal.example/health至少覆盖数据库 Redis 配置中心 注册中心 消息队列 对象存储 外部HTTP服务能建立TCP连接不代表业务一定可用但可以先排除路由 端口 防火墙 DNS不要等应用启动失败后再逐个猜依赖。14. 固定并验证JDK版本java-versionreadlink-f$(command-vjava)确认JDK主版本 具体补丁版本 安装路径 systemd使用的Java路径交互式Shell里执行的java可能来自PATH。systemd里的ExecStart最好使用明确的绝对路径ExecStart/usr/lib/jvm/java-17/bin/java ...否则服务器升级、PATH变化或多版本共存时应用可能在重启后使用另一个JDK。15. 明确JVM参数和诊断文件路径至少检查Xms与Xmx GC选择 GC日志 Heap Dump 时区 编码 应用ProfileJDK 17示例-Xms1g-Xmx1g-XX:HeapDumpOnOutOfMemoryError-XX:HeapDumpPath/var/lib/order-service/dump -Xlog:gc*,safepoint:/var/log/order-service/gc.log:time,uptime,level,tags:filecount10,filesize100M重点不是复制参数而是验证目录可写 日志会轮转 磁盘装得下 参数与服务器资源匹配启动后用jcmdPIDVM.command_line确认实际生效参数不要只看发布脚本。四、服务托管与发布保障16. 使用服务管理器托管进程单机生产环境建议使用systemd等服务管理方式而不是只依赖后台Shell命令。检查systemctl status order-service --no-pager systemctl is-enabled order-service至少明确运行用户 工作目录 启动命令 异常重启策略 停止信号 停止超时 环境配置来源服务异常退出、服务器重启和人工停止时行为都应该是可预测的。17. 检查配置和密钥的存放方式重点排查数据库密码 Redis密码 对象存储密钥 JWT密钥 支付和短信Token 第三方API凭证不要把密钥写入Git仓库 JAR包 启动命令行 所有人可读的环境文件 日志如果使用配置文件ls-l/etc/order-service/确认所有者和权限。具备条件时使用专门的Secret或密钥管理服务并建立轮换与审计流程。18. 确认日志轮转和保留策略如果使用应用文件日志检查Logback或Log4j2滚动策略单文件最大大小 保留天数 总容量上限 压缩策略 异常日志是否单独保存如果使用journaldjournalctl --disk-usage同时确认journald自身的容量限制。日志系统至少要防住两件事单条异常无限刷屏 日志长期不清理写满磁盘还要对日志增长速度设置监控而不是只监控当前磁盘使用率。19. 准备版本回滚而不是覆盖旧JAR推荐使用版本目录/opt/order-service/releases/20260801-0850/ /opt/order-service/releases/20260725-0900/ /opt/order-service/current检查当前链接readlink-f/opt/order-service/current发布前要回答当前运行版本是什么 上一个稳定版本在哪里 配置是否兼容回滚 数据库变更能否回退 回滚需要多久只有旧JAR还在不代表具备真正的回滚能力。数据库结构、缓存格式和消息协议同样需要兼容。20. 做一次重启、验收和告警演练最后不要只执行一次systemctl start order-service至少完成主动停止并确认优雅退出 重新启动并确认服务恢复 模拟进程异常退出并观察拉起 条件允许时验证服务器重启后自动启动 执行健康检查和核心只读接口 确认监控能够发现服务停止 确认告警能到达值班人员验收命令示例systemctl is-active order-service ss-lntp|grep:8080curl-fsShttp://127.0.0.1:8080/actuator/health没有经过演练的自动重启、回滚和告警只是配置文件里的愿望。五、上线前的最终记录建议把结果留成一张表检查项结果证据专用用户通过orderapp目录权限通过JAR可读、日志可写时间同步通过NTP已同步DNS与依赖通过关键域名和端口可达CPU与内存通过已记录基线磁盘与inode通过低于告警线文件句柄通过systemd限制符合容量JDK与JVM参数通过已核对实际命令行日志轮转通过已验证容量和保留systemd托管通过enabled、active回滚通过已确认上一版本重启与告警通过演练完成不要在群里只留一句新服务器部署完成。以后出了问题没有人知道当时检查过什么。写在最后一台服务器能把JAR跑起来只能证明它现在可以启动。能够用于生产还要证明权限可控 资源有余量 网络可达 日志不会失控 进程有人托管 故障能够告警 发布能够回滚 重启以后可以恢复本文归入「生产环境保命清单」系列后续会继续整理Java服务部署、验收和故障演练清单。你的生产上线清单里哪一项最容易被忽略或者你认为还应该补上“第21项”欢迎在留言区补充。系列导航上一篇《Nginx报upstream timed out3个timeout到底该改哪个》系列起点《HikariCP可用连接从30掉到0一次连接泄漏的完整排查》关注我回复关键词保命获取「生产环境保命清单」全部文章。我会继续整理Java服务部署、验收和故障排查清单。也可以把脱敏后的服务器环境、部署方式和错误现象发来我会尽量帮你判断还缺哪些检查。请务必隐藏密码、Token、IP、域名和客户数据。