Linux云主机部署搭建minecraft服务器以及记录java内存溢出问题

好朋友找我玩minecraft,正好之前租了一台腾讯云学生主机,主机配置一般,不过感觉几个人玩minecraft应该还是能撑得住,果断搞起,回想当年一起联机的快乐,瞬间兴奋了起来
因为有一个好朋友在美利坚,所以我本来以为带宽会是一个大问题,事实证明带宽问题不大,内存问题很大… 本来玩的好好的,突然服务器说挂就挂,一查发现是Out of memory,搞得心态炸裂

本文简单记录一下搭建minecraft服务器和尝试解决内存溢出问题的过程

服务器配置:1核 2G内存 60GSSD 带宽6Mbps
操作系统:CentOS Linux release 7.6.1810
minecraft服务端核心:mojiang官方核心,没有使用任何mod和插件,版本1.17.1,目前最新版

(2023.03.08更新 目前minecraft最新版1.19.3,使用CentOS Linux release 8.2.2004 以下方法依然可用XD)

1. 先决条件

由于minecraft 1.17版本开始不能使用java8,必须使用java16+,这里直接安装java-latest
在这里插入图片描述
(1) Java
安装 jdk

yum -y install java-latest-openjdk*

检查jdk版本

java -version

在这里插入图片描述
(2) 安装构建mcrcon工具所需的软件包

sudo yum install git
sudo yum group install "Development Tools"

2. 创建系统用户

不建议直接使用root作为运行minecraft的用户
可创建一个没有设置密码,不能用SSH登录的系统用户minecraft,并设置 /opt/minecraft 为用户主目录。

sudo useradd -r -m -U -d /opt/minecraft -s /bin/bash minecraft

3. 安装minecraft服务端

(1) 切换到用户minecraft

sudo su - minecraft

(2) 在主目录创建三个新目录

mkdir -p ~/{backups,tools,server}

backups:存放备份数据
tools:存放工具,包含mcrcon客户端,同时可编写一些自定义脚本用于服务器管理
server:minecraft服务端目录,包含地图和用户数据

(3) 安装mcrcon客户端
从git仓库clone到本地并编译

cd ~/tools && git clone https://github.com/Tiiffi/mcrcon.git
cd ~/tools/mcrcon
gcc -std=gnu11 -pedantic -Wall -Wextra -O2 -s -o mcrcon mcrcon.c

测试是否编译成功

./mcrcon -h

输出像这样就是编译成功

Usage: mcrcon [OPTIONS]… [COMMANDS]…
Sends rcon commands to Minecraft server.

Option:
-h Print usage
-H Server address
-P Port (default is 25575)
-p Rcon password
-t Interactive terminal mode
-s Silent mode (do not print received packets)
-c Disable colors
-r Output raw packets (debugging and custom handling)
-v Output version information

Server address, port and password can be set using following environment variables:
MCRCON_HOST
MCRCON_PORT
MCRCON_PASS

Command-line options will override environment variables.
Rcon commands with arguments must be enclosed in quotes.

Example:
mcrcon -H my.minecraft.server -p password “say Server is restarting!” save-all stop

(4) 下载minecraft服务端
可在 minecraft官网 获取最新官方服务端下载链接

wget https://launcher.mojang.com/v1/objects/a16d67e5807f57fc4e550299cf20226194497dc2/server.jar -P ~/server

(4) 初次执行并配置服务器
第一次并不会运行minecraft程序,只是执行初始化

cd ~/server
java -Xmx1024M -Xms1024M -jar server.jar nogui

会显示

[main/ERROR]: Failed to load properties from file: server.properties
[main/WARN]: Failed to load eula.txt
[main/INFO]: You need to agree to the EULA in order to run the server. Go to eula.txt for more info.

表示需要同意协议并且设置server.properties配置文件。
打开eula.txt文件,然后将eula=false更改为eula=true即可

vim ~/server/eula.txt

eula=true

接下来按照需要编辑配置文件

vim ~/server/server.properties

Minecraft Wiki 上有详细介绍每个配置选项的含义,可自行按照需要配置。
这里为了使用rcon客户端,需要配置以下几个配置项

rcon.port=25575
rcon.password=此处填写你想要设置的rcon密码
enable-rcon=true

(5) 将minecraft设置为守护进程
在Systemd目录下添加一个minecraft.service

sudo vim /etc/systemd/system/minecraft.service

添加以下配置

[Unit]
Description=Minecraft Server
After=network.target

[Service]
User=minecraft
Nice=1
KillMode=none
SuccessExitStatus=0 1
ProtectHome=true
ProtectSystem=full
PrivateDevices=true
NoNewPrivileges=true
WorkingDirectory=/opt/minecraft/server
ExecStart=/usr/bin/java -XX:ErrorFile=/opt/minecraft/server/err/hs_err_%Y-%m-%d-%H:%M:%S.log -Xmx1024M -Xms1024M -jar server.jar nogui
ExecStop=/opt/minecraft/tools/mcrcon/mcrcon -H 127.0.0.1 -P 25575 -p 此处填写你设置的rcon密码 stop

[Install]
WantedBy=multi-user.target

启动配置中Xmx和Xms分别为给虚拟机分配的可用最大和最小堆空间,这个根据自己的主机配置按需设置即可。

更新配置并开启服务端

sudo systemctl daemon-reload
sudo systemctl start minecraft

查看守护进程状态

sudo systemctl status minecraft

