12コメント

【Linux Ubuntu】Spigot鯖を自動再起動させる【Minecraft】

2022/01/10追記
このスクリプトは作りが甘いです。最低限の作りだし、少し前の記事なのでこちらの方が参考になるかもしれません。


こにゃにゃちわ=^_^=

昔々・・・

いや最近・・・

ウィルスにサーバーが破壊されたというのは記憶に新しい

そんでマイクラのワールドのサルベージにも成功し、サーバーは純正鯖からspigot鯖に変更したものの、被害があったってのは事実。

それは何かって、シェルスクリプト全損。

シェルスクリプト全部暗号化されてたのね。それもあってアドオンが使えるspigot鯖に移動したってのもあるんだが・・・

それでもしばらく使ってみて、アドオンじゃ補えない、シェルスクリプトだから出来る事ってのはある。


というわけで、作り直そう!!!!!!!

課題

ではまず課題。の前置き。
そもそも再起動させないと何が起きるのか。

今まで数日間連続で実際に稼働させてみると、メモリがたまりにたまりまくって、クラッシュしたりクソ重くなったりでまあ、身をもって再起動の大切さってのが分かりましたねハイ()

では本題

SimpleRestartというBukkit系鯖に使用できるアドオンが存在するのは既知の通り。
だが、なぜか動作しない
スクリーンショット 2020-11-24 010324.png
JavaScriptで書かれてるのか?そこらへん全くの無知なのだが、オンラインプレイヤーが存在しないと値を取得できずエラーで実行されない、てな感じっぽい。
あとこのアドオン、reloadコマンドを使うとカウントがリセットされてしまう。
再起動機能は、搭載しないとメモリが解放できずクラッシュしてしまう問題があるのでそれは避けなければならない。

じゃあどうするか

今まで、アドオンを使わずに対処してきた方法
 -それはLinuxで実装されているシェルスクリプト。

今まで使ってきたじゃあないか!

という訳で、やっていきます。

サーバーのscreen稼働化

その前にサーバーをscreenで動作させます。プロセス名で取得するのも面倒臭いので、あらかじめscreenで名前を付けて仮想端末として実行させておくことで、コンソールにも干渉しやすくします。

・・・建前。
本音は多分プロセスに直接干渉できなくはないんだろうけど、今までscreen制御でやってきたので、今まで通りの方法をとります。

java -Xms12G -Xmx12G -jar spigot-1.16.4.jar nogui

今までこれを書いたシェルスクリプトを実行させるだけでそれ以外シェルスクリプトで干渉している部分は無かったのですが、干渉できるように実装します。

sudo apt install screen

でインストールします。

今まで書いていたシェルスクリプトの文をこっちに置き換える。

screen -AdmSU minecraft java -Xms12G -Xmx12G -jar spigot-1.16.4.jar nogui
オプション
-A 端末サイズがどうこう?みんなこれ使ってるっぽいから便乗()
-dm デタッチモードで起動する(サーバーコンソールが表示されない)
-S セッション名(スクリーン名)を付与する
-U UTF-8を理解する(意味があるのかは不明)

minecraftというスクリーンを作ってjavaコマンドを実行させるわけだね。

-Xms -Xmxは例によってメモリ割り当て容量の設定。

シェルスクリプトを書く

やっていこ~う

といっても、今回は定期的に実行することで再起動通知をして、stopコマンドを実行して、少し間を明けてスタートスクリプトを実行するっていう、それだけなんだけどね!!!

では記述
スクリーンショット 2020-11-24 184804.png

