
上个月帮朋友在一台CentOS 7.9的服务器上开MC服前前后后折腾了一周才算稳定下来。服务端本身其实不难跑起来真正费时间的是环境准备、进程托管、备份、权限这些外围工作——网上教程要么太老要么只丢命令不讲为什么照着做完了还是一头雾水。这篇文章干脆把我从零到一的完整过程重写一遍把每个关键选择的理由也讲清楚。目标读者就是手里恰好有一台CentOS 7.9机器、想开一个稳定MC服的人不管是三五好友纯净生存还是挂插件搞小社区这套流程都能直接用。1. 为什么选CentOS 7.9以及动手前必须想清楚的三件事1.1 先搞清楚你的服务器到底是什么定位很多人开MC服失败不是技术不行是压根没想清楚这台机器要承担什么角色。我这次帮朋友搭的服定位很明确8到10个熟人一起玩以纯净生存为主后续可能加几个轻量插件。这个定位决定了后面所有选型——不需要上大型模组包不需要十八个世界的多服架构一台4G内存的单机就绰绰有余。先泼一盆冷水如果你打算开那种几百人同时在线的社区服CentOS 7.9单机方案从一开始就不合适你需要的是分布式架构、数据库分离、多节点部署那完全是另一个话题。这篇文章只解决中小型服务器的问题。1.2 CentOS 7.9本身还能不能用说句实在话CentOS 7系列已经进入维护后期官方源已经停止更新默认的yum源需要切到vault镜像才能继续用。如果你手里是生产环境的机器我建议迁移到替代发行版但如果只是开MC服系统层面的安全风险相对可控而且你大概率不会把其他业务放在同一台机器上。我的建议是开服前先把yum源切到可用的镜像源然后执行一次yum update -y把能打的补丁都打上。之后这台机器就不要乱装其他东西了专门跑MC服务。这是性价比最高的做法。1.3 硬件配置的最低底线MC服的性能瓶颈顺序是内存 单核CPU性能 磁盘IO 网速。内存MC 1.20以上版本服务端建议至少分配3G到4G加上系统占用物理内存8G起步比较舒服。4G内存的机器也能跑但要严格控制玩家数量和视距。CPUMC服务端是典型的单线程重负载应用主频越高越好核心数反而不是关键。E5这种老服务器CPU主频低跑MC反而容易被同配置的桌面CPU吊打。磁盘能上SSD就上SSD世界地图加载和区块加载对随机读写要求很高。机械硬盘跑MC玩家跑图时服务器TPS会明显下滑。动手之前先执行free -h和nproc看一眼机器资源心里有个底再开始装东西。2. 系统初始化和Java安装这一步决定你能跑哪个MC版本2.1 CentOS 7.9默认yum源的Java版本陷阱CentOS 7.9默认yum源里只有OpenJDK 8执行yum install java-1.8.0-openjdk装的也是Java 8。而Minecraft服务端的Java版本要求和玩家端完全不一样这里是最容易踩坑的地方。Java版本和MC版本的对应关系很简单MC服务端版本需要的Java版本1.12及以下Java 81.13 - 1.16Java 8或更高1.17 - 1.20.4Java 171.20.5及以上Java 21如果你像我一样打算跑1.20左右的版本那必须手动装Java 17。CentOS 7的yum源没有现成的OpenJDK 17包只能用官方RPM或者解压版二进制。2.2 安装Java 17的完整过程我习惯用解压版因为方便切换版本。Java 8和Java 17都留着以后想开旧版本服随时能切回来。# 先装默认的Java 8部分老工具链还需要它 yum install -y java-1.8.0-openjdk-devel # 下载Java 17的Linux x64压缩包 cd /opt curl -L -o jdk17.tar.gz https://api.adoptium.net/v3/binary/latest/17/ga/linux/x64/jdk/hotspot/normal/eclipse # 解压并做软链接 tar xzf jdk17.tar.gz ln -s /opt/jdk-17* /opt/jdk17 # 注册到alternatives让系统默认使用Java 17 update-alternatives --install /usr/bin/java java /opt/jdk17/bin/java 1 update-alternatives --install /usr/bin/javac javac /opt/jdk17/bin/javac 1 update-alternatives --config java # 验证版本 java -version注意Adoptium的下载链接每次跳转的是最新17版构建号所以解压后目录名是带版本号的软链接ln -s /opt/jdk-17* /opt/jdk17用的是通配符能自动匹配到实际目录。如果后面报错说找不到/opt/jdk17多半是解压后目录名格式变了ls /opt看一眼实际目录名改一下软链接就行。2.3 目录规划和运行用户拒绝root直接跑这是我从一个老运维那学来的习惯任何长期运行的服务都不要直接挂在root用户下跑。MC服一旦被入侵root权限意味着整个机器沦陷。# 创建独立用户和主目录 useradd -r -m -s /bin/bash mcserver # 创建服务目录 mkdir -p /opt/mc/server chown -R mcserver:mcserver /opt/mc # 用mcserver用户开始操作 su - mcserver目录规划我建议固定为/opt/mc/server所有服务端文件、插件、存档都放这里。不要把存档放到root家目录或者/tmp一是权限混乱容易出问题二是备份脚本写起来麻烦。3. 服务端核心选型原版、Paper还是Forge3.1 不同服务端的本质区别MC服务端有很多选择但核心其实就针对一个问题你是要原版体验、插件扩展还是模组玩法服务端适用场景性能表现扩展方式官方vanilla.jar纯净生存、人数少一般无Spigot老牌插件端尚可Bukkit插件Paper插件端首选好Bukkit/Paper插件Fabric轻量模组好Fabric模组Forge大型模组包偏差Forge模组我的选择是Paper。原因很简单兼容绝大多数Bukkit插件性能优化做得比原版好很多同时保持了原版玩法的感觉。Paper官方对自己的定位就是提高性能、修复漏洞、保持兼容实测下来同样的机器和视距TPS确实比原版稳定。如果你要玩的是大型模组包比如各种整合包那必须用Forge或Fabric这时候插件那套就不适用了。本文后面的配置以Paper为例但大部分内容对原版和Spigot同样有效。3.2 下载Paper并校验完整性去Paper官网的下载页面选择对应MC版本的构建包。注意Paper每个版本有多个build号选最新的稳定build就行。# 以1.20.4为例实际下载链接以官网为准 cd /opt/mc/server curl -o paper.jar https://api.papermc.io/v2/projects/paper/versions/1.20.4/builds/496/downloads/paper-1.20.4-496.jar # 下载完先看文件大小再对比官网的SHA256校验值 sha256sum paper.jar校验这一步很多人跳过但Paper的下载页会同时给出当前构建的SHA256养成对比校验值的习惯能避免下载到损坏文件。之前我在某个镜像站下过一次过期的paper.jar启动直接报内部错误排查半天才发现是包的问题。4. 首次启动和server.properties逐项拆解4.1 eula.txt新手翻车的第一个坑第一次启动服务端会直接闪退原因是MC要求你同意最终用户协议服务端目录下会生成一个eula.txt文件。把里面的eulafalse改成eulatrue然后重新启动。# 首次启动 java -Xms1G -Xmx1G -jar paper.jar nogui # 修改eula sed -i s/eulafalse/eulatrue/ eula.txt这里顺便解释一下nogui参数服务端默认会在有图形界面的环境里弹窗纯命令行服务器必须加nogui不然会启动失败。4.2 server.properties关键配置项服务端启动后会生成server.properties这个文件几乎决定了服务器的所有基础行为。我用vim改完后是下面这样的核心配置server-port25565 server-ip online-modetrue max-players20 view-distance10 simulation-distance8 spawn-protection0 enable-command-blocktrue white-listtrue motd欢迎来到我们的MC服务器 difficultynormal gamemodesurvival pvptrue逐个说下为什么这么配server-ip保持空监听所有网卡。如果填了内网IP外网玩家就进不来了填了公网IP在某些NAT环境下反而有问题。默认空值最省心。online-modetrue开启正版验证。打算开私服、只想让熟人玩的话强烈建议配合下面white-listtrue白名单。正版验证防止别人拿盗版客户端随便进你的服。view-distance10是客户端能加载的地图距离simulation-distance8是服务器真正模拟游戏逻辑的范围。这两个值是性能的大头调到12以上对CPU和内存压力会明显增加。8到10是比较平衡的区间。spawn-protection0关闭出生点保护。很多服务器出生点圈了一块地别人动不了如果你不是特别在意出生点安全设成0免得玩家互相干扰。white-listtrue开白名单。这是私服防熊孩子最关键的一道闸门配合whitelist add 玩家名命令使用。4.3 JVM启动参数内存怎么分才不浪费服务端的启动命令看着简单但JVM参数配不配好直接决定服务器能稳多久。我的启动参数如下java -Xms4G -Xmx4G \ -XX:UseG1GC \ -XX:ParallelRefProcEnabled \ -XX:MaxGCPauseMillis200 \ -XX:UnlockExperimentalVMOptions \ -XX:DisableExplicitGC \ -XX:AlwaysPreTouch \ -XX:MaxTenuringThreshold1 \ -XX:SurvivorRatio32 \ -jar paper.jar nogui核心思路就两点-Xms和-Xmx一致。有些人习惯-Xms1G -Xmx4G想让JVM按需扩容但MC服在扩容瞬间会有明显的卡顿实测一致性设置对TPS更友好。用G1GC垃圾收集器。MC服务端会产生大量短生命周期对象G1GC在多核机器上比默认的Parallel GC表现更好停顿更短。内存分配别贪心。物理内存8G的机器给JVM分4G留4G给操作系统做文件缓存和IO缓冲反而更流畅。分到6G以上系统内存吃紧开始用swap交换那才是真正的死局。5. 用systemd托管MC进程开机自启、崩溃重启、自动备份5.1 创建systemd服务文件很多人开MC服都是手动敲java -jar窗口一关服务器就没了机器重启还得重新拉起来。用systemd托管所有问题一次解决。sudo vim /etc/systemd/system/mcserver.service内容如下[Unit] DescriptionMinecraft Paper Server Afternetwork.target [Service] Usermcserver Groupmcserver WorkingDirectory/opt/mc/server ExecStart/usr/bin/java -Xms4G -Xmx4G -XX:UseG1GC -jar paper.jar nogui Restarton-failure RestartSec10 TimeoutStopSec30 KillSignalSIGINT [Install] WantedBymulti-user.target几个关键点Usermcserver保证服务以独立用户身份运行不碰root。Restarton-failure让服务崩溃后自动拉起但注意要配合RestartSec10避免频繁崩溃导致无限重启循环。KillSignalSIGINT很重要。systemd默认停服务是发SIGTERM但MC服务端收到SIGTERM会直接强制终止可能导致存档损坏。改成SIGINT就等价于在控制台执行了stop命令会触发正常的存档保存流程。启动并设置开机自启sudo systemctl daemon-reload sudo systemctl enable --now mcserver systemctl status mcserver5.2 日常管理命令# 看服务状态和最近日志 systemctl status mcserver journalctl -u mcserver -f # 重启服务 sudo systemctl restart mcserver # 完全停止 sudo systemctl stop mcserverjournalctl -u mcserver -f相当于实时看服务端控制台输出玩家报错、插件报错都能在这里看到比整天守着游戏客户端强多了。5.3 定时备份服务器可以崩存档不能丢MC服的存档是最宝贵的东西一个熊孩子点燃一块林地没有备份你就只能拍大腿。我在cron里放了一个备份脚本每天凌晨3点自动执行。# /usr/local/bin/mc_backup.sh #!/bin/bash # 先把当前世界写入磁盘 sudo systemctl stop mcserver sleep 3 # 打包存档 BACKUP_DIR/backup/mc WORLD_DIR/opt/mc/server/world DATE$(date %Y%m%d_%H%M%S) mkdir -p $BACKUP_DIR tar czf $BACKUP_DIR/world_$DATE.tar.gz -C /opt/mc/server world # 重新启动服务 sudo systemctl start mcserver # 只保留最近7天的备份 find $BACKUP_DIR -name world_*.tar.gz -mtime 7 -delete# 加入crontab crontab -e # 每天3点执行 0 3 * * * /usr/local/bin/mc_backup.sh这个脚本的思路是停机备份最稳妥。对于小服务器来说每天一次凌晨3点的短暂停机完全没影响但换来的存档安全是实打实的。如果你不想停机可以用RCON工具远程执行save-all之后再做热备份但复杂度会高不少小服没必要。6. 插件安装与LuckPerms权限配置6.1 插件安装其实只有三件事Paper服加插件流程非常简单把插件jar包放到/opt/mc/server/plugins目录重启服务器。但实际使用时要注意三件事插件依赖关系。很多插件不是独立的比如经济系统通常需要VaultPlaceholderAPI被一大堆插件依赖。装之前去插件页面看清楚它依赖什么缺了依赖插件会加载失败。版本匹配。Paper版本分得很细1.19的插件未必能在1.20上跑。插件的构建页面一般会标明支持的MC版本别想当然。配置目录。首次加载插件后plugins目录下会生成对应的配置文件夹改配置后热加载不一定生效直接重启最省事。我这次装的不多EssentialsX管基础指令LuckPerms管权限WorldEdit和WorldGuard管建筑和领地保护CoreProtect做方块操作日志。对熟人小服来说这几件足够覆盖大部分需求了。6.2 LuckPerms快速配置思路LuckPerms是目前最主流的权限插件但新手往往被它的概念绕晕。其实核心就两个概念用户和组。用户是玩家组是一组权限的集合。我的配置思路分三步先建组/lp creategroup builder给组加权限/lp group builder permission set essentials.fly把玩家放进组/lp user 玩家名 parent set builder还有一个容易忽略的点default组是每个玩家默认加入的组给所有玩家发基础权限就加在这个组里。比如让所有玩家都能用回家指令就用/lp group default permission set essentials.home。别一上来就op 自己。OP权限绕过所有插件权限检查一旦不小心给别人OP服务器就彻底失控了。权限管理宁可先收紧再放开也别图省事全给OP。7. 服务器变卡了怎么办TPS、mspt与profiler排查思路7.1 先量化问题再谈优化服务器卡顿很多时候是感觉卡但说不清是网络卡还是服务端卡。你得先量化才能定位。Paper服务端在游戏内执行/tps查看服务器20秒内的TPS。TPS是每秒游戏刻数正常是20.0低于18就说明服务端在持续吃紧。/mspt查看每个游戏刻的平均运算毫秒数。Paper 1.18以后才有这个指令数值在50以下表示每一刻计算能在50毫秒内完成服务器很健康长期超过200就得处理了。如果TPS正常但玩家感觉动作延迟那问题多半在网络链路而不是服务端排查方向就完全不同。这一步能帮你少走无数弯路。7.2 六个最常见的卡顿原因根据我的排查经验小服务器的卡顿原因集中在下面几类视距太高。view-distance调得越高每个玩家周围的区块计算量越大。8到10已经是很宽裕的设置追求极致流畅可以降到6。实体堆积。小动物圈养区、刷怪塔里几百上千个实体会把CPU吃满。用/spark profiler抓一段性能数据能直接看到哪个区块、哪些实体占了最多计算时间。红石机器。高频红石装置比如大型刷物品机是卡顿大户。服务器主线程的大量时间都耗在红石逻辑更新上如果你不想限制红石就只能祈祷机器别太疯狂。区块生成。玩家快速跑图时服务端需要实时生成新区块非常吃CPU。遇到这种情况等区块生成完或使用预生成世界地图插件能大幅改善。内存分配不足。观察journalctl里有没有频繁的老年代GC日志如果有说明堆内存不够适当调高-Xmx但前提是物理内存还剩足够。磁盘IO瓶颈。机械硬盘在存档写入和区块加载时拖后腿查看iostat确认磁盘繁忙度如果一直很高换SSD是唯一解。Spark这个工具我强烈推荐安装。它是一个性能分析插件遇到卡顿只需要在游戏内执行/spark profiler等几分钟再/spark profiler --stop它会生成一份在线分析报告详细到每个区块、每个实体的耗时。比靠猜强一百倍。8. 安全加固与上线前检查清单8.1 防火墙只放行必要端口CentOS 7.9默认用firewalld。配置只需要放行MC端口其他的一律不开。sudo systemctl start firewalld sudo systemctl enable firewalld sudo firewall-cmd --permanent --add-port25565/tcp sudo firewall-cmd --reload firewall-cmd --list-all如果你用的是云服务商的机器别忘了同时去控制台的安全组规则里放行端口。这是个非常隐蔽的坑本地防火墙开了云厂商安全组没放行外网照样连不进来。反过来也一样两边都得放行。8.2 文件权限和SELinux确认服务端目录的所有权是mcserver用户sudo chown -R mcserver:mcserver /opt/mc另外CentOS 7默认SELinux是Enforcing模式如果服务启动时报权限错误但文件权限看起来没问题多半是SELinux上下文的问题。检查办法是getenforce看状态。对于MC服这种场景我的处理是只对服务目录调整上下文而不是无脑关闭SELinux。8.3 上线前最后过一遍清单每次开服前我会在终端里依次确认这些项全部通过才把地址发给朋友systemctl status mcserver服务正常运行。firewall-cmd --list-all25565端口已放行。java -version确认当前Java版本符合服务端要求。free -h内存还有富余没有swap占用异常。游戏内/tpsTPS稳定在20。白名单和权限组确认自己和朋友都在default组或不低于基础权限。备份脚本手动执行一次确认tar包能正常生成并落盘。最后分享一个个人习惯把服务端版本、Java版本、启动参数、常用命令、每次改过的配置项都记在一个markdown笔记里放在/opt/mc/README.md。服务器可能几个月不碰下次要维护时翻笔记比翻记忆靠谱得多。这台CentOS 7.9上的MC服现在稳定跑了四十多天中间只有一次因为云厂商维护触发重启系统d托管自动把服务拉起来了存档完好。这套方案不算花哨但足够稳至少对一个朋友小服来说它比频繁折腾更值得。