一颗丁子
本帖最后由 一颗丁子 于 2021-12-4 09:36 编辑

前言

如你所见,这是一篇关于自动重启启动脚本的教程。

先说明一下教程环境: Linux系统
                                 Windows系统可以左转 这一篇文章

你的服务器可能会没事崩溃一下,总是需要手动重新启动),又或者是需要在每天指定的时间重启以降低内存消耗。
假如你遇到了这种情况,那么这篇教程十分适合你。

那么让我们开始吧!



首先,大家都知道的是,服务器自带的重启指令是:
  1. /restart
复制代码
但使用过的朋友都知道,这条指令只能帮你关闭服务器,却没法打开它。

在这个指令运行时,她所做的是:
1. 先关闭服务器
2. 尝试运行启动脚本

那么,自动重启这一需求就可以转变成两个问题:
1. 如何定时执行 /restart
2. 如何让启动脚本把关掉的服务器再打开

让我们一个个解决。

一:定时执行/restart指令

你可以通过插件做到这一点,这里举两个例子:

1. 使用 CMI基础插件 自带的 schedule.yml 定时执行指令/restart
具体配置是这样的:
  1. autoRestart:
  2.   Enabled: true
  3.   # 每两次触发之间间隔多长时间?
  4.   Delay: 600
  5.   # 延时循环触发
  6.   Repeat: false
  7.   # 如果延时循环触发禁用,那么在固定的时间点执行重启
  8.   # 下面这个代表每天的19点05分30秒重启,时间请使用24小时制
  9.   # 可用的时间项:Month Day Hour Minute Second
  10.   PerformOn:
  11.     1:
  12.       Hour: 19
  13.       Minute: 05
  14.       Second: 30
  15.   # 玩家最少不得少于此数量才自动重启
  16.   MinPlayers: 1
  17.   # 玩家最多不得多于此数量才自动重启
  18.   MaxPlayers: 10
  19.   # 如果该设置项为true,那么将在触发的多条指令里随机抽取一条触发,适合做抽奖
  20.   Randomize: false
  21.   # 触发的控制台指令
  22.   # save-all是储存玩家数据,防止重启后回档
  23.   Commands:
  24.   - save-all
  25.   - restart
复制代码
按照你的需求修改后直接写入 schedule.yml 即可,或者对照这里编辑文件,直接复制可能会有格式问题。

2. 使用单独的插件 UltimateAutoRestart 来执行指令。
简单介绍一下这个插件:
这是一个为自动重启设计的插件,可以在指定的时间执行你指定的指令,还自带Boardcast、Actionbar、Title的重启提示,且所有语言文件都可以汉化。
版本覆盖面也比较大(1.18-1.8),功能也很齐全,性能也较高,是个不错的插件。
这个插件的配置比较简单,这里不多赘述了。

二:让启动脚本打开关掉的服务器

这里简单粗暴一下,直接先贴出我的启动脚本,再解释用法。
  1. #!/bin/sh
  2. while true
  3. do
  4. a=$(cat control)
  5. if [ $a -eq 1 ]
  6. then
  7.   sleep 30s
  8.   java -server -XincGC -Xmx8G -Xms8G -XX:+AggressiveOpts -XX:+UseCompressedOops -XX:+UseCMSCompactAtFullCollection -XX:+UseFastAccessorMethods -XX:ParallelGCThreads=2 -XX:+UseConcMarkSweepGC -XX:CMSFullGCsBeforeCompaction=2 -XX:CMSInitiatingOccupancyFraction=70 -XX:-DisableExplicitGC -XX:TargetSurvivorRatio=90 -jar paper-1.16.5-642.jar
  9. #上面java开头的一大坨是我用的启动命令,请换成你自己的,否则无法使用
  10. else
  11.   echo "已停止自动重启"
  12.   exit
  13. fi
  14. done
复制代码
打开你服务端目录下的 spigot.yml 文件,看到
  1. restart-script: ./start.sh
复制代码
这一项设置,她代表你服务器的默认启动脚本应该在一级目录内(跟spigot.yml文件在一个地方),且文件名为 start.sh
照她说的,我们在目录下新建一个start.sh文件,将上面那一段启动脚本复制进去,然后在控制台执行
  1. ed -i 's/\r$//' start.sh
复制代码
或(来自#6的补充)
  1. sed -i 's/\r$//' start.sh
复制代码
命令,作用为删除Windows系统换行多余的符号。

接着解释一下这个启动脚本:
当脚本被运行时,检测一个叫 control 的文件中的内容,如果内容是 1 ,则执行启动命令来重新打开服务器,否则输出 已停止自动重启 到控制台并停止执行脚本。
比起传统无限循环重启脚本,这样的脚本可控性更强,在需要关服时更加方便,避免想关服关不掉的局面出现。
我还写了一个 sleep 30s ,代表延迟三十秒再开启服务器。因为假如不设置延迟,服务器开启进程可能与关闭进程冲突,造成无限重启。当然30秒确实有点长,5到10秒就够用了。

那么,我们在与刚刚一样的目录下新建一个 control 文件(注意没有后缀),在里面输入 1 这个数字,然后保存文件并关闭。

现在,你的自动重启就已经配置好了。

让我们测试一下使用是否正常:

假如你安装了上面说到的 UltimateAutoRestart 插件,那么你可以在后台执行
  1. ar now 10
复制代码
这一命令(十秒后重启服务器)。
然后观察服务器是否正常关闭,再开启。

接着把 control 中的数字 1 删掉,改成 0 之类的。
然后再执行一次:
  1. ar now 10
复制代码
之后观察是否正常输出了 已停止自动重启 字样。

假如一切正常,恭喜你,你已经配置好了自动重启
现在,你的服务器又多了一份安全保障


后记
简单的小教程) 第一次在这个版发文章,有点小紧张,大家多多包涵) 废话比较多的话我紫菜。