難しいことは何もありません。
#!/usr/bin/bash
SCREEN_NAME="minecraft"
START="./start.sh"
screen -p 0 -S ${SCREEN_NAME} -X eval 'stuff "say サーバーをあと30秒後に再起動します。 \015"'
sleep 25
screen -p 0 -S ${SCREEN_NAME} -X eval 'stuff "say サーバー再起動まで残り5秒・・・ \015"'
sleep 1
screen -p 0 -S ${SCREEN_NAME} -X eval 'stuff "say サーバー再起動まで残り4秒・・・ \015"'
sleep 1
screen -p 0 -S ${SCREEN_NAME} -X eval 'stuff "say サーバー再起動まで残り3秒・・・ \015"'
sleep 1
screen -p 0 -S ${SCREEN_NAME} -X eval 'stuff "say サーバー再起動まで残り2秒・・・ \015"'
sleep 1
screen -p 0 -S ${SCREEN_NAME} -X eval 'stuff "say サーバー再起動まで残り1秒・・・ \015"'
sleep 1
screen -p 0 -S ${SCREEN_NAME} -X eval 'stuff "kick @a サーバー再起動。一分ほどして接続し直してください。 \015"'
sleep 1
screen -p 0 -S ${SCREEN_NAME} -X eval 'stuff "stop \015"'
sleep 7
${START}
上二つのSCREEN_NAMEとSTARTは変数で、まあスクリーン名を変えてしまっても対応できるようにって感じ。まあ特に関係ないんすけど。

screen -p 0 -S ${SCREEN_NAME} -X eval 'stuff "say サーバーをあと30秒後に再起動します。 \015"'
これがチャット伝達部分
コンソールに「say サーバーをあと30秒後に再起動します。 \015」と入力してしまうわけ何ですね。
\015は特殊記号で、エンターキーを打鍵したことを意味します。C言語で言う「\n(改行)」って奴ですね。

sleepは秒数単位で待機命令を出すコマンド。
で最終的にマイクラで@a、全指定でkickコマンドを実行しstopコマンドを実行します。
kick挟むとメッセージが表示出来るからって、それだけの理由ですけど。

うおおお!!文ごっちゃぐちゃ書かれてもわかんねえええ!!!

という訳で実行結果↓

スクリーンショット 2020-11-24 184634.pngスクリーンショット 2020-11-24 184647.png

ではこれを定期的に実行(一時間毎)させて、自動で再起動しメモリを解放させるようにしませう。

crontabで設定する

crontab ってDebian系Linuxだとデフォルトで搭載されているのかな?おそらくインストール不要だと思いますが
sudo apt install cron で出来たはずなので念のため書いておく

そしたら
crontab -e
を実行

スクリーンショット 2020-11-24 200323.png

こんな感じで開く。基本は白紙・・・じゃないか、#コメントで英文が大量に書いてあった気がする。そちらはすべて削除しておけ~

で@reboot ファイルパス って記述されているのは分かると思いますが。

これは、パソコン起動時にスクリプトを実行するという項目。で、スタートスクリプトを実行しているわけですね。それだけ


スクリーンショット 2020-11-24 201013.png

こんな感じで追記。
分 時 日 月 曜日 シェルスクリプトファイルパス

という方式で記述。

アスタリスク記号は毎数を指します。

0 * * * *は毎週毎月毎日毎時0分の時実行する、実質一時間おきに実行するという意味なんですね。

この設定をすることで毎時0分になったとき、再起動スクリプトを自動で実行してくれるわけですね。わあ便利



いかがだったでしょうか。シェルスクリプトはアドオンとは別のメリットデメリットがあるので、使い分けると便利っぽいですね。

前に書いた記事もあるんですけど、

スクリーンショット 2020-11-24 202246.png
こんな感じでlatest.logファイルにチャットログが出力されるので活用出来る部分は最大限使って行きませう!

('ω')ノシ
0

