尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

Ubuntu云服务器搭建饥荒联机版专用服:配置、部署与运维实战

Ubuntu云服务器搭建饥荒联机版专用服:配置、部署与运维实战 1. 先算账再开服饥荒专用服的资源基线我在 Ubuntu 云服务器上架饥荒联机版专用服这件事前后折腾过四五次从最初 1 核 2G 的学生机一路换到 4 核 8G中间踩的坑基本都集中在配置估错和目录放错这两件事上。这篇就按我实际操作的顺序把从买机器到长期运维的完整链路捋一遍你照着抄基本能一次跑通省下反复重装系统的时间。1.1 一个主世界加一个洞穴内存到底吃多少饥荒联机版专用服有个很反直觉的特性它卡不卡跟在线人数的关系远没有跟实体数量的关系大。服务器进程干的事是持续模拟地图上所有生物、植物、建筑的状态机玩家越多、基地越大、养的家畜越多单帧要算的对象就越多CPU 单核占用就越高。内存则主要被地图数据和实体索引占着跟人数是弱相关的。我给一组实测的参考区间都是在 Ubuntu 22.04、关闭其他服务的前提下测的场景常驻内存RSS说明Master 单分片空载约 500-700 MB世界刚生成没有基地Master 单分片6 人加中型基地约 1.2-1.8 GB含冰箱、箱子、农场、成堆的猪人房Master Caves 双分片空载约 1.0-1.4 GB两个独立进程各自一份地图Master Caves6-8 人长期在线约 2.5-3.5 GB洞穴里挖矿、养兔人之后所以结论很直接开洞穴、想稳定带 6 人以上4 GB 内存是舒适线只想开单世界、4 人以内2 GB 能跑但没什么余量一旦有人造大基地就会开始频繁触发系统 OOM 杀进程。内存不够最典型的表现不是卡而是服务器毫无征兆地重启、玩家集体掉线你去dmesg里一查能看到 oom-killer 的记录。顺带解释一个很多人搜的问题云服务器32 核 128G里的 128G 指的是内存容量 128 GB不是硬盘也不是带宽。那个规格是给数据库、虚拟化平台这类负载准备的跑饥荒属于拿高射炮打蚊子。1.2 单核主频比核心数重要得多饥荒专用服的模拟主循环是单线程的你给它 32 个核心它也只用一个。所以选机器的时候判断标准应该反过来先看单核主频和是不是独享 vCPU再看核心数。我做过一次横向对比同样的存档一个建了三个月的基地群在两类机器上的 tick 表现差别很明显共享型 vCPU超卖比较狠的那种在晚高峰时服务器 tick 会明显抖动玩家会感觉走路一顿一顿换成独享型之后同样的负载就基本平了。原因也不复杂共享型是物理核被多个租户轮着用你的单线程主循环会被别人的负载打断。带宽这块容易被高估。饥荒的同步量其实很小一个玩家满负荷大概占用上行 20-40 KB/s8 个人同时在线也就 2-3 Mbps 上行。所以2-4 人2-3 Mbps 上行够6-10 人3-5 Mbps 上行够留点余量给模组和更新超过 10 人重点已经不是带宽而是单核能不能扛住这么多实体真正需要注意的是用带宽计费还是按固定带宽计费。饥荒是长连接、低流量一个月跑下来流量通常很少按流量计费反而便宜但如果你打算挂个网页地图或者频繁更新模组固定带宽更省心。另外很多云厂商对新用户有短期的试用额度先用试用机跑通全流程、确认没问题再决定买什么规格比一上来就买年付划算得多。1.3 系统版本、时区和时钟这三样要在装环境之前定好系统我建议直接用Ubuntu 22.04 LTS 或 24.04 LTS 的 64 位版本。理由有三个软件源里的 32 位兼容库版本足够新SteamCMD 必须要它systemd 的版本支持我后面要用的守护写法社区里对应的问题帖子也最多。别用太老的版本老版本的 glibc 会导致专用服报GLIBCXX_3.4.21 not found这类错很难绕。时区要改成自己常用的不然后面看日志会精神分裂sudo timedatectl set-timezone Asia/Shanghai timedatectl status最后是时钟同步这个看起来很无关实际上很关键。饥荒专用服启动时要拿集群令牌去跟平台服务器做鉴权如果本机时间偏差太大整个过程会莫名其妙地失败而日志里只会给一句很含糊的提示。同时你后面做存档快照、看日志时间线也都依赖系统时间准。Ubuntu 默认的systemd-timesyncd一般够用如果发现同步不上可以换成 chronysudo apt install -y chrony sudo systemctl enable --now chrony chronyc sources -vchronyc sources输出前面带*的那一行就是当前生效的时间源。国内用公共时间服务器源就行不用自己指定具体地址系统自带的pool.ntp.org会因为就近解析自动选到合适的节点。2. 拿到机器后的前半小时环境与账号2.1 首次登录与安全组先把门关上再干活云服务器开出来之后控制台会给你公网 IP 和初始密码或者让你绑定密钥。我用密钥登录密码登录太容易被扫。第一次登录后先做三件事# 1. 更新一次软件源 sudo apt update sudo apt upgrade -y # 2. 装上常用的基础工具后面调试用得上 sudo apt install -y vim htop tmux curl wget unzip git # 3. 看一眼当前谁在连你 sudo ss -tunlp改 SSH 端口这件事看个人习惯我的建议是改但改完一定要先确认云厂商控制台的安全组里放行了新端口再断开当前连接否则很容易把自己锁在外面。安全组是云平台层面的一道独立防火墙跟服务器上的 ufw 是两套东西两边都要放行才能真正通。饥荒需要开放的端口记住 UDP 是重点很多人只开了 TCP 结果一直连不上端口协议用途10999UDP主世界 Master 的玩家连接端口11000UDP洞穴 Caves 的玩家连接端口27016-27017UDP服务器列表上报端口8766-8767UDP鉴权端口22 或自定义TCPSSH 管理服务器本机如果开了 ufw也要对应放行sudo ufw allow 22/tcp sudo ufw allow 10999/udp sudo ufw allow 11000/udp sudo ufw allow 27016:27017/udp sudo ufw allow 8766:8767/udp sudo ufw enable sudo ufw status verbose2.2 建一个专用普通账号别用 root 跑游戏服这条是新手最常跳过的。SteamCMD 和饥荒专用服都不应该用 root 跑一是它们会在自己的工作目录里写一堆文件权限搞乱了以后很难收拾二是专用服本身是个长期暴露在公网的进程用 root 跑等于把风险放大了。sudo adduser --disabled-password --gecos steam sudo -iu steamsudo -iu steam是切到 steam 用户并且加载它的环境变量比su steam干净。之后的下载、配置、启动全部在这个账号下完成。建议给它配一个 SSH 密钥方便以后直接登录或者干脆就一直用sudo -iu steam切换。2.3 32 位运行库这个坑躲不掉SteamCMD 是 32 位程序在 64 位 Ubuntu 上跑必须先开 32 位架构支持再装对应的兼容库。这一步漏了的话SteamCMD 会直接报错退出或者更隐蔽地卡在某一步不动。# 切回有 sudo 权限的账号执行 sudo dpkg --add-architecture i386 sudo apt update sudo apt install -y lib32gcc-s1 lib32stdc6 libcurl4-gnutls-dev:i386如果你在 18.04 之前的版本上包名会是lib32gcc1而不是lib32gcc-s1装不上就换一个名字试。装完之后还有一个超经典的报错我在不同机房里遇到过至少三次error while loading shared libraries: libcurl-gnutls.so.4: cannot open shared object file这玩意的根因是专用服的可执行文件编译时链接的是libcurl-gnutls.so.4这个名字而某些发行版里装的库文件叫libcurl.so.4名字对不上。两个解法我一般用第二个因为它不影响系统包管理# 解法一补装带 gnutls 的包 sudo apt install -y libcurl4-gnutls-dev:i386 # 解法二直接做个软链接更稳不会跟包管理打架 cd /usr/lib/x86_64-linux-gnu sudo ln -sf libcurl.so.4 libcurl-gnutls.so.4 sudo ldconfig提示做软链接之前先用ls -l /usr/lib/x86_64-linux-gnu/libcurl*确认一下libcurl.so.4确实存在不存在说明前一步的包装失败了。3. SteamCMD 落地与服务器文件3.1 SteamCMD 用普通账号装别放到系统目录切到 steam 账号之后建两个目录一个放 SteamCMD 本体一个放游戏服文件分开是为了以后重装 SteamCMD 不影响存档和配置。sudo -iu steam mkdir -p ~/steamcmd ~/dst cd ~/steamcmd curl -sqL https://steamcdn-a.akamaihd.net/client/installer/steamcmd_linux.tar.gz | tar zxvf -第一次运行./steamcmd.sh的时候它会自己下载更新一堆东西等出现Steam提示符就算成了。之后可以用quit退出。3.2 appid 343050一条命令把服务端拉下来饥荒联机版的专用服务端在平台上的 appid 是343050游戏本体是 322330别搞混装错了会拉下来一堆用不上的客户端资源。用匿名方式登录就能下不需要买额外的授权。cd ~/steamcmd ./steamcmd.sh \ force_install_dir /home/steam/dst \ login anonymous \ app_update 343050 validate \ quit几个参数的作用值得说清楚force_install_dir指定落盘位置必须写在login之前写在后面不生效validate会让它校验文件完整性更新后出各种莫名其妙的启动失败时先跑一次 validate 往往就好了。下完之后检查一下关键文件在不在ls -l /home/steam/dst/bin64/应该能看到dontstarve_dedicated_server_nullrenderer_x64这就是我们要启动的主程序。3.3 目录清单每个文件去哪了干什么用这里必须先建立一个空间概念因为后面所有配置错误的根源都在文件放错了地方。饥荒专用服的配置分成两个完全独立的目录树路径归属放什么/home/steam/dst/程序目录可执行文件、data 资源包、mods/dedicated_server_mods_setup.lua/home/steam/.klei/DoNotStarveTogether/用户数据目录集群配置、令牌、世界存档、modoverrides.lua再把用户数据目录展开看~/.klei/DoNotStarveTogether/ └── Cluster_1/ # 集群目录名字可以自定义 ├── cluster.ini # 集群级配置 ├── cluster_token.txt # 集群令牌必须 ├── adminlist.txt # 管理员列表 ├── blocklist.txt # 黑名单 ├── Master/ # 主世界分片 │ ├── server.ini │ ├── worldgenoverride.lua │ ├── modoverrides.lua │ └── save/ # 存档在这里 └── Caves/ # 洞穴分片 ├── server.ini ├── worldgenoverride.lua ├── modoverrides.lua └── save/程序目录和用户数据目录默认是分开的靠启动参数里的-cluster Cluster_1关联起来。如果你想让它们合并到一处可以用-persistent_storage_root和-conf_dir两个参数改写默认路径但我不推荐新手这么干默认路径出了问题网上能搜到答案自定义路径出了问题只能自己查。4. 集群配置cluster.ini 与两个分片4.1 先造出集群骨架最简单可靠的办法是让服务器自己生成模板而不是手写。空目录直接启动一次主分片它会把默认的cluster.ini、server.ini、worldgenoverride.lua全部写出来你在模板上改比从零写省心得多。mkdir -p ~/.klei/DoNotStarveTogether/Cluster_1 cd /home/steam/dst/bin64 ./dontstarve_dedicated_server_nullrenderer_x64 -console -cluster Cluster_1 -shard Master它会因为缺令牌报错退出但配置文件已经生成了。这时按 CtrlC 停掉开始改。4.2 cluster.ini集群级别的东西都在这这个文件管的是整个集群而不是某一个世界逐段说明照着改就行[GAMEPLAY] game_mode survival max_players 6 pvp false pause_when_empty true [NETWORK] cluster_name 我的饥荒服 cluster_description 长期开欢迎朋友 cluster_password 换一个自己的密码 cluster_intention cooperative cluster_language zh [MISC] console_enabled true max_snapshots 6 shard_enabled true bind_ip 127.0.0.1 master_ip 127.0.0.1 master_port 10888 cluster_key 随便一串字母数字几个容易改错的点pause_when_empty true是没人时暂停模拟对省 CPU 很有用但要注意如果你的朋友开了自动挂机虫暂停会导致一些自动化失效。shard_enabled true是开启分片也就是洞穴的总开关不开这个Caves 分片起了也没意义。bind_ip和master_ip都填127.0.0.1是对的因为两个分片在同一台机器上走本地回环通信更快也更安全master_port是它们内部通信用的端口跟上面给玩家用的 10999/11000 完全是两回事。max_snapshots决定保留多少个存档快照回滚功能靠它。默认 6 大概能覆盖一两天长期服可以调到 10-12。4.3 server.ini分片级配置端口和主从标记每个分片目录下都有一份server.ini主世界和洞穴的写法不同。主世界Master/server.ini[NETWORK] server_port 10999 [SHARD] is_master true name Master id 1 [STEAM] master_server_port 27016 authentication_port 8766洞穴Caves/server.ini[NETWORK] server_port 11000 [SHARD] is_master false name Caves id 2 [STEAM] master_server_port 27017 authentication_port 8767关键点在于两个分片的server_port必须不同name必须和目录名一致id必须唯一is_master只能有一个是 true。这几条错任何一条表现都是洞穴起不来或者连不上洞穴。注意不同版本生成的模板里[STEAM]段的这几个端口有时会落在cluster.ini而不是server.ini。以你自己机器上生成的那份为准别拿网上抄来的配置直接覆盖容易整出双份配置打架的情况。4.4 令牌、管理员和黑名单cluster_token.txt是这个集群的身份凭证放在Cluster_1/目录下整个集群共用一份里面就是一行字符串。没有它服务器起不来会一直卡在启动阶段。这个令牌跟你的账号绑定一个账号可以开多个集群但建议一个集群一份便于管理。adminlist.txt在集群目录下一行写一个用户 ID前面加个**KU_xxxxxxxx用户 ID 怎么拿让朋友在游戏里按~打开控制台输入ThePlayer.userid打印出来或者在游戏里输入c_listallplayers()看当前在线玩家的 ID。管理员能用的指令包括踢人、回滚、重启权限不小只给信得过的人。blocklist.txt同理被写进去的 ID 无法进入服务器。5. 世界生成、洞穴与模组5.1 第一次启动生成地上世界配置齐了之后正式启动主世界cd /home/steam/dst/bin64 ./dontstarve_dedicated_server_nullrenderer_x64 -console -cluster Cluster_1 -shard Master第一次启动会花几分钟生成地图期间内存会飙高这是正常的。生成完成的标准是日志里出现Sim paused或者Server is now accepting connections这类字样。生成完之后你会发现Master/save/下多了一堆东西这就是你的存档。这时候在游戏里搜服务器名就能找到了搜不到的话优先检查三件事安全组的 UDP 端口、cluster_name是否含奇怪字符建议先用纯英文测试、以及游戏版本和服务器版本是否一致。5.2 洞穴分片为什么起不来洞穴是新手最容易卡住的地方我把它单独拿出来说。在启动 Caves 之前必须先让 Master 跑起来并且完成世界生成Master 没起来的时候启动 Caves 会一直重试然后失败。启动洞穴./dontstarve_dedicated_server_nullrenderer_x64 -console -cluster Cluster_1 -shard Caves如果你希望洞穴也按洞穴的规则生成需要在Caves/worldgenoverride.lua里明确指定预设否则有些版本会按主世界的规则去生成洞穴的地形结果就是洞穴里长草长树但没矿return { override_enabled true, preset DST_CAVE, }洞穴起不来时按这个顺序排查cluster.ini里shard_enabled是不是trueCaves/server.ini里is_master是不是false两个分片的server_port是不是撞了master_port 10888在两边是不是一致cluster_token.txt是不是只放了一份在集群目录下不要在每个分片里再放一份5.3 模组两个文件的位置千万别放错模组配置涉及两个文件位置完全不同这是最高频的翻车点文件一/home/steam/dst/mods/dedicated_server_mods_setup.lua这个文件在程序目录下作用是告诉服务器去创意工坊拉哪些模组下来。内容就两行格式ServerModSetup(378160973) ServerModSetup(458587300) ServerModCollectionSetup(379114180)ServerModSetup是单个模组 IDServerModCollectionSetup是整个合集 ID。这个文件只负责下载不负责启用。文件二~/.klei/DoNotStarveTogether/Cluster_1/Master/modoverrides.lua这个文件在用户数据目录下作用是告诉服务器这些下载好的模组用哪些、参数怎么配。它必须同时放在 Master 和 Caves 两个分片目录里否则只有一半世界有模组。return { [workshop-378160973] { enabled true, configuration_options { -- 具体参数看各模组自己的说明 } }, }配置完之后日志里会出现模组下载的进度输出。想确认模组到底落在磁盘的哪个位置直接搜最快find /home/steam -maxdepth 6 -type d -name workshop-*常见的模组相关故障模组红字加载失败一般是模组 ID 写错或者模组本身是纯客户端模组这类模组服务端装了也没用模组生效但参数不对多数是modoverrides.lua里的configuration_options键名跟模组定义的不一致照搬别人的配置最容易出这个问题。6. 让服务器活着守护、更新与排错6.1 systemd 还是 tmux这是个取舍两种起法我都长期用过说清楚各自的适用场景。tmux 方案适合想随时敲控制台指令的人。tmux new -s dst建会话在里面启动服务器CtrlB D脱离tmux attach -t dst回到会话直接打字就能执行c_save()、c_announce(要重启了)这类指令。缺点是机器重启后要手动再起。systemd 方案适合搭好就不想管的场景。崩溃自动重启开机自启日志统一进 journald。缺点是没法直接敲控制台指令想发公告只能靠外部工具。我的做法是两个都要用 systemd 跑正式服务保证稳定同时保留一个 tmux 会话用来临时调试。systemd 单元文件长这样两个分片各写一份[Unit] DescriptionDST Master Shard Afternetwork.target [Service] Typesimple Usersteam Groupsteam WorkingDirectory/home/steam/dst/bin64 ExecStart/home/steam/dst/bin64/dontstarve_dedicated_server_nullrenderer_x64 -console -cluster Cluster_1 -shard Master Restarton-failure RestartSec15 KillModemixed StandardInputnull [Install] WantedBymulti-user.target放到/etc/systemd/system/dst-master.serviceCaves 的改一下名字和-shard参数存成dst-caves.service然后sudo systemctl daemon-reload sudo systemctl enable --now dst-master dst-caves sudo systemctl status dst-masterRestarton-failure配合RestartSec15是为了避免崩溃后疯狂重启把 CPU 打满。KillModemixed能保证停止服务时把子进程一起带走不然会留一堆僵尸进程占着端口。6.2 定时更新版本不匹配的锅全在这饥荒的官方更新挺频繁而且服务器不更新客户端更新了两边就连不上玩家会看到版本不匹配的提示。这是长期服最烦人的问题解决办法就是定时自动更新。更新脚本/home/steam/update_dst.sh#!/bin/bash set -e /home/steam/steamcmd/steamcmd.sh \ force_install_dir /home/steam/dst \ login anonymous \ app_update 343050 validate \ quit给执行权限后配 crontab每天凌晨跑一次chmod x /home/steam/update_dst.sh crontab -e # 加入这一行 0 5 * * * /home/steam/update_dst.sh /home/steam/update.log 21更新的正确顺序是先停服 → 更新 → 再启动。热更新正在运行的服务端大概率会让存档处于一个不一致的状态。更稳妥的做法是让脚本自己去停服务、更新、再拉起并且更新前先复制一份存档备份。6.3 日志里最常见的六类报错我把这些年遇到的报错整理成一张表看到这类关键词可以直接对号入座日志关键词根因处理方式libcurl-gnutls.so.4: cannot open32 位库缺失或名字不匹配装 i386 包或做软链接Steam initialization failed网络出口不通或时间偏差过大检查出网、timedatectl校准时间Failed to bind to port端口被占用或配置冲突ss -tunlp找占用进程检查两个分片端口是否撞了Server is out of date服务端没跟着官方更新跑一次 app_update 343050ku_token相关鉴权失败令牌无效或已失效重新生成cluster_token.txt洞穴分片不断重试连接Master 未就绪或master_port不一致先起 Master 等生成完再起 Caves看日志有两个入口systemd 起的用journalctl -u dst-master -f直接跑的看~/.klei/DoNotStarveTogether/Cluster_1/Master/server_log.txt。关服一定要用c_shutdown()或者systemctl stop千万别kill -9直接强杀有很大概率让存档最后一帧写不完整轻则回档重则损坏。7. 开服之后的运维日常7.1 备份、快照和回滚三件事分清楚这三个概念经常被混着说我按实际用到的顺序讲。系统快照是云平台层面的整机备份恢复慢但能救回一切包括系统配置。我的习惯是每次大改配置之前先在控制台打一个快照改坏了直接回滚整机。存档备份是复制~/.klei/DoNotStarveTogether/Cluster_1/整个目录这是日常用得最多的。配一条定时任务每天打一个带日期的压缩包tar czf /home/steam/backup/dst-$(date %Y%m%d).tar.gz \ -C /home/steam/.klei/DoNotStarveTogether Cluster_1再加一条删除 14 天前旧备份的命令避免把盘塞满。游戏内回滚靠max_snapshots是服务器自己保存的阶段性快照。发现有人把基地点了或者存档出问题进控制台执行c_rollback(1)回退一步c_rollback(3)回退三步。回滚会让所有在线玩家掉线所以先c_announce通知一下。7.2 卡顿定位先分清是网络问题还是模拟问题服务器好卡这句话信息量几乎为零得分清是哪一类处理方式完全不一样。网络型卡顿的表现是所有人同时感觉延迟高、走路回弹、物品延迟掉地上但游戏里的模拟本身是流畅的。排查方法是让玩家在游戏里看右下角的延迟数值如果所有人同时飙高就是网络或者服务器上行的问题。检查点ss -tunlp看连接数、iftop看实时带宽、确认没有别的进程在抢带宽。模拟型卡顿的表现是延迟数值正常但画面像幻灯片、生物动作一顿一顿。这是服务端 tick 跟不上根子在实体太多或者单核太弱。用htop看专用服进程的 CPU 占用如果长期贴着 100%那就是它算不过来。应对办法是清理地图上堆积的物品大量掉落物不捡是最大的性能杀手、关掉一些实体密集的模组、或者换更高频的机器。提示htop里按F6可以按 CPU 排序一眼就能看出是不是某一颗核心被跑满了。饥荒专用服通常占用 100% 到 130% 之间一颗核跑满加一点辅助线程如果你的机器整体负载很低但游戏还是卡那基本可以确定是模拟问题而不是机器不够。7.3 换机器迁移的完整流程服务器到期或者想升级配置的时候迁移本身不难难的是别把存档搞坏。我的标准流程是这样旧机器上停服sudo systemctl stop dst-master dst-caves等进程完全退出用ps -ef | grep dontstarve确认没有了。打包两份数据Cluster_1整个目录以及程序目录下的mods/dedicated_server_mods_setup.lua。模组文件本身不用带走新机器会重新下载但配置要带。新机器上按第 2、3 章重做环境装 32 位库、装 SteamCMD、下载 343050。这一步不要省直接拷贝旧机器的 SteamCMD 目录过去容易因为路径硬编码出问题。恢复配置和存档把Cluster_1放到~/.klei/DoNotStarveTogether/下注意目录权限要是 steam 用户的。先手动起一次用命令行手动启动两个分片确认能正常加载存档、日志里没有报错再切到 systemd。改安全组新机器的公网 IP 变了如果是靠 IP 直连的老玩家得重新发一次地址。有一点要提醒cluster_token.txt是可以跟着走的不用重新生成。但如果旧机器还在跑两台机器同时用同一个令牌上线可能出现互相顶掉的情况所以迁移时务必先停掉旧机器。从我自己这几次折腾的经验看真正省时间的做法不是把步骤背下来而是把每一步的验证方法记下来。配置改完立刻确认世界生成成功、模组下载成功、端口能连通问题在什么阶段冒出来就一目了然。等到一堆配置全改完再一起启动出了问题只能从头二分排查那才是最耗时间的情况。另外第一次搭的时候我建议先不开洞穴、不装模组把最简单的单世界跑通确认能正常进游戏之后再一层一层往上加这样每一步出的问题都好定位。
返回列表