很重要的说明:
—本贴为本人原创,如有雷同纯属巧合;
—不得盗用本贴内容。转载本贴请注明作者一颗丁子,否则视为盗用;
—B站有一篇内容相似的教程,这也是我发的

那么之后再见了,肯定还会发教程的)掰掰
ヾ(•ω•`)o

wmw1939103823
看着不错,已收藏

zzw1111
不错,很好用

Lidocaine
难得有sh实例
兹磁大佬!

yuhao5018
然而并不行

root@hecs-x-large-2-linux-20210302154353:/home/1165# ed -i 's/\r$//' start.sh
ed: invalid option -- i
Try 'ed --help' for more information.
root@hecs-x-large-2-linux-20210302154353:/home/1165# sh start.sh
start.sh: 14: start.sh: Syntax error: "done" unexpected (expecting "then")
root@hecs-x-large-2-linux-20210302154353:/home/1165#

poikcue
一些问题:
如果ed -i不能用,请换成以下命令:
  1. sed -i 's/\r$//' start.sh
复制代码

在服务器启动完毕后,输入stop,观察一下会不会重新开启。如果是的话,那么不需要restart,只需要输入stop

a1760071990
这么多都是linux系统。。

结冰的离季
崩服或者ctrl+c能自动重启么

Lsmmy_
非常感谢大佬的分享,受益匪浅

Jstzjgsc
不好意思求助一下大佬
我用start.sh启动后,出现了如下代码
[23:13:28 FATAL]: Failed to start the minecraft server
net.minecraft.util.SessionLock$ExceptionWorldConflict: /root/./Eremus_Duri/session.lock: already locked (possibly by other Minecraft instance?)
        at net.minecraft.util.DirectoryLock$LockException.alreadyLocked(DirectoryLock.java:98) ~[app:?]
        at net.minecraft.util.DirectoryLock.create(DirectoryLock.java:44) ~[app:?]
        at net.minecraft.world.level.storage.LevelStorageSource$LevelStorageAccess.<init>(LevelStorageSource.java:338) ~[app:?]
        at net.minecraft.world.level.storage.LevelStorageSource.createAccess(LevelStorageSource.java:308) ~[app:?]
        at net.minecraft.server.Main.main(Main.java:151) ~[patched_1.17.1.jar:git-Paper-408]
        at org.bukkit.craftbukkit.Main.main(Main.java:293) ~[patched_1.17.1.jar:git-Paper-408]
        at jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:?]
        at jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:78) ~[?:?]
        at jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:?]
        at java.lang.reflect.Method.invoke(Method.java:567) ~[?:?]
        at io.papermc.paperclip.Paperclip.main(Paperclip.java:49) ~[paper-1.17.1-408.jar:?]
并不断循环重启,请问这该怎么办?
谢谢

一颗丁子
Jstzjgsc 发表于 2022-1-15 23:15
不好意思求助一下大佬
我用start.sh启动后,出现了如下代码
[23:13:28 FATAL]: Failed to start the minecra ...

sleep时间调长一点? 这是还没完全关闭 关闭进程还在进行

Jstzjgsc
一颗丁子 发表于 2022-1-15 16:16
sleep时间调长一点? 这是还没完全关闭 关闭进程还在进行

我查了一下,然后发现是session被锁定了.
我删除了session.lock文件,于是加载又能推进一点点了,但是又显示:
[23:33:21 WARN]: **** FAILED TO BIND TO PORT!
[23:33:21 WARN]: The exception was: io.netty.channel.unix.Errors$NativeIoException: bind(..) failed: Address already in use
[23:33:21 WARN]: Perhaps a server is already running on that port?
然后继续不断"重启-失败-重启"的循环

一颗丁子
Jstzjgsc 发表于 2022-1-15 23:37
我查了一下,然后发现是session被锁定了.
我删除了session.lock文件,于是加载又能推进一点点了,但是又显示 ...

是啊 意思就是你的机器上还有一个服正在占用端口
是不是用的Screen 崩过一次服 然后重启发现这个问题 崩服是不能正常重启的 你得把整个机子都重启了
没崩过服也这样的话 那就是sleep短了
要是都不行 那我也没办法了

Jstzjgsc
一颗丁子 发表于 2022-1-15 16:40
是啊 意思就是你的机器上还有一个服正在占用端口
是不是用的Screen 崩过一次服 然后重启发现这个问题 崩服 ...

如何把整个机子重启?
到服务器商那边直接重启整个服务器吗

一颗丁子
Jstzjgsc 发表于 2022-1-15 23:43
如何把整个机子重启?
到服务器商那边直接重启整个服务器吗

按理来说reboot命令就是重启 在你后台输入就好了
当然你要是怕出问题也可以咨询一下服务商)

Jstzjgsc
一颗丁子 发表于 2022-1-15 16:45
按理来说reboot命令就是重启 在你后台输入就好了
当然你要是怕出问题也可以咨询一下服务商) ...

我直接到服务器商那边重启了一下,然后就搞定了
谢谢帮助!

未央鹿鸣
好家伙 终于找到需要的了

FZDNSZYT
作者你看看这个:> ./mc: line 2: $'\232\204,否则无法使用': command not found ./mc: line 3: syntax error near unexpected token `else' ./mc: line 3: `else'

第一页 上一页 下一页 最后一页