当前位置 博文首页 > ttoobne:Linux云主机部署搭建minecraft服务器以及记录java内存

    ttoobne:Linux云主机部署搭建minecraft服务器以及记录java内存

    作者:[db:作者] 时间:2021-08-30 10:29

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

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

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

    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设置为守护进程

    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空间好像听说过但是不知道具体是啥,一百度,原来之前听过无数遍的虚拟内存在Linux中是通过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,现在应该可以愉快玩耍了,如果还出现问题可能还会继续更新,如果本文有错误欢迎指出!

    参考资料:
    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

    cs