"paperclip,这词英文是回形针,但在Minecraft开服圈,它几乎是每个私服服主绕不开的东西——Paper服务器核心的启动器。很多新手问我的第一句话就是:我从官网下了一个paperclip.jar,双击没反应,或者闪一下就没了,怎么回事?这篇文章我把从下载、启动、配置到排查的整个过程捋一遍,配合我自己从1.16到1.21版本多次开服的实际经历,给打算自己搭Paper服务器的人一份可以直接照着操作的清单。"
1. Paperclip到底是什么:不只是回形针
1.1 名字的来历和它在服务器里的角色
在英文里paperclip是回形针,一个夹文件的办公用品。放到Minecraft这个场景里,它是Paper服务器核心的一种分发和启动格式,由PaperMC团队负责维护。
你可能听说过"服务端核心"这个概念。原版Minecraft的服务端叫做Vanilla Server,官方提供的那个server.jar只能跑最基础的游戏逻辑,不支持插件,性能也一般。社区在此基础上做出了很多分支,Paper就是目前最流行的性能优化分支之一。而Paper团队提供给普通用户下载的那个jar,往往命名成paper-版本号.jar或者paperclip-版本号.jar,实际跑起来的效果是一样的。比如你从papermc.io下载Paper 1.21.1,会拿到一个"paper-1.21.1-xxx.jar",这个jar内部就是通过Paperclip的机制来引导和启动服务器的。
Paperclip最核心的贡献,是把"下载依赖、校验文件、准备运行环境、启动服务端"这四个环节打包成了用户无感知的一步。你只需要一个jar,扔进目录里,执行java -jar命令,它就会自动处理后面的事情。首次运行时它会生成一个cache目录,把需要用到的原始服务端文件缓存起来,之后再启动就会快很多。
1.2 和原版、Spigot、Paper的区别
很多人分不清Vanilla、Bukkit、Spigot和Paper这几者之间的关系。简单说,Vanilla是官方原版,纯基础玩法,没有API;Bukkit是历史上第一个被广泛使用的插件API框架,但官方已经停更很久;Spigot是Bukkit的优化分支,在1.14之前几乎是开服标配;Paper又是Spigot的分支,在保留插件兼容性的同时大幅优化了区块加载、实体管理、网络压缩等底层逻辑,还修复了大量原版和Spigot里存在的漏洞。
我用一张表来对比,看差异更直观:
| 服务端 | 插件兼容性 | 性能表现 | 社区活跃度 | 配置难度 |
|---|---|---|---|---|
| Vanilla | 不支持 | 最弱 | 官方维护,更新快 | 低 |
| Spigot | 支持Bukkit/Spigot插件 | 中等 | 更新慢,长期半停更 | 中 |
| Paper | 兼容Bukkit/Spigot/Paper插件 | 最好,实体和区块优化明显 | 活跃,版本更新快 | 中等偏高 |
| 其他分支(如Mohist) | 兼容Fabric/Forge等 | 看具体场景 | 维护靠社区 | 高 |
选Paper不只是因为性能,还因为它提供了更细的配置粒度。比如你可以单独设置怪物AI是否会主动远离玩家、箭矢落地后多少秒消失、实体最大存活数量等。这些东西在原版里想改只能靠数据包或者插件硬顶,在Paper里改配置文件即可。
1.3 为什么要选Paperclip开服
我开服的早期也用过纯官方的server.jar,后来切到Spigot,最后固定在Paper上。说实话,Paperclip给我最直接的体感是:启动速度更快、卡顿更少、崩溃之后恢复更稳。
有一个特别典型的场景:服务器开久了,玩家多了,原版服务端在主世界跑实体时经常会出现"卡顿半秒、然后一堆人掉线"的情况。Paper里有专门的实体管理策略,比如spawn-limits、max-entity-collisions这些选项,配合JVM参数,能把TPS稳定在20附近。TPS是Minecraft服务器性能的核心指标,满值20,低于15就会明显感觉到走路像在水里一样,打怪反馈延迟。
另外,Paperclip解决了"版本错位"的问题。以前用Spigot,你得先下载BuildTools自己编译,那过程对新手非常不友好。Paper官方直接提供编译好的jar,下载下来就可以跑,省掉了大量时间。当然,它也不是完全没有门槛,Java版本、内存参数、端口占用这些坑一个不少。接下来我把从零到一的过程完整写出来。
2. 环境准备和首次启动:从零跑起一个Paper服务器
2.1 硬件、操作系统和Java版本怎么选
先说你最关心的配置问题。Minecraft服务器吃的是单核性能和内存,CPU主频比核心数重要得多。你拿一台16核32G的服务器,分配4G内存给Minecraft,效果可能不如一台4核8G但CPU主频更高的小主机。物理机、云服务器、家用电脑都可以跑,关键在于内存余量:建议至少2G内存留给系统,剩下的按玩家数来分。
玩家比较少(10人以内),2到4G就够;日常在线20到50人,4到8G比较稳妥;超过100人,8G以上,但我不建议单个服务端堆到12G以上,因为Java垃圾回收在大堆下的停顿会很棘手,更好的方案是用Velocity或BungeeCord做群组服。
操作系统方面,我自己用Linux居多,尤其是Ubuntu Server和Debian,因为远程维护方便,占用资源低,也不容易中招图形界面带来的内存开销。Windows也不是不行,只是需要更注意端口检测和防火墙放行。操作流程差异不大,命令稍有区别而已。
Java版本是Paperclip最容易被忽略的坑。不同Minecraft版本要求的Java版本完全不同,装错了直接报错。我整理过一张对照表,开服之前先对一下:
| Minecraft版本 | 最低Java版本 | 推荐Java版本 |
|---|---|---|
| 1.8 - 1.11 | Java 8 | Java 8 |
| 1.12 - 1.16 | Java 8 | Java 8或Java 11 |
| 1.17 | Java 16 | Java 17 |
| 1.18 - 1.20.4 | Java 17 | Java 17 |
| 1.20.5及以上 | Java 21 | Java 21 |
注意,装多个Java版本时,必须确认命令行里实际用的是哪个。Linux下可以执行java -version检查;Windows下如果装了多个JDK,记得在环境变量的Path里把目标版本放到最前面。
2.2 下载、建目录、写启动脚本
我建议在一个独立的目录里开服,不要图省事直接把jar丢在桌面。比如在服务器上新建/opt/mc,或者本地D盘下新建mcserver目录,所有服务端文件、插件、世界存档都放这里,方便备份和迁移。
下载文件的时候,去PaperMC官网(papermc.io)的Downloads页面,选好你想要的Minecraft版本,然后点版本号后面的下载按钮。官网默认给的是paper-版本号.jar,这个就是Paperclip格式的启动jar。下载之后,重命名成paper.jar也行,不重命名也可以,脚本里对应上就行。
Linux下的启动脚本start.sh,我一般写成这样:
#!/bin/bash java -Xms4G -Xmx4G -XX:+UseG1GC -XX:+ParallelRefProcEnabled -XX:MaxGCPauseMillis=200 -XX:+UnlockExperimentalVMOptions -XX:+DisableExplicitGC -XX:+AlwaysPreTouch -jar paper.jar --noguiWindows下对应创建一个start.bat:
@echo off java -Xms4G -Xmx4G -XX:+UseG1GC -XX:+ParallelRefProcEnabled -XX:MaxGCPauseMillis=200 -XX:+UnlockExperimentalVMOptions -XX:+DisableExplicitGC -XX:+AlwaysPreTouch -jar paper.jar --nogui pause注意Linux下要给脚本执行权限:chmod +x start.sh,然后通过./start.sh启动。最关键的参数是--nogui,它告诉服务端不要尝试加载图形界面,在纯文本环境里也能正常跑。如果你本地跑想用图形面板,去掉这个参数也可以,但远程服务器上一定要带上。
2.3 首次启动会遇到的问题和处理方式
第一次执行启动脚本,大概率会遇到两个提示:一是生成eula.txt,告诉你必须修改eula=true才能继续;二是日志刷出一堆下载信息。这是Paperclip在准备运行环境,耐心等一会儿,如果网络不好可能时间会比较长。
遇到eula问题,直接用文本编辑器打开服务端目录下的eula.txt,把eula=false改成eula=true,保存后再次启动即可。这只是表明你同意Mojang的最终用户许可协议,所有第三方服务端都要走这一步。
下载依赖超时要分几种情况。常见的是连接Mojang或PaperMC官方源很慢,尤其是国内网络环境,有时候请求会卡很久。解决办法是用代理或者更换网络运营商提供的镜像源,不过不要乱改Paperclip内部的下载地址。Paperclip设计上对校验很严格,篡改缓存会导致启动失败,所以老老实实等它下完就好。
启动成功的标志是日志里出现"Done (x.xxxs)! For help, type "help""这一行。看到这个,说明服务器已经监听在25565端口了。此时直接在Minecraft客户端里用localhost加入游戏就能本机测试。
3. 配置调优:让服务器从"能跑"到"好跑"
3.1 JVM内存与垃圾回收参数(Aikar's Flags)
很多人的误区是-Xmx(最大堆内存)给得越多越好。实际上对于Minecraft这种对象分配极为频繁、低延迟要求高的Java应用,堆内存过大会导致G1GC在发生全局标记和混合回收时产生明显停顿,表现出来就是玩家集体卡住。所以Aikar(Paper社区的核心开发者之一)给出的建议是:最大堆内存不要超过物理内存的50%,不要超过8G,除非你有非常特殊的理由。
我自己的习惯:8G总内存的服务器,给MC分4G;16G总内存,给6到8G;再高就上群组。启动参数直接用社区流传很广的Aikar's Flags,它针对G1收集器做了细粒度的调整,比如控制新老生代比例、减少显式GC调用、调整RSet更新时间占比等。下面是我常用的完整版本:
java -Xms6G -Xmx6G -XX:+UseG1GC -XX:+ParallelRefProcEnabled -XX:MaxGCPauseMillis=200 -XX:+UnlockExperimentalVMOptions -XX:+DisableExplicitGC -XX:+AlwaysPreTouch -XX:G1NewSizePercent=30 -XX:G1MaxNewSizePercent=40 -XX:G1HeapRegionSize=8M -XX:G1ReservePercent=20 -XX:G1HeapWastePercent=5 -XX:G1MixedGCCountTarget=4 -XX:InitiatingHeapOccupancyPercent=15 -XX:G1MixedGCLiveThresholdPercent=90 -XX:G1RSetUpdatingPauseTimePercent=5 -XX:SurvivorRatio=32 -XX:+PerfDisableSharedMem -XX:MaxTenuringThreshold=4 -jar paper.jar --nogui-Xms和-Xmx最好设置成一样的值,避免运行时动态扩容带来的额外开销。--AlwaysPreTouch会在启动阶段就请求并锁定所有虚拟内存页,虽然启动时间会变长,但运行期卡顿明显减少。改完参数后重启服务器,观察三五分钟,TPS如果稳定在20就是健康状态。
3.2 server.properties里真正重要的几个开关
server.properties是Minecraft服务端的标准配置文件,位于服务端根目录。打开这个文件,几乎每个键都对应一个功能,但真正影响体验的也就几个。
第一是view-distance。它决定服务器向客户端发送多少区块。注意它和客户端渲染距离是两回事,默认10,如果服务器性能有限,建议改成6到8。再低会影响玩家体验,远处看风景全是虚空,没必要。
第二是simulation-distance。从1.18版本开始有这个键,控制红石、怪物AI等逻辑模拟的范围。它比view-distance更吃性能,推荐设置成5或者6,保证主城附近红石机器不卡,远处的区块即使加载了也不会空跑计算。
第三是network-compression-threshold。网络压缩阈值,默认256,意思是数据包超过256字节才启用压缩。如果玩家延迟普遍较高,可以把这个值调大,比如512甚至1024,牺牲一点带宽换取更低的CPU占用;如果本地局域网联机,设成-1禁用压缩反而更快。
第四是max-player和online-mode。前者是最大玩家数,注意TPS本身受玩家数影响,开太大只会让服务器页面好看,实际扛不住。online-mode默认true,正版验证模式,不要随便关掉,关掉之后盗版玩家可以进,但服务器同时也失去了对UUID的官方控制,容易被刷号骚扰,除非你确实在做离线服且明确了解风险。
还有一个隐藏比较深的优化点:sync-chunk-writes。这个键在Paper的paper-world-defaults.yml里,默认true,意思是区块保存时同步写入磁盘。对机械硬盘来说这会造成明显卡顿,改成false可以改为异步写入,但在断电时可能丢区块,需要结合你自己的备份策略来决定。服务器用的是SSD的话,保持默认true问题不大。
3.3 Paper专属配置:paper-global.yml与paper-world-defaults.yml
与server.properties不同,Paper的专属配置被拆成了两个主要文件:paper-global.yml和paper-world-defaults.yml。首次启动后会在目录下自动生成,里面注释非常详细。我重点说几个一般人不知道但很管用的选项。
paper-global.yml里有一个tick-rate下的auto-save-interval,默认是6000刻(5分钟),决定服务器多频率自动保存一次。对于大型服务器,保存瞬间容易卡顿,可以调成9000甚至12000,能有效降低存档卡顿,但风险是停电时丢更多数据,务必权衡。
prevent-moving-into-unloaded-chunks这个选项建议打开。如果不开,玩家在高速移动(比如鞘翅飞行)时可能冲进未加载的区块,轻则卡一下,重则掉出世界。打开后服务器会阻止玩家进入未加载区块,体验更稳。
paper-world-defaults.yml里,最实用的是spawn-limits。它分别控制怪物、动物、水生物、环境友好的生物的生成上限。原版上限偏高,服务器容量一大就会吃满CPU。比如每个世界的怪物上限默认是40,调成20到25就能显著降低实体压力,同时不影响正常刷怪。这里的数值不是全图硬上限,而是按玩家每单位时间内的生成配额计算的,所以砍到20体感也不会消失。
还有entity-per-chunk-save-limit。这个选项针对经验球、箭矢这类堆积物特别有效。以前我服务器一到刷怪塔区域就频繁顿卡,打开存档一查,光经验球就有几万颗。设置entity-per-chunk-save-limit的经验球数值为100,箭矢为50,超过的实体就不写入存档,运行内存马上干净很多。
标记一下,改完任何yml文件都要重启服务器生效,改之前先备份原文件。Paper很多配置项是启动时读一次的,运行中修改不会热加载。
4. 插件与玩法落地:从Paperclip到完整体验
4.1 常用插件推荐与安装方法
Paper服务端支持Spigot和Bukkit的插件,生态非常丰富。安装流程很简单:把下载好的jar文件丢进服务端根目录下的plugins文件夹,如果文件夹不存在就手动新建一个,然后重启服务器。Paper会在启动时扫描plugins下的所有jar并加载。
基础功能性插件,我自己用的比较稳的一套是:
- EssentialsX:提供基础指令,比如/home、/tpa、/spawn、/kit,几乎每个服务器标配
- LuckPerms:现代权限管理插件,用它控制玩家能执行哪些指令、能进入哪些世界
- WorldEdit与WorldGuard:前者负责批量建造和地形编辑,后者负责圈地保护
- CoreProtect:方块记录插件,哪块被谁破坏了,一查就能恢复
- ViaVersion:兼容不同版本客户端进入同一个服务器,比如1.20.4的服务端让1.19客户端也能进
装插件之前,先确认它支持的Minecraft版本。很多老插件用在新版本上会直接抛NoSuchMethodError,表现就是启动时报错或者插件功能失效。Paper插件的兼容性比Spigot好,但也不是万能,尽量下载预览版本或者更新频繁的维护版。
每装一个新插件,先单独启动一次服务器,看日志里有没有"Loading plugin"和"Enabling plugin"这两行。如果插件加载时报了一堆红色stacktrace,说明它有依赖库没有装全,通常需要把插件说明里要求的依赖也放进plugins目录。
4.2 单人测试、局域网联机和公网部署
服务器跑起来之后,先在客户端多人游戏里添加localhost或127.0.0.1,确认能正常进入。这一步能排除大多数本地问题:世界生成正常、出生点不卡、玩家动作对话都顺畅。
局域网联机的话,用主机IP或者内网IP,例如192.168.1.10:25565,玩家的客户端和你的服务器在同一个路由器下才能访问。公网部署就需要考虑端口转发了。在路由器后台找到端口转发功能,把TCP和UDP的25565端口都转发到运行服务端的那台机器IP上,然后在外网用你的公网IP加端口加入游戏。
如果你没有公网IP,或者不想折腾路由器,可以考虑用frp这类内网穿透工具,把本地的25565映射到一台有公网IP的跳板机上。只要能保证TCP握手正常,Minecraft的流量就能走通。
公网部署前一定检查防火墙。Linux下用ufw或iptables放行25565端口,Windows下在防火墙高级设置里添加入站规则。我见过不少服务器本地能进、外网死活连不上,最后发现是防火墙拦截了java进程的入站连接。
4.3 开服自查清单:备份、升级、监控
最后一个环节,也是很多新手最容易省略的环节:备份和监控。没有备份的服务器,一次坏档就全完了。我常用的备份方式是Linux下crontab定时任务,每天凌晨把服务端目录里的world、world_nether、world_the_end这几个文件夹打包压缩,保留最近7天的备份。
tar -czf backup_$(date +%Y%m%d).tar.gz world world_nether world_the_end plugins升级Paper版本之前,先停服,备份世界,再替换新的jar包。启动后第一件事开timings或spark查看TPS和tick曲线。Paper自带timings报告,运行/timings on,过几分钟执行/timings report,会生成一个网页链接,里面详细记录每个实体、区块、插件消耗的tick时间,非常直观。
如果你装了spark插件,指令更友好:/spark tps看看实时TPS,/spark heap看内存占用,/spark profiler做性能剖析。遇到不明原因的卡顿,先开profiler,跑一分钟,它会给出CPU热点分析方法,比盲猜插件可靠得多。
我个人还建议在服务端前接一个BungeeCord或Velocity代理,就算只有一两个子服也值得。代理层可以做玩家上线连接、权限分组、账号统一管理,将来想拆成多世界群组服也不需要推倒重来。
5. 我在多个版本里踩过的坑和排查方法
5.1 启动期报错:内存、端口、Java版本
我开服这几年,最常见的启动期报错就三类。
一是"Invalid maximum heap size: -Xmx4G"。出现这个,先检查你的系统物理内存是不是真的够4G,如果内存不够就该调小。还有一个容易忽略的原因:Java版本和容器位数。在32位JVM上设置超过1G的-Xmx也会报这个错,现在基本是64位Java,遇到这种提示第一时间检查java -version里的64-Bit字样。
二是"Failed to bind to port: 25565: Address already in use"。字面意思很清楚,端口被占了。通常是你没关干净上一个服务端进程,或者别的程序占了端口。Linux下用lsof -i :25565看是哪个进程占用的,找到PID后kill掉就行。Windows下则用netstat -ano | findstr :25565,再对应PID在任务管理器里结束进程。
三是启动日志一开头就提示"Unsupported class file major version"。这说明Java版本太老,识别不了新版本Minecraft核心编译出来的class文件。对应前面那张Java版本表检查一遍即可。还有反过来一种情况:你下的是Java 8时代的Paper老版本,却用了Java 21去跑,同样可能报错。最好根据核心版本精准安装Java。
5.2 插件冲突与崩溃日志定位
插件装多了,难免出现冲突。最典型的症状:服务器启动到一半,日志刷出一堆"NullPointerException"或者"InvalidPluginException: Unsupported plugin version",然后进程退出。
遇到这种情况,不要慌,先找到日志文件logs/latest.log,搜索关键词ERROR或者Caused by。崩溃时往往有一段stacktrace,里面第一行就是报错的插件包名。比如"github.com/xxx/MyPlugin.method(...)",用这个包名去插件说明文档里搜,就能定位是哪个插件的问题。最简单处理方式是把该插件临时移出plugins目录,重启看是否恢复正常。
还有一种隐蔽的冲突:两个插件同时改写了同一条指令。比如EssentialsX和另一个领地插件都注册了/sethome,后加载的插件可能会覆盖前者,导致指令行为异常。排查时用/plugins指令看加载顺序,再决定禁用哪一个。插件之间互相依赖时,加载顺序错乱也会报错,这时候需要在paper-global.yml里通过load-before或load-after手动指定加载顺序。
5.3 跨版本升级Paper的注意事项
每次Minecraft大版本更新,Paper也会跟着发布对应版本。跨版本升级是所有服主最紧张的环节,我总结的流程是:先备份全量数据,再下载新版jar,然后保留原plugins和世界数据,直接启动。
如果你服务器上有大量插件和复杂的红石机械,不建议跨大版本直接升级。比如1.20.4到1.21,很多依赖NMS(Minecraft服务端内部类)的老插件会直接失效。版本升级前必须去对应插件GitHub页面查兼容性说明,等所有核心插件都更新了再动手。
升级完成后,还要检查一次世界配置。Paper在每次启动时会自动优化或转换部分世界数据格式,旧世界的某些实体可能丢失,所以升级后让玩家暂时不要大规模刷怪或跑图,先让服务器自动清理一晚。我在一次1.18升1.19时遇到过旧世界区块出现大片空心方块的情况,后来发现是某个地图预生成的插件没有适配新版区块格式,卸载后重新生成才正常。
我个人在实际操作中还有一个不算高深但特别有效的习惯:每次升级前把plugins目录也全面备份,而且不嫌麻烦地记录一份插件版本清单。这样即使新版本全线崩掉,我也可以在十分钟内回滚到旧版本。很多服主觉得备份麻烦,但真正经历过一次存档损坏之后,你就会知道备份这个动作本身是开服流程里的安全底线,而不是可选项。
最后再分享一个小技巧:Paper每次启动会在根目录生成一个latest.log,里面除了报错信息,还记录了启动耗时、World加载顺序、插件版本等关键数据。如果你哪天想让服务器启动更快,看看日志里每个世界的加载耗时,把不需要立即加载的世界放到后启动,或者把worlds目录下暂时不想用的世界改名成.bak后缀,启动时间能缩短非常明显。折腾服务器这件事,经验都是一次次踩坑换来的,希望这篇东西能帮你少走几步弯路。