MC服务器全自动化运维,崩服自动重启、自动备份等(基于Linux)
本篇教程由浅入深,基于Linux实现Java版MC服务器的各种自动化任务。Linux是绝大多数服务器的操作系统,无论你是用电商平台很火的有图形化界面的面板服,还是租的只带一个Linux os的VPS,亦或者是基于Linux内核的个人NAS以及旧电脑都适用
本文属于小白保姆级教程,写作风格力求细致,如您觉得冗长还请见谅
文章代码中出现的所有路径,都请根据你的实际情况,换成对应的路径,我下面将不再提醒
教程&&代码作者:Bilibili up ©️三葉Leaves
开篇–需求分析&&前置环境
需求分析
情形1:崩服重开
我的MC服务器会因为各种原因崩溃。最常见的就是一些玩家行为导致tick值越过设定的预警(这个值在服务器的server.properties
文件里可以设置),然后watchdog自动关闭了服务器。每到此时,粉丝群便炸开了锅,需要我重新开服,而我的电脑不会总是在身边。
情形2:自动备份
一些玩家的误操作或者恶意为之,摧毁了大家心爱的小镇。此时需要回档,然而每天备份十几个G的存档是件麻烦事
情形3:自动游戏公屏推送消息
大家已经建立了聚居的小城镇的位置,亦或者是老玩家已经熟知的地狱交通位置,而刚入服的新玩家不知道,尽管自主探索找到大家是个很惊喜的事情,但是若能给每个刚入服的玩家自动公屏推送一下常用坐标和欢迎消息,也是件美事
上述三种情形都是我开服过程中遇到的问题,事实上这并不难实现。
情形4:每天自动重启服务器
一旦一个MC服务器开久了总归是不太好的,会出很多莫名其妙的缓存带来的Bug(比如玩家死亡的时候要是恰好退出了服务器,地点将会持续渲染,随着时间推移越来越卡,所以每天重启一遍服务器。
前置环境
作者的环境:
- Linux(Ubuntu) os(部署在docker容器内)。docker集成在群晖(synology)NAS的DSM os里
- 已经部署好MC服务端并成功开服
关于终端命令远控
也许你用的是图形化界面的面板服,此时我下文说的这些命令会让你无从下手。这里我必须先说明,Linux是一个以终端命令为主的系统,大多数操作依赖于在终端(Terminal)中打命令实现
连接到终端的方式有很多,最常见的就是用ssh工具。你可以这样问你租的面板服客服:
“你们的服务器ssh怎么用?请给我ssh地址和sftp地址”
然后让他教你怎么用。最终的结果就是获得一个能打命令的界面,就像这样:
功能1:崩服自动重开
1.设定系统时区
计划任务和备份文件名都需要用到时间,所以有必要先同步一下
先查看自己的时间日期对不对
1 | date |
如果正确,那就可以跳过直接下一步了,否则可以参考下面的步骤
使用如下命令
1 | tzselect |
按照系统的提示逐一选择地区(这里假定你的时区为上海),完成后输入
1 | ln -fs /usr/share/zoneinfo/Asia/Shanghai /etc/localtime |
再次使用date
检查时间,理应已经自动同步完成
2.编写崩服自动重启脚本
编写脚本
在MC服务端文件目录下新建一个名为startMC.sh
的脚本文件:
1 | vim startMC.sh |
在里面编写命令如下(不会用vim编辑器的自行搜索)
1 |
|
给脚本赋权:
1 | chmod 755 startMC.sh |
在里面编写命令如下
1 |
|
这段命令会新建一个名为mc
的screen,同时在这个screen里运行刚才编写的开服脚本
使用screen的意义:
- mc开服后终端将只能打mc里的命令(如gamemode,op等),而我们需要继续用Linux的命令就用不了,所以需要把它放在screen里后台运行
- ssh终端被关闭后有时会导致mc服务进程也被关闭,用screen可以解决这个问题(也可以用nohup)
开服命令并自动开服
以后想开服时,使用如下命令启动刚才编写的脚本即可:
1 | bash BootScript.sh |
也可以设置开机启动开服,先给脚本赋权
1 | chmod 755 BootScript.sh |
接着,在crontab里设置一个特殊的条件任务。进入crontab
1 | crontab -e |
在里面添加内容如下
1 | @reboot bash /root/BootScript.sh |
这样做,以后每次Linux系统开机时就会自动开服,崩服也会自动重启了
值得一提的是,有时你会发现开机自动开服会失效,这是因为这边存在一个悖论:
我们使用了cron来开机自启动开服脚本,但cron服务本身开机就没有被启动,那么自然开服脚本也不会被启动了
此时可以自行搜索如何设置你的系统开机自启动cron service,或者参考其他开机启动脚本的方式,这里推荐一篇教程:linux设置开机启动脚本的3种方法_linux开机启动脚本-CSDN博客
部分情况,你会遇到如下的报错
1 | System has not been booted with systemd as init system (PID 1). Can't operate. |
你会发现你的系统的systemd似乎有问题,这种多半发生在你使用了Docker或者WSL时出现,因为出于各种原因,你用的是阉割版的Linux。我尝试过很多种方法,至今未解决Docker中systemd的问题,如果你知道欢迎评论区指正。此时很遗憾,这种情况下没法做到开机自动开服
关服命令
值得一提的是,由于开服指令不间断执行,在你真正想要关服时,常规的游戏里使用/stop
命令是没用的,我们只能关闭screen来彻底关服
当你在MC的命令界面时,使用快捷键可以彻底关服
1 | Ctrl+A,K |
或者当你在终端界面时,
先获取已经运行的screen
1 | screen -ls |
如果你使用了我刚才编写的脚本,那么你会看到一个名为mc的screen,记住前面的数字id,使用命令
1 | screen -X -S 刚才记下的id quit |
同样也能关服
功能2:自动备份
先说我的备份需求:
- 每天的早上6点备份一次,这是为了在发生意外时(比如某位玩家的家不小心炸了)能及时回档到一天前的状态
- 每天备份的同时删除昨天的备份。这是为了节省磁盘空间,因为玩到后期存档动辄就是几十个G
- 每两周的周一保留一次备份而不删除。这是因为每隔两周存档都已经经过了比较大的变化和发展,这样做可以保留一些关键节点的回忆
- 扩展功能:远程备份。将存档备份到另一台机子上,这样即便本机出问题了另一台机子也有存档,亦或者是本机磁盘容量不够了,需要把存档直接备份到另一台机子。
功能实现(每天的备份与清理):
为了解决硬编码问题,我们在Minecraft游戏目录自带的config里创建一个.conf配置文件,用于存放我们备份存档的目录
1 | vim config/backup.conf |
在其中编写你希望存放存档备份文件的位置、备份日志的位置以及游戏存档目录(根据实际情况修改里面的路径)。这里我多设置了几个远程主机的配置,因为有可能你希望把存档备份到别的机子上(似乎这样才更合理一点)。如果你只需要备份到本机,那么可以忽视
1 | # 备份文件名,如(三葉的服务器存档#1.20.1-fabric) |
给配置文件赋权
1 | chmod 755 backup.conf |
接着开始编写我们的备份脚本吧!
创建backup.sh
1 | vim backup.sh |
脚本内容如下
1 |
|
运行这个脚本时会:
- 压缩游戏的存档为.zip并且命名为当天的日期,然后放到你刚才设置的存放位置
- 删除昨天备份的存档
- 无论备份成功与否,都输出日志信息到刚才你设置的日志位置
给脚本赋权
1 | chmod 755 backup.sh |
将这个脚本添加入计划任务,每天早上六点执行一次即可:
进入计划任务文件
1 | crontab -e |
添加如下内容
1 | 0 6 * * * /path/to/your/backup.sh |
功能实现(每两周保留一次存档):
刚才的步骤中已经实现了每日的备份和清理已备份的存档,但是我们还需要每两周的周一保留一次备份而不删除。
说实话,“每两周的周一”这个逻辑还真不太好编程,作者苦思冥想了几天始终没有很满意的方案,偶然之间意识到奇偶之间不是正好错位相隔吗,很吻合每两周这个逻辑!!这样编程真是十分讨巧,那么代码就来了
创建每两周备份一次的脚本
1 | vim longTermBackup.sh |
脚本内容如下:
1 |
|
接下来就只需要设置每周一运行一次这个脚本即可,如果脚本检测到当前不是偶数周,则不会触发备份
给脚本赋权
1 | chmod 755 longTermBackup.sh |
进入计划任务文件
1 | crontab -e |
添加如下内容
1 | 0 4 * * 1 /path/to/your/longTermBackup.sh |
到这里,已经完美实现了预期的所有备份要求
功能实现(远端备份)
不光能从Linux服务器备份到Windows主机上,反正也行,总之哪里空间大你就传哪(别告诉我你想传百度网盘,此时自己搭设云盘网络存储比如WebDAV的好处就体现出来了)
配置ssh密钥对
我使用rsync
实现远端备份的需求,因为这个技术支持增量同步,很符合MC存档大但是每天的数据变化不太大这种场景。rsync
使用了ssh的端口,每次使用时都需认证,因此为了实现自动化脚本,最佳实践是配置ssh的密钥对而不是使用密码进行ssh连接。具体配置方法可以看我这篇教程:
如何通过 SSH 使用 RSA 密钥对登录主机?
rsync命令
备份到另一台机子的同时,从源位置删除已备份好的文件(为了节省源主机的空间)
1 | rsync -avz --remove-source-files -e "ssh -p 40022" /volume1/叶子的分享/MC资源/三葉的服务器存档/ leaves@192.168.2.248:/volume1/docker/alist/Leaves的空间/MC资源/存档/ |
40022
为我自定义的ssh端口号,替换成你的(默认是22)/volume1/叶子的分享/MC资源/三葉的服务器存档/
是我的MC存档的源路径,替换成你的leaves
是我在目标服务器上的用户名,替换成你的192.168.2.248
是目标主机的IP,根据实际情况替换/volume1/docker/alist/Leaves的空间/MC资源/存档
是对方主机上的目标备份位置,替换成你自己的
双端都保留存档文件
如果你磁盘空间够用,需要双端都保留存档文件,那你可以删去--remove-source-files
选项,如下:
1 | rsync -avz -e "ssh -p 40022" /volume1/叶子的分享/MC资源/三葉的服务器存档/ leaves@192.168.2.248:/volume1/docker/alist/Leaves的空间/MC资源/存档/ |
这样做就是单纯的同步啦
目标主机的磁盘空间也要节省?
咱们机子上有删除昨天备份的逻辑,但是对方没有哇!为了避免时间一久目标机子上的存档堆积成山,你可以加一个--delete
选项
1 | rsync -avz -e --delete "ssh -p 40022" /volume1/叶子的分享/MC资源/三葉的服务器存档/ leaves@192.168.2.248:/volume1/docker/alist/Leaves的空间/MC资源/存档/ |
这样会从目标主机删除本机没有的文件,简单来说就是真正的双端同步
添加至计划任务
打开计划列表:
1 | crontab -e |
添加如下条目(命令部分替换成你自己的)
1 | 0 4 * * * rsync -avz -e "ssh -p 40022" /volume1/叶子的分享/MC资源/三葉的服务器存档/ leaves@192.168.2.248:/volume1/docker/alist/Leaves的空间/MC资源/ |
以后每天凌晨四点就会自动同步啦
功能3:欢迎消息
“如果我看得更远,那是因为我站在巨人的肩膀上” –艾萨克·牛顿
欢迎消息的代码大概包括以下逻辑:
抓取screen里的MC控制台消息,然后用正则表达式匹配内容,最后推送需要的欢迎消息到控制台公屏
然而一个合格的程序员不应该只是埋头苦干,还应该懂得借鉴(真不是因为我懒=v=),这种常用的功能前辈们肯定已经把项目封装好了,果然,网上找到了个名为Welcome Message的模组,恰好满足我的简单的欢迎消息需求,既然如此,以逸待劳
模组下载地址:Welcome Message - Minecraft Mod (modrinth.com)
使用方法也很简单,模组装载到服务端后重启游戏,然后在服务端游戏目录的config里找到welcomemessage.json5,编辑即可
1 | vim welcomemessage.json5 |
配置字段作者注释也写的很清楚了,这里不赘述。编辑好以后重启游戏即可
功能4:定时重启
这个实现起来是最简单的
如果你用docker+screen
在宿主机里先往docker容器里写命令,再从容器向screen里写命令,这真的挺套娃
1 | docker exec -it ubuntuMC1.20.1 screen -S minecraft -X stuff 'stop^M' |
- 容器名:使用
docker ps
查看你运行MC的容器的名称,这里假设是ubuntuMC1.20.1
。 - screen名:使用
docker attach 容器名
后使用screen -ls
查看MC所在screen的名称,这里假设是minecraft
。
完事以后,把这条命令添加到crontab,设定每天凌晨3点执行个一次就行
如果你只用了screen
1 | screen -S minecraft -X stuff 'stop^M' |
- screen名:使用
screen -ls
查看MC所在screen的名称,这里假设是minecraft
。
完事以后,把这条命令添加到crontab,设定每天凌晨3点执行个一次就行
- 标题: MC服务器全自动化运维,崩服自动重启、自动备份等(基于Linux)
- 作者: 三葉Leaves
- 创建于 : 2024-09-25 00:00:00
- 更新于 : 2024-11-21 10:12:57
- 链接: https://leavesblog.netlify.app/138eecc6736b/
- 版权声明: 本文章采用 CC BY-NC-SA 4.0 进行许可。