如何选择合适的系统
(网页面板开服可以跳过本段)如果你想要优化你的《我的世界》服务器,首先要考虑的就是系统的选择。很多人都认为 Linux 类系统(Centos、Debian 等)比 Windows 更高效、稳定,但这并不意味着你就要盲目地选择一个你不熟悉的系统。想象一下,如果你遇到了一个紧急的问题,你却不知道如何在 Linux 下操作,你会不会觉得很无助?而且,在内存足够使用的情况下,Windows 和 Linux 开服的性能差距其实并不大。所以,我的建议是,选择一个你最熟悉、最舒服的系统。当然,如果你已经熟悉 Linux 的操作,或者有较强的学习能力,想要尝试 Linux 开服,那么我会推荐你使用 Ubuntu(稳定性突出、可靠性不俗、大量教程和文档)。
如何选择合适的JVM版本
(网页面板开服可以跳过本段)JVM(Java Virtual Machine)也就是 Java 虚拟机,它是一个虚构出来的计算机,可以在实际的计算机上模拟各种计算机的功能 1。JVM可以让你的《我的世界》服务器运行在不同的系统上,但是你需要选择合适的JVM版本。一般来说,你有两个选择:JRE(Java Runtime Environment)和 JDK(Java Development Kit)。JRE是Java运行环境,只包含了基本的运行库和虚拟机。JDK是Java开发工具包,除了包含JRE之外,还增加了一些性能调优工具如 VisualVM。我推荐你使用 JDK,因为它可以让你更好地监控和优化你的服务器性能。至于JVM的版本,根据《我的世界》服务端版本号不同,你需要选择不同的JDK/Java版本2 。如果你使用的是1.17及以上版本,你需要使用 Java 16 或 Java 173,因为这些版本对 Java 有更高的要求。如果你使用的是1.16及以下版本,你可以使用 Java 8 或 Java 114,因为这些版本对 Java 的兼容性更好。总之,你需要根据你的服务器需求和系统环境,选择一个适合你的JVM版本。
服务端的选择
从服务端的选择开始就注定了性能优劣的起步水平,现在有很多种服务端可以选择,它们各有优缺点,适合不同的需求。一般来说,服务端可以分为两大类:基于官方代码的服务端和不基于官方代码的服务端。基于官方代码的服务端是在原版服务端的基础上进行修改和优化,保留了原版的特性和兼容性,但也受限于原版的性能和BUG。不基于官方代码的服务端是完全重新编写的服务端,拥有更高的性能和更多的自定义功能,但也可能存在兼容性和稳定性问题。下面介绍一些常见的服务端:
- Minecraft Server:Minecraft Server 是 Mojang 官方制作的原版服务端,更新非常快,基本上和 Minecraft 客户端版本同时发布,不能安装任何 Mod 和插件,只能够使用原版的命令和物品,适合基友服联机使用。
- Spigot:Spigot 是一个非常流行的服务端,它是在 CraftBukkit(水桶服)基础上优化而来的,支持 Bukkit 插件 API,并且拥有近百项的优化,例如异步加载、读取区块,限制实体的活动范围,修复一些内存泄露的问题等等。所以同版本下可以很容易感受到 Spigot 有着更出色的性能和更低的内存占用。
- Paper:Paper 是一个在 Spigot 基础上优化而来的服务端,拥有更多更激进的优化,Paper 也修复了一些原版或 Spigot 的 BUG 和特性,例如刷 TNT、刷沙子、催熟仙人掌和甘蔗、破基岩之类的操作在 Paper 端里统统是做不来的3。Paper 也支持 Bukkit 插件 API,并且有自己的插件 API(Paper API),可以让插件开发者利用 Paper 的特性和功能2。
- Forge:Forge 是一个老牌 mod API, 优点就是 mod(这不是一个独立的服务端,但是通常 mod 和原版是不能兼容的,所以把 mod API 也视作一种服务端)
- Mohist:Mohist 是一个全新的 Minecraft Forge 服务端,基于 1.12.2/1.16.5/1.7.10 下,核心采用 Forge + Paper 结构,开发环境使用 ForgeGradle,支持 Forge mod 和 Paper 系列插件。
在最后需要提醒的是,如果没有特殊原因,建议使用最新版本的服务端,最新版本的服务端往往修复了目前已知的绝大多数 BUG 和有着更多的性能提升。
启动脚本
(网页面板开服可以跳过本段)越多的启动参数反而导致越多的性能损耗。在不了解 JVM 工作原理的情况下,不要随随便便增加一大堆无用的启动参数。一般情况下指定最小内存、最大内存即可,Java7 还需要指定一个大于等于 128MB 的 MaxPermSize
。
根据不同版本的 JDK,启动参数也有所不同。下面给出一些常用版本的 JDK 的启动参数示例:
Java7 的开服参数可以是(如果大型插件非常多,MaxPermSize
可以设置得更高):
-Xms
最小内存-Xmx
最大内存-XX:MaxPermSize=128M
-XX:+AggressiveOpts
-XX:+UseCompressedOops
-
-XX:MaxPermSize
的含义是设置永久代(PermGen)的最大大小,这个区域用于存放类信息和常量池等数据. -
-XX:+AggressiveOpts
的含义是尽可能的使用更多对性能有帮助的优化功能 -
-XX:+UseCompressedOops
的含义是指针压缩,可以减少一定的内存占用(64 位才支持)
-
Java8 的参数可以是:
-Xms
最小内存-Xmx
最大内存-XX:+AggressiveOpts
-XX:+UseCompressedOops
- Java8 不需要设置永久代大小,因为它被元空间取代了,元空间默认使用本地内存
Java9 及以上版本的参数可以参考:
-
-Xms 最小内存 -Xmx 最大内存
-XX:+UnlockExperimentalVMOptions -XX:+UseZGC -XX:ZUncommitDelay=10
-
-XX:+UnlockExperimentalVMOptions
的含义是解锁实验性质的 VM 选项 -
-XX:+UseZGC
的含义是使用 ZGC 垃圾回收器,这是一个低延迟、高吞吐量、可伸缩的垃圾回收器 -
-XX:ZUncommitDelay=10
的含义是设置 ZGC 在释放未使用内存之前等待的时间(秒),默认值为 300,这里设置为 10 是为了减少内存占用
-
参数的优化
不要小瞧参数的修改带来的优化空间,有时候只修改一个参数,就是在线 100 人 TPS19 和 TPS16 的差距。参数的调整分别为 server.properties
(原版服务器就有),bukkit.yml
(水桶服或者衍生版才有),spigot.yml
(Spigot 或者衍生版才有),paper.yml
(PaperSpigot 才有)。
前面加点为需要注意的项目
server.properties
中可以优化性能的参数:
-
view-distance
,视距,默认值是10
。含义是玩家的视距也就是加载的区块范围,默认是 10 个区块,相当于一个正方形边长为21
的区域。视距10
加载的区块是视距5
的四倍。视距越大,玩家能看到的景色越多,但也需要更多的内存和运算能力来加载和更新区块。推荐将这个值设置在5
或者6
,如果在线人数非常多可以设置为4
。降低视距可以有效减少内存的占用,也能有效提高 TPS,还可以减少网络流量的消耗。这个参数对性能提升是立竿见影的。 -
generate-structures
,默认值是true
。含义是是否在生成世界时生成一些特殊的结构,例如村庄、神庙、要塞等等。设置为 false 可以减少这些结构生成和周期性检查带来的开销。这个参数很少被提起,但是对性能的提升有着不少的帮助。需要彻底关闭这个参数,还需要在spigot.yml
中把save-structure-info
设置为false
,并且关服后手动删除每个世界(例如world
、world_nether
、world_the_end
)下的data
文件夹里的Fortress.dat
、Mineshaft.dat
、Stronghold.dat
、Temple.dat
、Village.dat
文件。
network-compression-threshold
,默认值是 256。这个参数只有 1.8 的服务端才有,含义是网络封包压缩的阀值。例如设置为 16,代表封包大于 16 才被压缩,设置成 256 代表着封包大于 256 才被压缩。设置的值越小则会压缩更多的封包,可以使得宽带使用减少,提高网络流畅程度,但是也会增加性能的开销。如果性能够用可以设置为 128,使得更多通讯封包被压缩,一定程度上减少宽带使用率又不会带来太多的性能开销。设置的值太小,例如小于等于 32 会明显增加对性能的开销,不建议这么做。
bukkit.yml
中可以优化性能的参数:
-
spawn-limits
,意思是限制实体的生成。这个并不是限制一个区块生成多少实体,而是针对一个人可以生成多少实体。例如 monsters: 70,在线人数只有 10 个人,则最多只能生成 700 个怪物实体(僵尸、骷髅、蜘蛛等等),适当的设置这些参数可以减少实体对性能的影响。例如:
spawn-limits:
monsters: 70
animals: 10
water-animals: 15
water-ambient: 20
ambient: 15
或者再少一点:
spawn-limits:
monsters: 50
animals: 8
water-animals: 7
water-ambient: 10
ambient: 1
-
chunk-gc
,控制着区块的回收,单位是 Tick,period-in-ticks
是指每过多少tick
回收一次需要回收的区块,设置的太小会导致回收过于频繁而影响性能,设置的太大会导致需要回收的区块迟迟不回收使得内存占用过大。合理的数值一般是300~400
。load-threshold
是指达到多少需要回收的区块的时候才进行回收。例如设置成300
,只有当需要回收的区块到达300
以上才进行回收,合理的设置这个数值可以使得额外只多占用一丁点内存却使得区块回收的性能开销可以被无视。一般设置为300~600
比较合适。
- autosave
,自动保存存档(地图、玩家数据等)的周期,单位是 Tick,如果你使用了定时保存的插件,例如 Saveit、AutoSave 等等,你可以将他设置为 0,即关闭这个功能。这样可以减少服务器瞬卡发生的可能。
spigot.yml
中可以优化性能的参数:
-
user-cache-size
,1.7.5 以上版本才有,其控制用户缓存的大小,如果你的服务器玩家很多,可以设置的更大一些,例如 5000。 -
save-user-cache-on-stop-only
,1.7.5 以上版本才有,其含义是是否只在服务器关闭 / 重启的时候保存用户缓存,设置为 true 可以提高性能。 -
view-distance
,同 server.properties 里的 view-distance 一样。 -
chunks-per-tick
,是指每 tick(1/20 秒)扫描计算多少区块,计算的内容是作物的生长。默认值是 650,可以设置成 350 来提高性能。极端的情况可以设置成 150,但是会使得作物生长的速度明显变慢。 -
max-tick-time
: (仅较新的版本有该参数,如 1.8.3+)是指每 tick,实体和 tile 最多可以用的时间(单位是毫秒),要明白其含义首先要解释什么是 TPS,TPS 的意思是每秒有多少 tick,最大值是 20,也就是每秒 tick20 次,每次 50 毫秒。如果运算量过大导致每 tick 计算了超过了 50 毫秒,那么 TPS 就会下降,一旦 TPS 低于 15 就会产生明显的卡顿。在这参数中 tile 代表着熔炉、箱子、牌子、骷髅头等等所能占用的最大时间,entity 是指的实体,例如动物、怪物、村民、展示框、掉落物、船、矿车等等。设置 tile 和 entity 的总和小于等于 30 则能明显降低 tile 和 entity 对 TPS 的影响,而服务器运算资源几乎一大半都是由这两者消耗的。设置 tile 为 10,entity 为 20 比较合适,如果实体非常多,还可以设置 tile 为 6,entity 为 24。 -
anti-xray
,服务端自带的反透视功能,俗称假矿。这个功能相比插件版的假矿来说,额外内存占用极少,少到可以忽略,并且矿物的变动计算是异步进行的,对 TPS 的影响很小。engine-mode 为 1 则是隐藏矿物,engine-mode 为 2 则是将非矿物也伪装成矿物,engine-mode 设置为 2 的效果最好,但是会额外吃一定的性能和宽带,但是 engine-mode 设置为 1 无法防御矿追。具体如何权衡请自行决定。如果你不需要本功能,例如你是纯 RPG 服务器,可以直接把 enabled 设置为 false 关闭这个功能,提高性能。
nerf-spawner-mobs
,简单来说就是让刷怪笼生成的怪物变成白痴,直观感受就是刷怪笼刷出的怪不能攻击了。默认为 false,意思是不开启。设置为 true 可以获得一定的性能提升。
entity-activation-range
,这个参数是控制实体的活跃范围,例如 monsters: 32 意思是在玩家附近 32 格范围内的怪物才会活跃(被计算 AI 等),减少这个数值可以明显提升性能,但是设置得过小会使得游戏难度大幅降低。一般可以把 monsters 设置为 24,animals 设置为 12,misc 设置为 2(misc 主要是掉落物,设置 2 可以使得掉落物几乎不再卡服)。
entity-tracking-range
,这个参数是控制实体的可见范围,这个参数不会影响性能,对宽带的影响也极小。不建议修改这个参数,但是适当的降低数值可以减少客户端的卡顿。
-
random-light-updates
,随机的光照更新,设置为 true 的话服务器会随机更新光照,并且在区块加载的第一个 tick 运算光照逻辑。设置为 false 可以提高不少性能。 -
save-structure-info
,在前面已经介绍了。
max-bulk-chunks
,1.7.10 + 才有这个参数,意思是每个数据封包里塞多少个区块。适当提高这个数值,例如从 10 提高到 15 可以减少网络卡顿和客户端读取区块的速度,但是设置得过高会导致客户端崩溃。
-
max-entity-collisions
,实体碰撞箱的阀值。建议设置为 2,可以减少密集卡服的问题。 -
max-tnt-per-tick
,每 tick(1/20 秒)最多计算多少 TNT 爆炸,设置为 20 可以显著防御 TNT 蹦服。
paper.yml
中可以优化性能的参数:
keep-spawn-loaded
,spawn 区块是否常驻内存,设置为 false 可以减少一定的内存占用和计算量
-
tick-next-tick-list-cap
,每 tick 最大的运算量,减少数值可以提高 TPS,例如设置为 8000 -
tick-next-tick-list-cap-ignores-redstone
,达到上面的运算阀值是否无视红石运算,设置为 true 可以显著减少红石对服务器性能的影响。 -
optimize-explosions
,是否开启爆炸算法优化,设置为 true 可以提升一定的服务器性能 -
use-async-lighting
,是否让光照的逻辑运算异步化,设置为 true 可以使得光照运算不再影响 TPS,强烈推荐设置为 true -
cache-chunk-maps
,是否缓存 chunkmaps,可以让区块的数据更多得被复用,可以一定程度提高性能,推荐设置为 true -
fast-drain
,快速液体流动运算,推荐设置为 true,可以减少液体流动运算对服务器性能的影响
优化插件的选择和一些插件建议
服务器的性能瓶颈往往在于实体的运算(它们吞噬了一半的 CPU 时间),所以定时清理实体(怪物、动物等)和限制密集卡服的插件是提升性能的利器。
很多插件都支持使用 Mysql 来存储数据,例如 CoreProtect、QucikShop、LWC 等等,如果条件允许的话,请使用 Mysql 来代替文本数据库和 Sqlite。这么做可以让服务器更加流畅。
安装插件的时候也不要太懒使用网页后台现成的插件或者使用论坛上搬运的网盘地址下载。请到 bukkit 或者 spigot 官网看看插件有无新版本。举个例子,创造服常用插件 WorldEdit 很多服务器还在使用 6.* 的版本,然而目前最新版本为 7.2.8。7.* 相比 6.* 就有着不少的性能提升和新功能。7.2.8 版本相比老版本的改动在于修复 bug 和大幅提高性能,还支持了更多的方块和实体。所以说新版本的插件往往意味着更好的性能和更少的 bug,如果版本兼容,尽可能使用最新稳定版的插件。
玩法也对性能有帮助
管理员可以提供一些类似新手村的聚居点,让玩家聚集在一起,这样就不需要加载更多区块,节约了服务器的资源。还有,也可以提供了公共的刷怪场和养殖场等,玩家可以在这里刷怪和养动物,少去自己建造这些设施,也能减轻服务器的负担。
找出卡服的真凶
1. 如何使用 Timing
Timing
是 Bukkit
和其衍生服务端版本(Spigot、MCPC+、PaperSpigot 等)自带的一种性能诊断工具,可以很方便的查看服务端的性能是由那些部分所消耗的,以图表形式还能直观的查看重点性能消耗大户,对于腐竹来说可以很方便的定位卡服的插件或者卡服的原因,对于插件开发者来说可以直接定位到性能不佳的程序方法(Function),方便优化插件性能。为了确保真实性,下面的演示全部在真实的服务器上操作,为了保护玩家隐私和密码安全,已打码处理。
要使用这个功能,首先你需要在服务器内或者直接在后台内输入指令 —— timings on
开启统计,具体如图所示:
为了得到准确的统计结果,建议等待至少 15 分钟,如果是在瞬间卡顿的峰值附近,建议至少等待 5 分钟。
在等待足够的时间后,输入指令 —— timings paste
稍等片刻,会生成一串网址,记下这个网址(图片已打码)
现在打开图中的网址,即可查看服务端的『性能分析报告』了。需要注意的时候,不需要使用的时候请使用 timings off
指令关闭性能统计,否则会带来不必要的性能损耗。
2. 如何读懂 Timing
首先,我们打开刚刚生成的网址,我们先从基础的信息开始阅读。
Total
是指从统计开始一共服务端运行的时间(由 Ticks 推算),Sample Time
是指统计总时长。后面紧跟着的是服务端的版本信息,例如我的是 PaperSpigot1.8.8
,Average Entitys
是平均实体的数量,表示形式是 活跃实体数量 / 总实体数量。一般而言只有活跃实体才会消耗 CPU 时间。Average Players
是统计时间内平均这个服务端在线的人数(注意,是单个服务端的在线人数),例如我的是 105.81 人。Average TPS
是统计时段内平均的 TPS,例如我的是 19.44。Server Load
是指服务端负载水平。超过 100% 则意味着 TPS 会开始低于 20 的水平,一般超过 150% 就会有明显卡顿了。