● minecraft.service - Minecraft Server
Loaded: loaded (/etc/systemd/system/minecraft.service; enabled; vendor preset: disabled)
Active: active (running) since Fri 2021-08-20 21:03:03 CST; 1h 52min ago
Main PID: 7062 (java)
CGroup: /system.slice/minecraft.service
└─7062 /usr/bin/java -XX:ErrorFile=/opt/minecraft/server/err/hs_err_%Y-65e3e…

设置开机启动

sudo systemctl enable minecraft

记得设置防火墙,放通对应端口号的请求,默认端口号为25565,在server.properties中也可以自己改端口号

4. 设置每日备份

切换到minecraft用户

sudo su - minecraft

编写备份脚本

vim /opt/minecraft/tools/backup.sh
#!/bin/bash

function rcon {
  /opt/minecraft/tools/mcrcon/mcrcon -H 127.0.0.1 -P 25575 -p 此处填写你设置的rcon密码 "$1"
}

rcon "save-off"
rcon "save-all"
tar -cvpzf /opt/minecraft/backups/server-$(date +%F_%R).tar.gz /opt/minecraft/server
rcon "save-on"

## Delete older backups
find /opt/minecraft/backups/ -type f -mtime +7 -name '*.gz' -delete

添加执行权限

chmod +x /opt/minecraft/tools/backup.sh

创建定时任务

crontab -e

设置每日0点自动备份

0 0 * * * /opt/minecraft/tools/backup.sh

5. 解决内存溢出问题

难顶啊,玩着玩着进程就挂了,去看错误日志,看到一个Out of memory
在这里插入图片描述
果断百度解决办法,搜到几种优化方法:
更换虚拟机:我换了zulu,效果不好,还是会内存溢出
修改jvm启动参数:-XX:+AggressiveOpts -XX:+UseCompressedOops,效果也不好 这篇文章有说原因
减少server.properties中配置项view-distance:这个我改了之后内存占用好像是减少了一些,但是效果不明显

我又回去看了眼错误日志,人家好像告诉了我们可能的解决办法:
在这里插入图片描述
第二条增加物理内存或者swap空间,物理内存要加钱的,swap空间好像听说过但是不知道具体是啥,其实就是利用磁盘来充当内存,从而缓解内存不足的问题
用命令查看系统中已经配置的swap

swapon -s

输入命令显示我系统中没有配置好的swap分区或swap文件
果断添加swap文件

su
cd /var
dd if=/dev/zero of=swapfile bs=1M count=2048
mkswap swapfile
swapon swapfile
echo "/var/swapfile swap swap defaults 0 0" >> /etc/fstab

完成这番操作之后感觉没那么容易内存溢出了
但是为了保险起见,可以编写一个进程挂了自动重启的脚本
在这里插入图片描述
~/tools/auto_restart/work.sh

#!/bin/bash

# mutex file
#
# Open a mutual exclusion lock on the file, unless another process already owns one.
#
# If the file is already locked by another process, the operation fails.
# This function defines a lock on a file as having a file descriptor open to the file.
# This function uses FD 9 to open a lock on the file.  To release the lock, close FD 9:
# exec 9>&-
#
# From https://stackoverflow.com/questions/185451/quick-and-dirty-way-to-ensure-only-one-instance-of-a-shell-script-is-running-at
mutex() {
    local file=$1 pid pids 

    exec 9>>"$file"
    { pids=$(fuser -f "$file"); } 2>&- 9>&- 
    for pid in $pids; do
        [[ $pid = $$ ]] && continue

        exec 9>&- 
        return 1 # Locked by a pid.
    done 
}

# Check lock
mutex /opt/minecraft/tools/auto_restart/auto_restart.lock || { echo "auto_restart.sh already running." >&2; exit 1; }

# Restart server
while true;do
    if [ `ps -ef | grep server.jar | grep -v grep | wc -l` = 0 ];then
        source /opt/minecraft/tools/start_server.sh >&2
        echo [`date +%Y-%m-%d` `date +%H:%M:%S`]: restart server >&2
    fi
    sleep 5
done

脚本里参考stackoverflow上的大佬加了一把锁,防止这个脚本被执行多次同时产生多个实例。

~/tools/auto_restart/auto_restart_on.sh

#!/bin/bash

LOG_FILE="/opt/minecraft/tools/auto_restart/restart.log"

nohup /opt/minecraft/tools/auto_restart/work.sh > $LOG_FILE 2>&1 &

echo auto restart on, view $LOG_FILE to know more.

开启自动重启的脚本,创建后台执行

~/tools/auto_restart/auto_restart_off.sh

#!/bin/bash

kill -9 $(ps -aux | grep work.sh | grep -v grep | awk '{print $2}')

echo auto restart off.

关闭自动重启的脚本,直接kill掉,很粗暴

ok,现在应该可以愉快玩耍了,如果还出现问题可能还会继续更新,如果本文有错误欢迎指出!


2021.10.04 更新
现在服务器已经稳定跑了一个多月没挂了
就是去冒险的时候移动速度过快(开船)可能会导致服务器overloaded,就会变卡
不过不会直接宕掉
整体体验还行
status


2021.10.23 更新
使用swap空间感觉治标不治本,玩家相距比较远的时候还是会卡,最终还是妥协了,升级了2核4G,玩完mc还可以开新坑(terraria或者饥荒什么的)
在这里插入图片描述


参考资料:
https://www.myfreax.com/how-to-install-minecraft-server-on-centos-7/
https://www.bilibili.com/read/cv9784699
https://segmentfault.com/a/1190000008125116
https://stackoverflow.com/questions/185451/quick-and-dirty-way-to-ensure-only-one-instance-of-a-shell-script-is-running-at

  • 5
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值