この記事へのコメント

  • kokuma

    screenで起動する というところで詰まっています。
    途中までは実行されるのですが、突然止まり、 screen is terminating と表示されてしまいます。
    2021年12月25日 18:31
  • kokuma

    先程の者です。
    時間をおいたらなぜか起動できました
    2021年12月25日 22:52
  • kokuma

    restart.shを手動で起動すると再起動できるのですが、cronで起動するとサーバーが閉じはするのですが、再び起動しません。
    エラーログもないのでどうすればいいか分からない状況です。
    考えられる原因などを教えて下さい。
    2021年12月25日 23:03
  • 猫山さん。

    起動するjarファイルのパスにcronで実行されたスクリプトからアクセス出来ていないかもしれません。どっかのファイルにパスを文字列として出力して確認してみるといいかもしれません。別要因の可能性は全然あるので参考にならないかもですが…

    > kokumaさん
    >
    > restart.shを手動で起動すると再起動できるのですが、cronで起動するとサーバーが閉じはするのですが、再び起動しません。
    > エラーログもないのでどうすればいいか分からない状況です。
    > 考えられる原因などを教えて下さい。
    2021年12月26日 02:55
  • 猫山さん。

    画像が見れないですね
    Discordか何かでやり取り出来ませんか?

    > kokumaさん
    >
    > >猫山さん。
    > https://imgur.com/gallery/f1WDFOp
    > こんな感じなんですけど、、、
    2021年12月26日 11:52
  • kokuma

    >猫山さん。
    Discord:Hexanitrohexaazaisowurtzitane #0759 です。
    よろしくおねがいします。
    2021年12月26日 11:56
  • ミネムラ

    この記事を参考にさせていただき、Ubuntu Server上でサーバーが自動再起動するようにしてみました。私の場合サーバー起動用スクリプトとしてactivate.sh、再起動用スクリプトとしてreboot.shを用意しました。スクリプトの中身は全く同じです。
    ./reboot.shと手入力した場合はサーバーが正常に再起動するのですがcrontabから実行した場合は、アナウンスは正常に実行されサーバーも終了するものの、サーバーが起動しないという状態です。
    原因としてどのようなことが考えられるでしょうか。
    2022年03月19日 10:28
  • 猫山さん。



    >ミネムラさん
    コメントありがとうございます。
    crontabは性質上、crontabのディレクトリでスクリプトを実行します。
    crontabに設定した時にフルパスでスクリプトを指定して実行しているのですが、crontabのディレクトリで実行されたreboot.shが「./activate.sh」を実行しても、カレントディレクトリ(crontabのディレクトリ、./指定)にactivate.shは存在しないため実行できていない物だと思います。私も悩んで同じ問題が起きました。
    解決策としては、activate.shをフルパスで指定して実行する、activate.shが存在するディレクトリに移動(cd)してから実行すると大丈夫だと思います。
    また、全く別の方法ですけど
    https://nekoy3.net/2022/02/16/docker-spigot/
    こういった方法もありますので、ある程度ゆとりが出来たらお試しください。
    2022年03月27日 04:30
  • ミネムラ

    >猫山さん
    返信いただきありがとうございます。
    crontab内でのreboot.sh、activate.sh内のserver.jarの指定、reboot.sh内のactivate.shの指定すべてをフルパスで行ってみたのですが、crontabからではサーバーが起動できませんでした。。。
    色々調べてみて、無理そうだったらご教授いただいた方法を試してみたいと思います!
    2022年04月02日 22:23
  • 猫山さん。

    ちなみに1行目には#!/bin/bashではなく#! /bin/shにしていたり、chmodで権限をファイルに与えていなかったりしませんか?
    別プラットフォームでやりとり(Discord等)が出来るのであればスクショとか使ってやりとり出来ますよ

    > ミネムラさん
    >
    > >猫山さん
    > 返信いただきありがとうございます。
    > crontab内でのreboot.sh、activate.sh内のserver.jarの指定、reboot.sh内のactivate.shの指定すべてをフルパスで行ってみたのですが、crontabからではサーバーが起動できませんでした。。。
    > 色々調べてみて、無理そうだったらご教授いただいた方法を試してみたいと思います!
    2022年04月02日 22:32
  • ミネムラ

    Discordでやり取りさせていただければありがたいですm(_ _)m
    しげる#9938です。
    2022年04月02日 23:02