Tag

运维

docker+mc的运维管理方案

之前在 一篇文章 中提到过docker部署minecraft服务器,后来发现并不好用,因为portainer免费版并没有很好的控制台管理方式,没有用户组之类的精确权限控制,同时也没有好用的文件管理方案,最终选择使用code-server来管理,在容器中安装tmux用于后台运行并随时打开控制台,同时还有vscode的好用文件管理

Dockerfile

# ubuntu 作为基础镜像。
FROM ubuntu:24.04

# HTTP 代理
ENV HTTP_PROXY="http://172.17.0.1:7890"
# HTTPS 代理
ENV HTTPS_PROXY="http://172.17.0.1:7890"
# 针对 code-server/npm/git 等的全局代理(通常是小写的)
ENV http_proxy="http://172.17.0.1:7890"
ENV https_proxy="http://172.17.0.1:7890"
ENV NO_PROXY="localhost,127.0.0.1,::1,10.0.0.0/8,172.16.0.0/12,192.168.0.0/16"
# 时区
ENV TZ="Asia/Shanghai"

# 配置 APT 清华源
COPY aliyun-ubuntu.sources /etc/apt/sources.list.d/
RUN apt-get update

# 安装依赖
RUN DEBIAN_FRONTEND=noninteractive \
    apt-get install -y --no-install-recommends \
    curl \
    gosu \
    tmux \
    ca-certificates \
    iputils-ping \
    wget \
    zip \
    unzip \
    locales \
    && rm -rf /var/lib/apt/lists/*

# 设置编码
RUN locale-gen en_US.UTF-8 && update-locale LANG=en_US.UTF-8 LC_ALL=en_US.UTF-8

# code-server
RUN curl -fsSL https://code-server.dev/install.sh | sh

COPY start.sh /
RUN chmod +x /start.sh

RUN useradd --shell /bin/bash -u 1001 -m mc
WORKDIR /home/mc

# 暴露端口
EXPOSE 8080
EXPOSE 25565

CMD ["/start.sh"]

start.sh

#!/bin/bash
set -e

# 检查环境变量是否已设置
if [ -z "$SERVER_NAME" ]; then
    echo "Error: SERVER_NAME environment variable is not set correctly."
    exit 1
fi

# 修正文件归属
chown -R mc /home/mc

# ===============================================================
# 信号捕获函数:用于优雅关闭 MC Server
# ===============================================================
graceful_shutdown() {
    echo "Caught signal. Performing graceful shutdown..."
    
    # 检查 tmux session 是否存在
    if tmux has-session -t mc 2>/dev/null; then
        echo "Sending 'stop' command to Minecraft server via tmux..."
        
        # 使用 tmux send-keys 向 'mc' 会话发送 'stop' 命令和 Enter 键
        # -t mc: 指定目标会话
        # C-m: 相当于按下 Enter 键
        tmux send-keys -t mc 'stop' C-m
        
        # 等待 MC Server 进程退出。mc-server-runner 会处理 Java 的关闭
        # 我们可以等待 tmux session 消失,表示 mc-server-runner 已退出
        TIMEOUT=60
        COUNT=0
        while tmux has-session -t mc 2>/dev/null && [ $COUNT -lt $TIMEOUT ]; do
            echo "Waiting for Minecraft server to stop... (Max $TIMEOUT seconds)"
            sleep 1
            COUNT=$((COUNT + 1))
        done
        
        if [ $COUNT -eq $TIMEOUT ]; then
            echo "WARNING: Minecraft server did not stop gracefully within $TIMEOUT seconds. Killing tmux session."
            tmux kill-session -t mc 2>/dev/null
        else
            echo "Minecraft server stopped successfully."
        fi
    else
        echo "Minecraft server tmux session not found or already stopped."
    fi

    # 停止 code-server (exec 后的 code-server 已经是主进程,收到信号后会自动退出)
    # 我们这里不需要手动杀死 code-server,因为 Tini 会转发信号给它。
    # 退出脚本,允许 Tini 干净地清理进程
    exit 0
}

# 捕获 SIGINT (Ctrl+C) 和 SIGTERM (Docker Stop) 信号
trap 'graceful_shutdown' SIGINT SIGTERM

echo Starting Server...
cd /home/mc/$SERVER_NAME
gosu mc tmux new -d -s $SERVER_NAME
gosu mc tmux send-keys -t $SERVER_NAME:0 "$START_CMD" C-m

echo Starting Code...
gosu mc sed -i "s#^password: .*#password: $CODE_PASSWORD#" /home/mc/.config/code-server/config.yaml
gosu mc code-server --bind-addr 0.0.0.0:8080 /home/mc/$SERVER_NAME &
CODE_SERVER_PID=$!
echo "code-server started with PID $CODE_SERVER_PID."

# 等待 code-server 进程或收到的信号。
# 这一行是保持 start.sh 脚本存活的关键,以监听信号。
wait $CODE_SERVER_PID

# 如果 code-server 意外退出,则执行优雅关闭流程
graceful_shutdown

aliyun-ubuntu.sources

Types: deb
URIs: http://mirrors.aliyun.com/ubuntu
Suites: noble noble-updates noble-backports
Components: main restricted universe multiverse
Signed-By: /usr/share/keyrings/ubuntu-archive-keyring.gpg

docker-compose.yml 使用示例(此处的镜像是本地构建的)

services:
  velocity:
    image: minecraft-universal:1.5
    container_name: velocity
    hostname: velocity
    environment:
      SERVER_NAME: "velocity"
      START_CMD: "./start.sh"
      CODE_PASSWORD: "<your-password>" 
    ports:
      - "25565:25565"
    volumes:
      - /opt/java:/java:ro
      - /opt/mc-velocity:/home/mc
    restart: unless-stopped
    networks:
      - mc
      - web

使用时需要先在映射的目录下创建目录,目录名字和环境变量中的SERVER_NAME一致,并在目录下添加 start.sh 以及其他服务器文件,对应compose中定义的启动指令

同事误删mysql库补救办法

发现问题

今天下午同事突然跑来找我说不小心把库删了,问我会不会恢复,我从来没有这种删库恢复的经验,自然是要学习一下的,直接开始帮他恢复

查找解决办法

被删库的机器,这儿就叫他243,243的应用和数据库在同一个服务器上

  1. 首先先停止了应用防止继续写入或者丢失服务数据
  2. 检查mysql的binlog是否开启 SHOW VARIABLES LIKE 'log_bin%';,发现是开着的
  3. 检查binlog是否完整 ls /opt/mysql/data/ 发现缺少了几乎一半的binlog,推测是开启了过期清理
  4. 这个时候了解服务器运维的同事提出可以问机房的人恢复硬盘备份,并联系了相关同事
  5. 等待了一段时间,运维同事恢复了前一天的一个备份到一台新机器上,这儿叫他229

解决过程

在等待的时间里,确定了解决方案

  1. 检查两个服务器的binlog id差异
  2. 在243上找到最新的删库的binlog id
  3. 在229上找到最新的binlog id
  4. 在243生成两个binlog id中间差异的sql文件
  5. 将sql文件scp到229服务器上
  6. 229服务器的mysql执行sql补全缺失的数据

其中第二步可以在等待的时候完成

检查binlog的脚本 - 243

mysqlbinlog --no-defaults -v --base64-output=DECODE-ROWS  --stop-position=287225397  binlog.000075 | tail -n 500 > ~/tail.log
# at 287225397
#260227 15:46:29 server id 1  end_log_pos 287225556 CRC32 0x97e6fb47 	Query	thread_id=663510	exec_time=1	error_code=0	Xid = 583720608
use `laboratory`/*!*/;
SET TIMESTAMP=1772178389/*!*/;
SET @@session.pseudo_thread_id=663510/*!*/;
SET @@session.foreign_key_checks=0/*!*/;
DROP TABLE IF EXISTS `assay_report` /* generated by server */

检查binlog的脚本 - 229

mysqlbinlog --no-defaults --database=laboratory ./binlog.000074 > ~/74.sql
# at 1074009846
#260227 10:39:55 server id 1  end_log_pos 1074009890 CRC32 0x5b7eb4ae   Rotate to binlog.000075  pos: 4
SET @@SESSION.GTID_NEXT= 'AUTOMATIC' /* added by mysqlbinlog */ /*!*/;
DELIMITER ;
# End of log file
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;

在243生成差异sql

mysqlbinlog --no-defaults --database=laboratory  --skip-gtids  --start-position=256983036 binlog.000074 --stop-position=287225397 binlog.000075 > all.sql

恢复sql

# 登录sql
mysql -u root -p
# 执行文件 (1.5G的all.sql最终执行了十几分钟,服务器是固态硬盘)
source /home/all.sql

最终效果

在下班前恢复完成数据库并准时下班🎉🎉🎉

ps:本次行动由gemini提供技术支持😂

Arthas

Arthas 是一款线上监控诊断产品,通过全局视角实时查看应用 load、内存、gc、线程的状态信息,并能在不修改应用代码的情况下,对业务问题进行诊断,包括查看方法调用的出入参、异常,监测方法执行耗时,类加载信息等,大大提升线上问题排查效率。
通常,本地开发环境无法访问生产环境。如果在生产环境中遇到问题,则无法使用 IDE 远程调试。更糟糕的是,在生产环境中调试是不可接受的,因为它会暂停所有线程,导致服务暂停。
开发人员可以尝试在测试环境或者预发环境中复现生产环境中的问题。但是,某些问题无法在不同的环境中轻松复现,甚至在重新启动后就消失了。
如果您正在考虑在代码中添加一些日志以帮助解决问题,您将必须经历以下阶段:测试、预发,然后生产。这种方法效率低下,更糟糕的是,该问题可能无法解决,因为一旦 JVM 重新启动,它可能无法复现,如上文所述。
Arthas 旨在解决这些问题。开发人员可以在线解决生产问题。无需 JVM 重启,无需代码更改。 Arthas 作为观察者永远不会暂停正在运行的线程。

Arthas官方文档

查cpu高占用

  • dashboard 查看占用最高的线程
  • thread -n 3 查看占用高的线程及其堆栈

查内存高占用

  • oom崩溃的情况无法处理,需要-XX:+HeapDumpOnOutOfMemoryError
    • -XX:HeapDumpPath=/tmp/heapdump.hprof 指定dump文件位置
    • 进程还活着才可以分析
  • vmtool --action forceGc 先fullGc一次
  • dashboard 查看Memory
  • jmap -histo:live <pid> | head -n 20 查看是否有大量自定义对象 一般排名靠前的都是java的基本类型
  • heapdump --live /tmp/dump.hprof 导出文件后拖到idea或者mat软件分析
    • 在合并的路径tab中可以按照实例类型和引用关系找到引用最多对象的实例
    • 在最大对象tab中可以看到对象及其引用的对象的占用并层层展开查看引用关系
    • 保留(Retained)是这个对象及其引用的对象层层递归加起来的总内存占用,主要看这个
      • 计算的是对象的独占对象的内存占用,如果一个object还被其他object引用,则不纳入计算
      • 找到保留大小最大的几个对象,通过引用树找到持有这些对象的实例
    • 浅层(Shallow)是这个对象本身占用的内存,一般只有数组的浅层大小会很大

修改方法逻辑

  • jad --source-only com.example.demo.UserController > /tmp/UserController.java 添加 --lineNumber=false 不显示行号 -d dump文件到目录
  • 编辑补全逻辑
  • mc /tmp/UserController.java -d /tmp 编译成class
  • retransform /tmp/com/example/demo/UserController.class 热重载

查慢方法调用

  • trace com.example.demo.OrderController createOrder -n 1 添加监听
    • -n 1 指定触发次数,方法触发指定次数后自动退出,不添加则会连续监听直到ctrl c
    • 若入参或返回值过长可以输出到文件 文件路径不能使用~ 否则会创建名为~的文件
  • 输出包含方法调用栈以及行号的执行耗时
    • 输出的列表和Map不会展开内容,只会显示size

查方法入参返回值

  • watch com.example.demo.UserService login "{params, returnObj}" -n 1 添加监听
    • -n 1 指定触发次数,方法触发指定次数后自动退出,不添加则会连续监听直到ctrl c
    • 添加 -x 2 展开对象, 展开2刚好够展开Map和List
    • watch com.example.demo.UserService login "{ @com.alibaba.fastjson.JSON@toJSONString(params), @com.alibaba.fastjson.JSON@toJSONString(returnObj) }" -n 1 使用OGNL编写表达式可以输出json格式, 此时不需要-x展开
    • watch com.example.demo.UserService login "{ params, returnObj }" "params[0].name == 'test'" -n 1 使用OGNL编写条件表达式,可以在递归调用等地方过滤不想要收集的方法调用 如果在win等无法输入中文的情况下可以用unicode编码 "'\u6d4b\u8bd5\u540d\u5b57' == params[0]"

远程连接内网路由器

看标题会感觉是一个很简单的操作,但是不是。路由器后台会自动重定向到ip访问,导致常规端口转发不生效。

我尝试过zerotier,但是和公司的局域网网段重叠了,遂放弃。

今天发现ssh可以做socks代理,于是解决了。

ssh指令ssh -D 1080 -N -q user@host -p port打开一个socks代理

然后下一个火狐(可以下便携版)

进入设置拉到最下面找到网络设置,配置socks代理(别写http的)

然后就可以直接访问了

wordpress 非标准端口 https

今天折腾了一天的wordpress,想从http切换到https

首先用acme申请了证书

在wordpress容器到公网之间添加了一个nginx做反代顺便添加https支持

首先遇到的问题是修改站点地址为https后argon的js和css都请求失败,一看发现还都是http

折腾半天找不到配错的地方,最后没写过php也只能硬改代码了,在argon的functions.php里添加了以下代码

function fix_output_urls($buffer) {
    return str_replace('http://e404.top', 'https://e404.top', $buffer);
}

function start_output_buffer() {
    ob_start("fix_output_urls");
}

add_action('wp_loaded', 'start_output_buffer');

然后就返回了正常的https地址

但是打开管理界面的时候一直重定向到自己

又调试半天,找不到问题原因

只能直接改代码看日志debug

半夜把is_ssl函数改了一下发现能跑了

function is_ssl() {
	if ( isset( $_SERVER['HTTPS'] ) ) {
		if ( 'on' === strtolower( $_SERVER['HTTPS'] ) ) {
			return true;
		}

		if ( '1' === (string) $_SERVER['HTTPS'] ) {
			return true;
		}
	} elseif ( isset( $_SERVER['SERVER_PORT'] ) && ( '443' === (string) $_SERVER['SERVER_PORT'] ) ) {
		return true;
	}

	return false;
}

第二天发现是wp-config-docker.php原来是需要替换config.php的

修复误损坏/usr的ubuntu

前情提要

在安装telegraf的时候需要复制文件到/etc /usr /var 等目录下,移动文件的时候错误使用了mv usr/* /usr/*的指令,导致系统损坏,缺少bash无法ssh远程连接

尝试远程修复

ssh连不上的情况下发现跑在docker中的容器居然还在正常运行,于是尝试通过portainer新建容器挂在根目录修复,发现portainer会执行宿主机上的可执行文件调用docker,失败

物理机处理

在无法远程修复的情况下只能直接操作物理机修复/备份数据重装。此时物理机/usr目录损坏已经无法重启正常进入系统,启动时显示run-init: can't execute '/sbin/init': No such file or directory,猜测是因为该文件是从/usr/sbin下软链接过来的

使用安装盘进入系统

我的安装盘是rufus创建的,使用的是之前安装系统时的ubuntu 24.04.1 server

首先进入启动盘选择界面,根据教程需要try ubuntu without install然后进入Live 环境,但是server的启动盘中并不包含这个选项,所以直接进入install界面,然后ctrl + alt + f2进入安装器的 BusyBox / Shell

挂载磁盘

使用lsblk指令列出可挂载的磁盘,我的机器中有一块固态和一块机械,固态的主要数据在 /dev/nvme0n1p2,机械的数据在/dev/sdb1,同时我还插入了移动硬盘以便在系统无法修复的情况下直接备份数据,移动硬盘在 /dev/sdc

首先挂载系统盘检查损坏情况mkdir /nvme && mount /dev/nvme0n1p2 /nvme,然后ls /nvme/usr检查损坏情况

非常神奇的,/nvme/usr/bin/nvme/usr/lib/nvme/usr/src没有被删除,于是我直接从安装器的系统中复制了其余的includelib64libexeclocalsbinshare目录到/nvme/usr下,并重启系统,此时正常进入系统

检查系统损坏情况

虽然正常进入了系统,但是并不是所有问题都解决了,首先检查了一些系统服务是否正常运行

dpkg -V | grep -v '^??'列出所有有缺失的包,apt reinstall重新安装确保丢失文件被重新安装

最后安装mariadb的时候忘了指定版本导致启动失败,回忆起以前安装的时候找的对标mysql8的版本,于是卸载自动安装的最新版本换成了mariadb-server=1:10.11.13-0ubuntu0.24.04.1,重启服务后正常运行

检查docker的时候发现docker compose指令不见了,于是重新安装apt install docker-compose-plugin

一天后发现博客无法访问,博客是部署在docker中的wordpress(也就是你现在看到的博客),显示Error establishing a database connection,检查后发现mariadb的默认绑定地址是127.0.0.1,所以无法从容器中访问

后记

至此,系统已修复完成,所有服务都可以正常运行

tmux

在后台启动tmux tmux new -d -s name

给tmux输入发送指令 tmux send-keys -t name:0 "echo hello" C-m

Windows部署MongoDB

下载

MongoDB 6 的zip中只包含mongod即服务端,需要额外下载mongosh作为客户端

mongo下载:https://www.mongodb.com/try/download/community

mongosh下载:https://www.mongodb.com/try/download/shell

两者的下载都需要选择平台和架构

mongod安装服务

下载的MongoDB解压到目标位置,然后在其中新建一个文件mongod.yml(名字和后缀名不重要,随便起)

这儿的两个path,都换成自己的,目录需要自己手动创建,比如我这儿就是在MongoDB文件夹下新建的data文件夹和logs文件夹

systemLog:
    destination: file
    path: D:\App\MongoDB\logs\mongod.log
storage:
    dbPath: D:\App\MongoDB\data

在命令行中执行以下指令注册服务(这儿的serviceName是不可缺少的)

# 安装mongo服务
mongod --config "D:\App\MongoDB\mongo.yml" --install --serviceName "MongoDB"
# 启动mongo服务
net start MongoDB

此时mongodb的服务就已经安装并启动了,可以用mongosh连接了(添加path不再赘述)

创建用户

// 参考 https://www.mongodb.com/docs/manual/tutorial/create-users/#create-additional-users-for-your-deployment
use test
db.createUser(
  {
    user: "用户名",
    // passwordPrompt()会要求在控制台中输入密码, 避免密码出现在日志中, 也可以直接使用密码
    pwd:  passwordPrompt(),
    // 权限参考 https://www.mongodb.com/docs/manual/reference/built-in-roles/#database-user-roles
    roles: [ { role: "readWrite", db: "test" },
             { role: "read", db: "reporting" } ]
  }
)

mongosh登录

mongosh "mongodb://admin:123456@localhost:27017/test?authSource=admin"

Ubuntu安装Mysql5.7笔记

下载

https://downloads.mysql.com/archives/community/

解压

tar -xf mysql-5.7.39-linux-glibc2.12-x86_64.tar.gz

创建linux用户和组

groupadd mysql && useradd -r -g mysql mysql

设置

注意,以下示例步骤中安装mysql的位置为/usr/local/mysql,mysql数据文件夹为/usr/local/mysql/data

vim /etc/my.cnf

参考:http://c.biancheng.net/view/7618.html

这儿的不要乱写,容易导致各种奇奇怪怪的问题

[mysqld]
port=3306
user=mysql
basedir=/usr/local/mysql
datadir=/usr/local/mysql/data
socket=/tmp/mysql.sock
max_connections=200
symbolic-links=0
character-set-server=utf8
default-storage-engine=INNODB
sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES

[mysql]
default-character-set=utf8

[mysqld_safe]
log-error=/usr/local/mysql/error.log
pid-file=/usr/local/mysql/mysqld.pid

文档:https://www.mysqlzh.com/doc/13/78.html

# 创建数据文件夹, 日志文件夹, 设置所有者
cd /usr/local/mysql && mkdir logs && touch error.log && chown mysql:mysql -R *

初始化

bin/mysqld --defaults-file=/etc/my.cnf --basedir=/usr/local/mysql/ --datadir=/usr/local/mysql/data/ --user=mysql --initialize

解决./mysqld: error while loading shared libraries: libaio.so.1: cannot open shared object file: No such file or directory

sudo apt install -y libaio-dev numactl

复制 mysql 到系统服务

cp support-files/mysql.server /etc/init.d/mysql

解决Unit mysql.service does not exist, proceeding anyway.

修改vim /etc/init.d/mysql

# 若/etc/my.cnf中指定了mysql目录,则此处也需要指定
basedir=/usr/local/mysql
datadir=/usr/local/mysql/data

启动mysql

systemctl enable mysql

或者

service mysql start

进入mysql命令行

mysql -u root -p
# 在接下来的一行中输入密码

解决./mysql: error while loading shared libraries: libncurses.so.5: cannot open shared object file: No such file or directory

apt-get install -y libncurses*

修改密码

-- 更新密码
alter user 'user'@'host' identified by 'password';
-- 刷新权限
flush privileges;

常用操作

以下内容参考于 https://blog.csdn.net/qpzkobe/article/details/102833458

# 创建用户 username替换为用户名, host替换为地址, password替换为密码
# 示例 CREATE USER 'mc'@'localhost' IDENTIFIED BY '123456';
CREATE USER 'username'@'host' IDENTIFIED BY 'password';
# 删除用户 username替换为用户名, host替换为地址
# 示例 DROP USER 'mc'@'localhost';
DROP USER 'username'@'host';
# 授权 privileges替换为权限, databasename替换为库名, tablename替换为表名, username替换为用户名, host替换为地址
# 示例 GRANT all ON playerpoints.* TO 'mc'@'localhost';
GRANT privileges ON databasename.tablename TO 'username'@'host';
# 撤销授权 privileges替换为权限, databasename替换为库名, tablename替换为表名, username替换为用户名, host替换为地址
# 示例 REVOKE all ON playerpoints.* FROM 'mc'@'localhost';
REVOKE privilege ON databasename.tablename FROM 'username'@'host';

# 刷新权限
flush privileges;

screen简单教程

Linux screen命令用于多重视窗管理程序。

screen为多重视窗管理程序。此处所谓的视窗,是指一个全屏幕的文字模式画面。通常只有在使用telnet登入主机或是使用老式的终端机时,才有可能用到screen程序。

https://www.runoob.com/linux/linux-comm-screen.html

下文中使用name作为默认的screen名字示例,实际使用中需要替换成你创建的screen的名字

简单的入门使用

创建并进入

screen -S name # 创建一个名字为name的screen

挂起当前screen(还可以进入)

在screen中按下ctrl + a,然后按d(注意如果开启中文输入法可能会失效)

查看存在的screen

screen -ls # 查看存在的screen

进入挂起的screen

screen -x name # 进入名为name的screen(允许多个终端同时进入)

若打开了多个同名的screen, 则需要先使用 screen -ls 列出并找到要打开的screen对应的id, 然后使用 screen -x id 进入对应的screen

screen -x 12345 # 进入id为12345的screen

退出当前screen(无法再进入)

exit # 若当前处于screen则退出screen, 否则会退出当前bash

特殊用法

后台创建

screen -dmS name # 创建一个名为name的screen但是不进入

外部执行指令

screen -x -S name -p 0 -X stuff "ls\n" # 外部调用名为name的screen输入ls并回车(\n代表回车)

此处的 -p 0 意为若存在多个screen则选择第0个(从0开始),若你没有同名的screen则可以去掉

外部关闭screen

screen -S name -X quit # 从外部关闭名为name的screen

滚动

先按 ctrl + a , 然后按esc

记录一次MySQL遇到的问题

昨天自己的家里云突然死机,重启之后MySQL启动不了

经过半天的百度,无论怎么设置权限,结果都是Permission denied

最终重装mysql解决

首先备份mysql文件(包括数据文件夹),之后删除原有mysql用户及存放mysql的mysql用户家目录

重新创建mysql用户,下载并初始化mysql

初始化完成后停止mysql服务,将新的mysql的数据文件夹重命名,然后将之前备份的数据文件夹复制过来,复制完成后重新启动mysql服务

完成

win10部署MySql5.7并修改密码

下载

https://downloads.mysql.com/archives/community/

下载完成后解压到自己想安装到的文件夹

这里我使用的是 D:\app\MySql

配置

在此文件夹下新建 my.ini 文件

这里贴出我的配置文件

[mysqld]
port=3306
basedir=D:/app/MySql
datadir=D:/appData/MySql
max_connections=200
character-set-server=utf8
default-storage-engine=INNODB
sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES
[mysql]
default-character-set=utf8

详细解释见中文文档 https://www.mysqlzh.com/doc/13/78.html

设置Path

  1. 此电脑右键 属性
  2. 点击 高级系统设置
  3. 点击 环境变量
  4. 在系统变量中找到Path
  5. 点击编辑
  6. 点击右侧的新建
  7. 输入 D:\app\MySql\bin (这里写自己的安装位置\bin)
  8. 一路确定退出

初始化

  1. win + R 打开运行
  2. 在运行中输入 cmd 并回车
  3. 在cmd中进入mysql文件夹
# 进入mysql文件夹的bin目录
d:
cd app\MySql\bin

# 安装
mysqld install

# 初始化数据文件夹
mysqld --initialize --console
# 执行完成后会给出初始密码(看起来像乱码的那串字符串), 记下来, 后面登录需要用

# 启动
net start mysql

进入MySql

在cmd中输入 mysql -u root -p

根据提示输入密码(上面初始化的时候给你的密码)

输入密码 输入密码 登录完成 登录完成

修改密码

-- 选择数据库
use mysql;
-- 更新密码
update user set authentication_string=password('新密码') where user='root' and Host='localhost';
-- 刷新权限
flush privileges;

use mysql; 失败报错则使用

-- 修改密码
alter user user() identified by '密码';
-- 退出重进
exit

Linux环境变量设置完没有改变

我自己的服务器用的是Centos7, 最近设置环境变量的时候发现设置完source之后PATH居然没有变化

# 修改环境变量(我是写在文件最前面的)
vim /etc/profile

刷新环境变量

source /etc/profile

然后在profile里面设置完环境变量的地方echo了一下, 发现输出的PATH是正确的

经过排查之后发现

/etc/profile.d 里面有一个 mysql.sh

PATH=/usr/local/src/openJDK/bin:/usr/local/src/node/bin:/home/mysql/mysql/bin:/usr/local/src/ffmpeg:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin:/home/mysql/mysql/bin

怪不得PATH总是改完没反应

这里将它重命名为 mysql.sh.bak , 再source刷新之后, PATH就正确了

Linux设置ssh并通过ssh密钥登陆

进入 .ssh

# 进入 .ssh 文件夹
cd ~/.ssh

处理旧密钥

# 处理旧的密钥文件
mv id_rsa id_rsa.bak
mv id_rsa.pub id_rsa.pub.bak

创建密钥

# 输入后按3次回车
ssh-keygen -t rsa

公钥写入到文件

# 将公钥写入authorized_keys
cat id_rsa.pub >> authorized_keys

问题

若出现问题无法登陆,则检查日志 /var/log/secure

写入公钥后无法登陆

Authentication refused: bad ownership or modes for file /root/.ssh/authorized_keys

原因:

sshd 为了安全,对属主的目录和文件权限有所要求。如果权限不对,则 ssh 的免密码登陆不生效

用户目录权限为 755 或者 700,就是不能是 77x

.ssh 目录权限一般为 755 或者 700

rsa_id.pub 及 authorized_keys 权限一般为 644

rsa_id 权限必须为 600

# 设置权限(权限错误会无法登陆)
cd ~/.ssh
chmod 644 authorized_keys id_rsa.pub && chmod 600 id_rsa && chmod 700 .

Ubuntu20.04安装&配置下载源/中文

下载ISO & 安装

官网下载,这里选LTS(长期支持版)

这里我用的vmware虚拟机安装的ubuntu,如果要在实体机上安装ubuntu的话,可以使用ubuntu官网推荐的rufus

安装过程比较长并且没有什么需要操作的地方,跳过

配置下载源

安装好系统后,默认是英文,系统默认没有附带中文的语言文件,要更换语言就得下载。

下载之前首先要设置下载源,国内不配置下载源下载会非常慢(如果有弹窗让你更新的话先放着,等配置好下载源之后再更新)

关闭并且重载

等到进度条走完就完成了换源(如果有报错跳过即可)

更换系统语言

安装完成后

设置格式

设置完成后重启就是中文得了

不要忘了设置输入法 不要忘了设置输入法

其他设置

标准文件夹改名

将语言设置为中文后系统会询问是否改名标准文件夹,这里我选择不改

原因是之前用centos7(gnome桌面),中文输入法有时会失灵,无法输入中文,没办法进入中文名字的文件夹

自动息屏

时区

SU & ROOT

ubuntu默认不允许直接使用root账户登陆,需要使用时请使用 su 指令切换到 root 账户,使用完毕之后用 exit 指令退出

第一次使用 su 切换toot账户之前需要先为root账户设置密码

输入 sudo passwd 为root账户设置密码,输入指令后需要输入3此密码,第一次是当前账户的密码,后两次是设置root账户的密码,输入后不显示是正常情况

代理

wget的时候是不走系统代理的,解决办法

export https_proxy=192.168.48.1:7890 export http_proxy=192.168.48.1:7890 export ftp_proxy=192.168.48.1:7890

这里的 192.168.48.1:7890 是我本机的代理,使用时修改成你的代理地址

远程连接/SSH

Ubuntu默认带了openssh-client,但是没有openssh-server

直接 apt install -y openssh-server 会提示

这里我们直接卸载已有的openssh-clileht

apt remove -y openssh-client

然后再安装openssh-server

apt install -y openssh-server

ps: 这里我使用的root账户安装,若是普通账户请在指令前添加 sudo

sudo apt remove -y openssh-client

sudo apt install -y openssh-server

Windows cmd选择模式

首先打开cmd,在左上角的cmd图标,并在菜单中选择默认值(打开属性是一样的界面,与默认值的区别是属性只修改当前cmd,默认值会修改所有修改完之后打开的cmd)

打开后找到选项 -> 编辑选项 -> 快速编辑模式,将其取消选中

点击右下角的确定

paper.yml按世界单独配置

paper.yml中的设置很丰富,可设置的项目非常多,但是有一点可能很少有人知道,那就是这些功能可以按世界单独设置。paper.ymlworld-settings下的所有的选项都可以按世界单独设置(但是一些项目只在特定的世界有效,比如末影龙相关的设置只在末地有效)

默认在world-settings下有default项,这一项的意思是默认配置,如果没有其他的配置覆盖他,那么paper将会以default下的配置项进行运作

只有 world-settings.default 下的项目才可以按世界单独配置,不在其中的项目是不可以单独设置的

默认配置为

world-settings:
  default:
    grass-spread-tick-rate: 1
    seed-based-feature-search: true
    seed-based-feature-search-loads-chunks: true
    ...: ...
    ....: ...

多世界的配置为

world-settings:
  # 默认配置
  default:
    grass-spread-tick-rate: 1
    seed-based-feature-search: true
    seed-based-feature-search-loads-chunks: true
    ...: ...
    ....: ...
  # 下界的单独设置,在下界会覆盖default的设置
  # 没有在此处设置的会沿用default
  world_nether:
    grass-spread-tick-rate: 2
    seed-based-feature-search: true
    seed-based-feature-search-loads-chunks: true
    ...: ...
    ....: ...
  # 末地的单独设置,在下界会覆盖default的设置
  # 没有在此处设置的会沿用default
  world_the_end:
    grass-spread-tick-rate: 3
    seed-based-feature-search: true
    seed-based-feature-search-loads-chunks: true
    ...: ...
    ....: ...

Paper反矿透anti-xray的开启 & 配置

官方文档

paper自带一个反透视的功能,相比较插件的反矿透,优化做的较好

此功能只有paper和基于paper的服务端核心才有(如果服务端没有paper.yml配置文件那就是不支持,bukkit,spigot,forge,fabric是没有的)

高版本paper核心的配置文件在 服务端文件夹/config 文件夹下

原理大概是通过给客户端发送虚假的数据包,使得平常不可见的方块在客户端上的数据并不是真实的数据,使用一些“工具”的客户端看到的这些方块也就不是真实的方块了

以下的解释参考自paper官方文档:https://paper.readthedocs.io/en/latest/server/configuration.html

以及:https://gist.github.com/stonar96/ba18568bd91e5afd590e8038d14e245e

启用

打开 服务端文件夹/paper.yml 找到 anti-xray 设置项

默认的配置如下

低版本的配置文件有所不同是正常情况

# 这里以1.17版本的配置文件为示例解释每个配置项的含义
# 如果不同版本有差异属于正常情况
anti-xray:
  # 是否启用 true -> 启用
  enabled: false
  # 引擎模式
  # 1是用石头替换下面列表里面的方块
  # 2是用随机方块替换所有方块
  # 这里的方块指的是玩家看不到的,没有裸露在外的方块
  engine-mode: 1
  # 设置隐藏矿石的最大高度
  # 需要填写16的倍数,其他值将向下舍入为16的倍数
  # 在此高度以下的方块将会按对应的模式进行反矿透
  max-block-height: 64
  # 方块更新的半径, 当一个方块被更新时, 客户端的方块也会随之更新
  # 有效值:0, 1, 2
  # 大于2的默认为2, 小于0的默认为0
  # 不要使用0, 这只是一种测试模式
  update-radius: 2
  # 是否混淆接触熔岩的方块
  lava-obscures: false
  # 是否允许有paper.antixray.bypass权限的玩家绕过反矿透
  use-permission: false
  # 在引擎模式1中要隐藏的方块列表
  # 一些方块可能需要手动添加
  # 注意: 此列表使用的是原版方块名称而不是bukkit方块名称。
  hidden-blocks:
    - copper_ore
    - deepslate_copper_ore
    - gold_ore
    - deepslate_gold_ore
    - iron_ore
    - deepslate_iron_ore
    - coal_ore
    - deepslate_coal_ore
    - lapis_ore
    - deepslate_lapis_ore
    - mossy_cobblestone
    - obsidian
    - chest
    - diamond_ore
    - deepslate_diamond_ore
    - redstone_ore
    - deepslate_redstone_ore
    - clay
    - emerald_ore
    - deepslate_emerald_ore
    - ender_chest
  # 在引擎模式2中应该替换的方块列表
  # 一些方块可能需要手动添加
  # 注意: 此列表使用的是原版方块名称而不是bukkit方块名称。
  replacement-blocks:
    - stone
    - oak_planks

这里将 enable: false 改成 enable: true 以启用反矿透

配置详细解释

enabled

解释:是否启用

允许的值:true / false

engine-mode

解释:反矿透的运作方式

模式1:根据世界类型用石头、地狱岩或末地石替换指定的矿石(通过发送经过修改的数据包,性能消耗较模式2相比较小)

模式2:在向客户端发送块数据包时随机放置指定的假矿(性能消耗较模式1相比较大)

允许的值:1 / 2

抗 X 射线模式 图片来源于 https://gist.github.com/stonar96/ba18568bd91e5afd590e8038d14e245e

模式1计算量较小,但模式2可以更好地反矿透。在模式1中,只有完全被不透明方块覆盖的矿石才能被隐藏。这意味着暴露在空气中的矿石仍然可见。在模式2中,假矿石中会遮挡这些矿石,并且添加假空气

max-block-height

解释:反矿透的运作范围,可以写128

允许的值:16的倍数,其他值将向下舍入为 16 的倍数

注:低版本的配置与上述不同,填写的是max-chunk-section-index,规则是 (填写的数值 + 1) * 16。大于 15 的 max-chunk-section-index 默认为 15。小于 0 的 max-chunk-section-index 没有意义。

update-radius

解释:方块更新的半径, 当一个方块被更新时, 客户端的方块也会随之更新

允许的值:0 / 1 / 2 (大于2的默认为2, 小于0的默认为0)

注:不要使用0, 0是一种测试模式,如没有需要请不要修改

lava-obscures

解释:是否混淆接触熔岩的方块,可以写true

允许的值:true / false

use-permission

解释:是否允许有paper.antixray.bypass权限的玩家绕过反矿透,可以写false

允许的值:true / false

hidden-blocks

解释:在引擎模式1中要隐藏的方块列表, 一些方块可能需要手动添加(例如下界的矿石)

注:此列表使用的是原版方块名称而不是bukkit方块名称。

replacement-blocks

解释:在引擎模式2中应该替换的方块列表, 一些方块可能需要手动添加

注:此列表使用的是原版方块名称而不是bukkit方块名称。

ps

按世界单独配置

Paper Watchdog 报错

问题特征

使用paper及其分支核心,服务端长时间无响应时会由Watchdog打印线程转储信息

特征是有很长的一串报错,开头如下

[Paper Watchdog Thread/ERROR]: --- DO NOT REPORT THIS TO PAPER - THIS IS NOT A BUG OR A CRASH - git-Paper-xxx (MC: 1.1x.x) ---
[Paper Watchdog Thread/ERROR]: The server has not responded for 10 seconds! Creating thread dump

中间会出现多个类似以下结构的报错

[Paper Watchdog Thread/ERROR]: ------------------------------
[Paper Watchdog Thread/ERROR]: Current Thread: Timer hack thread
[Paper Watchdog Thread/ERROR]: 	PID: x | Suspended: false | Native: false | State: TIMED_WAITING
[Paper Watchdog Thread/ERROR]: 	Stack:
[Paper Watchdog Thread/ERROR]: 		xxxx.xxxx.xxxxxx.xxxxx(xxxx xxxx)
[Paper Watchdog Thread/ERROR]: ------------------------------

最后会进行插件和存档的保存消息,并且不会退出服务端的进程(会导致自动重启脚本失效)

这是由于服务端的进程未响应的时长超出了设置的限制,导致Watchdog打印线程转储信息并自动保存关闭

可能的导致原因

  • 某些插件的代码有bug导致主线程进入死循环
  • 粘液科技之类的插件
  • 玩家做的红石机器造成了过大的卡顿
  • 服务器配置太差

解决办法

寻找卡服根源

可以安装spark插件(指令教程),查看占用分析

自行寻找(可以二分法删插件),多看看日志可能有所帮助

升级硬件

大部分时候是升级CPU,cpu选择优先考虑单核水平,可以百度cpu天梯图查看单核排名

和多分配内存(分配过多内存并没有作用,多分配内存只是为了减小gc压力,cpu速度不够的时候并不能靠多分内存弥补)

修改watchdog的限制

治标不治本,该卡还会卡,仅在某些特殊情况(如预加载地图)下使用

找到 服务端文件夹/paper.yml (高版本在 服务端文件夹/config/paper-global.yml ),打开并找到以下选项

watchdog: early-warning-every: 5000 early-warning-delay: 10000

  • early-warning-every: 服务器无响应时打印线程转储之间的间隔(以毫秒为单位)
  • early-warning-delay: 服务器无响应后距离watchdog线程开始打印线程转储的毫秒数

将两个值改成你要的数值即可,注意单位是毫秒

腾讯云域名添加子域名解析

进入DNSPod控制台,找到 我的域名

点击添加记录

比如这里我要设置我的域名e404.top的子域名www.e404.top

主机记录就写www,类型就是A,其他都默认即可

填写完成之后点击确认

崩溃&启动失败的日志/崩溃报告解析

日志

日志位于

  • 客户端:客户端文件夹/.minecraft/logs
  • 服务端:服务端文件夹/logs

文件夹中,最后一次启动的日志是 latest.log ,每当服务端启动时,旧的 latest.log 会被压缩到 年-月-日-次数.log.gz 文件中

如果你的启动脚本是带有自动重启的,并且你没有在它开始重启之前关闭它,那么 latest.log 就会被压缩到gz文件中

此时你需要找到对应的gz文件,使用解压缩软件查看其中的log文件

log文件可以直接用文本文档打开,通常有问题的日志应该从后往前看

崩溃报告

日志位于

  • 客户端:客户端文件夹/.minecraft/crash-reports
  • 服务端:服务端文件夹/crash-reports

文件夹中,崩溃报告的命名格式是 crash-年-月-日_时.分.秒-服务端/客户端.txt

崩溃报告中通常会带有

  • 崩溃原因的描述
  • 导致崩溃的报错
  • 崩溃时运算的实体
  • 服务器的存档信息
  • 服务器的版本
  • 服务器的JVM信息
  • 服务器的系统信息
  • MOD列表(mod服)

以下是一些常见的问题

mod前置未安装

Mod §eMOD名字§r requires §6前置名字§r §o前置版本 or above§r§7Currently, §6前置名字§r§7 is §o§nnot installed

解决办法:安装对应版本的前置

mod前置版本不合要求

Mod §e`MOD名字`§r requires §6`前置名字`§r §o需要的`前置版本` or above, and below `` 需要的`前置版本` ``§r§7Currently, §6`` `前置名字` ``xx§r§7 is §o当前`` 的`前置版本` ``

解决办法:安装对应版本的前置

Minecraft服务端地址

默认地址

Minecraft服务端的端口默认是25565,地址默认是127.0.0.1

客户端进入服务端需要填写 地址:端口 ,注意这里的地址和端口需要换成你自己的,并且冒号一定要用英文的 : ,否则会无法连接。当你认为自己其他地方没有问题的时候请检查一下冒号是否写错了

修改端口

端口在 服务端文件夹/server.properties 文件中修改,此文件可以直接用文本文档打开

在其中找到 server-port=25565 (其他port项不用管),将其中的25565调整到你需要的端口(如非必要,不要修改端口,游戏中加入服务器时,端口是25565的服务器的地址可以不写端口)

端口可用数值1-65535,其中0不使用,1-1023为系统端口,也叫BSD保留端口,1024-65535为用户端口,又分为:BSD临时端口(1024-5000)和BSD服务器(非特权)端口(5001-65535),建议使用五位数端口以防止端口冲突

修改端口后需要重启服务器生效,如果重启时控制台报错 **** FAILED TO BIND TO PORT! 就代表你选择的端口被其他进程占用了,需要更换端口

指定地址

默认地址127.0.0.1可以理解为本机,也就是当你服务端和客户端在一台机器上的时候可以使用此地址连接到服务端

在同一局域网中可以通过 服务端所在机器的ip:服务端端口 连接到服务端,例如( 192.168.1.1:25565

如果要跨公网连接的话有以下几种方式

  1. 有自己的公网ip(公网ip在哪儿,服务端的机器也要在哪儿,不要说有个vps然后要自己电脑开的服能远程连接,不现实)
  2. 使用frp,也就是内网穿透,教程
  3. 使用自己的动态公网ip,教程

常见问题

no further information

连接时出现

意为你填写的地址没有响应

可能原因有

  1. 地址有错误
  2. 防火墙没关闭
  3. 安装组未放行(vps)

如果是vps,请关闭系统防火墙并配置安全组放行

如果是第三方服务商提供的机器,可以找服务商询问

Unknow Host

大概率是地址写错了,请检查地址种的冒号是否是英文的冒号 :

原版客户端进Forge服

你需要使用mod一致的客户端连接服务器

连接中止

可能的原因有很多,你应该

  1. 检查你的客户端mod是否与服务端mod对应
  2. 检查你的服务端和客户端日志
  3. 如果你看不懂日志,请把完整的日志文件发给看得懂的人让他帮你(问的时候先提供日志并且详细地描述问题)

关闭防火墙&安全组放行

Windows关闭防火墙

打开控制面板,找到 控制面板\系统和安全\Windows Defender 防火墙 ,在左侧找到 启用或关闭WindowsDefender防火墙 点击

设置如图 设置如图

将两个网络的防火墙都关闭后确定

Linux关闭防火墙

以下两种方式任选一种即可,一种用不了的换另一种

systemctl

启动:systemctl start firewalld

查看状态:systemctl status firewalld 

停止:systemctl disable firewalld

禁用:systemctl stop firewalld

iptable

查看防火墙状态:service iptables status

停止防火墙:service iptables stop

启动防火墙:service iptables start

重启防火墙:service iptables restart

关闭防火墙自启:chkconfig iptables off

开启防火墙自启:chkconfig iptables on

vps安全组放行端口

在进入vps实例的管理界面,找到安全组,注意安装组里面有出站规则和入站规则

出站规则放行全部(出站就是vps里的进程通过端口访问外网的内容)

入站放行常用端口,(如果开服的话也同时放行服务器端口)

出站规则 出站规则 入站规则 入站规则

DDNS教程

此教程需要花钱购买一个域名,腾讯云,阿里云等服务商均提供此服务且价格并不贵

购买域名的教程此处就不放了,以下的教程需要有域名

申请公网ip

首先移动用户可以关闭此教程了,移动的公网ip极难申请

联通和电信用户可以打电话给运营商要一个动态公网ip,如果问用来做什么的话可以说装监控

我就是电信用户,一个电话搞定

光猫改桥接

同样是打电话给运营商,让运营商把自己的光猫模式改成桥接

获取密钥

这里我是使用的腾讯云,就以腾讯云的控制台举例

首先进入腾讯云的控制台 https://console.dnspod.cn/

查看图片

进入DNSPod Token界面,如果没有密钥的新建一个

创建后拿到id和token

保存好id和token,不要泄露给不信任的人

使用DDNS程序动态解析ip到域名

这里我使用的是DDNS-GO https://github.com/jeessy2/ddns-go

 GitHub

jeessy2/ddns-go

在release界面中选择最新的适合你操作系统的构建并下载 https://github.com/jeessy2/ddns-go/releases

按照README.md中的使用教程启动之后,通过浏览器进入其设置界面

在此处填入之前保存的id和token 在此处填入之前保存的id和token 在IPV4下设置你要解析的域名 在IPV4下设置你要解析的域名

在IPV4下的Domains中填写你要解析的域名(如果是子域名需要自行添加域名解析,见/blog/腾讯云域名添加子域名解析/

IPV6按需设置,没有的不填

设置完成后点击最下方的SAVE

点击保存 点击保存

管理端口映射

此时我们已经可以通过域名访问我们的ip了,但是一般我们的网络和公网直接还隔了一个路由器

这里以华为的路由器为例

打开NAT服务 打开NAT服务

这里假设我的电脑上开了一个mc的服务端,使用25565端口,我要把它映射到公网ip的25565上

这里注意设备不要选错了,要选择对应的设备

设置映射 设置映射

保存之后就可以从外网连接了(如果连接不了的话请自行检查机器的防火墙)

注意

  1. ddns-go进程将会每隔一段时间检测一次ip变动,并在变动后更新域名对应的ip
  2. 根据解析端的dns不同,刷新时间会有出入,这里建议将dns设置为 119.29.29.29223.5.5.5
  3. 保持ddns-go的进程开启,不要关闭(linux可以使用screen)

Java下载

Minecraft1.17及以后的版本需要Java17

Minecraft1.16及以前的版本可以用Java8-15

推荐使用8/11这两个LTS的版本,LTS意为长期支持版本

高版本Java优点

包含更加合理高效的GC(垃圾回收)机制,运行效率更高

高版本Java缺点

一些插件或mod可能尚不支持高版本的Java

各种安装包的区别

一般Java分为Jre和Jdk,Jdk要略微大一些,但是从使用角度来看并没有什么区别

如果你的操作系统是64位的,下载时请选择64位(x86-6464bit

如果你知道如何配置Path,也可以下载zip或tgz格式的压缩包,并在解压后自行配置Path,否则请下载exe或msi格式(linux选择rpm等)的安装包,安装包会帮你配置Path

linux配置path

win配置path

链接

提供一些我知道的下载链接,你可以自行选择

DragonWell8:https://github.com/alibaba/dragonwell8/releases/latest (仅JDK8,阿里巴巴优化版本)

DragonWell11:https://github.com/alibaba/dragonwell11/releases/latest (仅JDK11,阿里巴巴优化版本)

AdoptOpenJDK:https://adoptium.net/releases.html (包含各个版本的Jdk和Jre)

AzulZuluJDK:https://www.azul.com/downloads/?architecture=x86-64-bit&package=jdk (包含各个版本的Jdk和Jre)

OracleJDK:https://www.oracle.com/java/technologies/javase/javase-jdk8-downloads.html (仅Jdk)

OracleJRE:https://www.oracle.com/java/technologies/javase-downloads.html (仅Jre)

linux设置路径(Path)

注意

本文教程中默认假设java文件夹位于 /usr/local/java,实际修改以你自己的java文件夹为准

Path意义

输入指令后计算机会查找对应的可执行文件,查找的路径就是Path

操作步骤

这里以设置java的路径举例,假设java文件夹位于 /usr/local/java ,你在操作的时候需要把 /usr/local/java 替换成自己的软件的路径

修改路径文件

打开系统路径文件

vi /etc/profile

进入编辑模式

在vi里面默认不是编辑模式

按i或者右侧方向键上面那一块里面的insert键进入编辑模式

左下角显示 -- INSERT ---- 插入 -- 时就是进入了编辑模式,注意不要使用替换模式

添加路径

在打开文件的最前面添加如下内容

export JAVA_HOME=/usr/local/java
export PATH=$PATH:$JAVA_HOME/bin


# 检查是否设置完成
java -version
# 如果显示 bash: java: 未找到命令... 就代表你改的有问题
# 如果显示了java的具体信息就代表修改成功

JAVA_HOME并非必须,也可以用改成如下方式(注意,两者二选一)

export PATH=$PATH:/usr/local/java/bin

按esc,输入 :wq 保存并退出

刷新路径

source /etc/profile

如果输入此指令后什么也没发生,别担心,这是正常情况,说明操作执行正常完了

检查路径

通过查看Java版本检查Java是否被加入进path

java -version

也可以直接查看path

echo $PATH

Minecraft服务端更换核心

保险起见,进行此操作前应该将服务端文件备份 (整个服务端文件夹打包或者复制一份都可)

以下所有操作均需要在关服时进行操作

服务端更新核心(不更换游戏版本)

将新的核心移动到服务端文件夹内

forge和fabric需要重新安装以下载需要的lib文件,单独复制核心并不能成功开服

然后修改开服脚本中的 -jar 参数后的核心名字

启动服务端后注意控制台,如果有报错需要注意

在确认没有问题后再删除旧的核心Jar文件

服务端更换核心

插件和mod是不互相兼容的,除非是没有安装插件或mod的情况下更换,否则不推荐

插件服和(mod服或插件mod服)互换核心时需要修改存档结构

修改方法

将新的核心移动到服务端文件夹内,然后修改开服脚本中的 -jar 参数后的核心名字

启动服务端后注意控制台,如果有报错需要注意

在确认没有问题后再删除旧的核心Jar文件

更换不同游戏版本的核心

如果是升级,1.12 -> 1.13,1.17 -> 1.18 等大更新不建议更换,及其容易出问题

如果是降级,想都别想

小更新将新的核心移动到服务端文件夹内,然后修改开服脚本中的 -jar 参数后的核心名字

启动服务端后注意控制台,如果有报错需要注意

在确认没有问题后再删除旧的核心Jar文件

Minecraft服务端换地图

保险起见,进行此操作前应该将服务端文件备份 (整个服务端文件夹打包或者复制一份都可)

客户端/官服存档结构

主世界中的区块存储在这个根文件夹中,下界则存储在子文件夹DIM-1中,末地则存储在DIM1中。每个维度都有其自己的datapoiregion文件夹。

https://wiki.biligame.com/mc/%E4%B8%96%E7%95%8C

具体存档结构见:https://wiki.biligame.com/mc/Java%E7%89%88%E4%B8%96%E7%95%8C%E6%A0%BC%E5%BC%8F

新的世界 ├─advancements ├─data ├─datapacks ├─DIM-1 下界 ├─DIM1 末地 ├─entities ├─playerdata ├─poi ├─region └─stats

插件服存档结构

服务端文件夹 ├─ world 主世界及存档通用数据文件 │ ├─ advancements │ ├─ data │ ├─ datapacks │ ├─ entities │ ├─ level.dat │ ├─ level.dat_old │ ├─ playerdata │ ├─ poi │ ├─ region │ ├─ session.lock │ ├─ stats │ └─ uid.dat ├─ world_nether 下界数据文件 │ ├─ data │ ├─ DIM-1 │ ├─ level.dat │ ├─ level.dat_old │ ├─ session.lock │ └─ uid.dat └─ world_the_end 末地数据文件 ├─ data ├─ DIM1 ├─ level.dat ├─ level.dat_old ├─ session.lock └─ uid.dat

MOD服存档结构

在原版的基础上可能会有其他维度的文件夹,一般是DIM-维度编号为名字的文件夹

更换地图

插件服和官服/mod服的存档互相更换时需要改变结构

插件服存档移动到官服/mod服/单机

world_netherworld_the_nether 中的DIM开头的文件夹移动到 world 文件夹中

然后将world文件夹整个移动到服务端中

反之,新建 world_netherworld_the_nether 文件夹,将DIM开头的文件夹移动到其中

注意,mod创建的维度无法移动到插件服,多世界插件创建的维度和主世界在迁移时仅可保留一个作为主世界(可以拆成一个单独的存档)

MinecraftMOD服安装/配置MOD

找mod

mod一般发布在curseforge上 https://www.curseforge.com/minecraft/modpacks (此网站国内不墙,但是访问需要过人机验证)

国内找mod推荐mc百科 https://www.mcmod.cn/modlist.html mod搬运较多;相比mcbbs的mod板块多了搜索功能,搜索功能完善,筛选条件够多,并且介绍/物品/教程都较全,格式规范;但是更新会有延迟,下载并不是都有,一般是找到mod之后通过其中的连接跳转到cursegorge下载最新版

mcbbs的mod板块 https://www.mcbbs.net/forum-mod-1.html

安装mod

首先分清楚客户端mod和服务端mod(mc百科的介绍界面有标注)

客户端mod是只在客户端生效的mod,在服务端毫无作用还有极大几率在启动时出错导致崩溃

一般添加了汉化,特效,修改了渲染等的mod就是服务端mod

例如小地图,optifine高清修复,血条,jei等

服务端mod分为纯服务端使用的服务端mod和客户端和服务端都使用的服务端mod

一般添加了新物品,新生物,新游戏机制的就是服务端mod

例如暮色森林,匠魂,工业等

纯服务端mod一般是指在服务端生效,且不需要客户端安装的mod(客户端可装可不装)

纯服务端mod比较少见,除非mod发布页面写了只需要服务端安装,否则都按服务端mod处理

例如平坦基岩生成

将mod加入mods文件夹 服务端文件夹/mods 然后重启服务端

配置mod

更新mod

如果mod作者没有注明需要操作什么,一般就是将旧的mod的Jar删除后将新的mod的Jar放进mods文件夹

汉化mod

mod的jar文件使用压缩软件打开,找到 assets/mod名字/lang 文件夹,其中会有一个或多个json文件,如果缺少zh_cn.json的话这个mod就无法显示中文的内容

此操作需要在客户端/服务端关闭的情况下进行

此时可以到网上找找有没有mod的汉化,如果没有并且想要自己汉化mod的可以将en_us.json复制一份出来,将其中的 "xxxx.xxx.xx": "yyyyyyyyyyyy" 格式的一段中的yyyyyyyyyyyy内容替换成中文内容,注意不要有json语法错误

推荐使用vscode并且安装json插件进行编辑

替换完成后保存并关闭,将此文件命名为zh_cn.json,然后放进上面在mod的Jar文件中找到汉化文件的文件夹中

此方法也可用于汉化光影包

Minecraft插件服安装/配置插件

找插件

插件一般发布在spigot上 https://www.spigotmc.org/search/?type=resource_update (此网站国内不墙,只有5秒的ddos检测)

国内找插件可以去mcbbs,搬运的插件一般都会汉化用法和配置文件,提供明确的获取方式 https://www.mcbbs.net/forum-servermod-1.html

安装插件

插件服的插件基本通用,版本向前兼容(比如支持1.13的插件,如果没有描述,多半支持1.14及以后的版本)

下载插件得到插件的jar文件后将jar文件移动到插件服的plugins文件夹中,然后重启服务端

如果启动时没有报错,并且启动完之后在控制台输plugins看到插件名字并且是绿字说明插件启动/安装成功

配置插件

使用汉化的语言/配置文件

汉化的语言文件有多种可能的使用方式

  1. 插件配置文件夹中有默认的语言文件,替换掉它
  2. 插件有语言文件夹,将语言文件(文件中带zh_CN或者类似的标识)放进去,然后在配置文件中搜索lang,找到后替换语言代码(一般为zh_CN)
  3. 插件自带汉化,在配置文件中搜索lang,找到后替换语言代码(一般为zh_CN)

配置文件的汉化一般是汉化了其中的注释,如果汉化文件不是最新的,建议对照着旧文件改插件自动生成的配置文件,否则可能会有错漏导致不可预知的后果

查看默认配置文件

插件的Jar文件使用压缩软件打开,里面会有默认的配置文件(注意不要修改其中的默认文件,复制出来即可)

此方法可以查看其自带的语言文件是否有自己需要的,以及它使用的语言代码格式

更新插件

如果插件作者没有注明需要操作什么,一般就是将旧的插件Jar删除后将新的插件Jar放进plugins文件夹

一些插件的链接

EssentialsX(包括本体和Protect,Chat,Spawn):提供大部分的基础指令和对玩家限制。使用时需要手动给default组添加权限。注意需要下载带X的版本

mcbbs:https://www.mcbbs.net/thread-619883-1-1.html

中文Wiki:https://mineplugin.org/Essentials

官网:https://essentialsx.net/

英文Wiki:https://essentialsx.net/wiki/Home.html

构建:https://ci.ender.zone/job/EssentialsX/

GitHub:https://github.com/EssentialsX/Essentials/

Luckperms:提供权限组管理,个人认为比GroupManager好用,安装完第一次启动可能比较慢,请耐心等待

mcbbs:https://www.mcbbs.net/thread-676818-1-1.html

官网:https://luckperms.net/

中文Wiki:https://pluginscdtribe.github.io/wiki/luckperms/

构建:https://ci.lucko.me/job/LuckPerms/

GitHub:https://github.com/lucko/LuckPerms/

AuthMeReloaded(开发版):提供登录功能,替代正版验证

mcbbs:https://www.mcbbs.net/thread-442729-1-1.html

官网:https://www.spigotmc.org/resources/authme-reloaded.6269

英文Wiki:https://github.com/AuthMe/AuthMeReloaded/tree/master/docs

构建:https://ci.codemc.io/job/AuthMe/job/AuthMeReloaded/

GitHub:https://github.com/AuthMe/AuthMeReloaded/

CoreProtect:记录玩家的几乎所有操作,提供按区域/玩家/时间回档的功能,防熊利器,但是要定期清理,不然会很占储存

mcbbs:https://www.mcbbs.net/thread-682499-1-1.html

官网:https://www.spigotmc.org/resources/coreprotect.8631/

中文Wiki:https://mineplugin.org/CoreProtect

Residence:领地插件,允许玩家圈地以保护自己的房屋农田等建筑。虽然是付费插件,但是提供了免费版下载,会限制在63格以上高度放置流体和中立方块,一定要手动关闭,方法见mcbbs帖子

mcbbs:https://www.mcbbs.net/thread-631343-1-1.html

官网:https://www.spigotmc.org/resources/residence-1-7-10-up-to-1-16.11480/

免费下载:https://zrips.net/Residence/

Github:https://github.com/Zrips/Residence

Vault:经济及部分插件的前置

官网:https://www.spigotmc.org/resources/vault.34315/

mcbbs(旧版本,仅供参考):https://www.mcbbs.net/thread-703488-1-1.html

中文Wiki:https://mineplugin.org/Vault

XConomy:经济插件,国产插件,作者修bug快,也可以用其他的经济插件代替

mcbbs:https://www.mcbbs.net/thread-962904-1-1.html (包含Wiki)

spigot:https://www.spigotmc.org/resources/xconomy.75669/

GitHub:https://github.com/YiC200333/XConomy

Skinsrestorer:皮肤插件,允许离线服务器显示正版皮肤(没办法,谁叫国内离线玩家多)

mcbbs:https://www.mcbbs.net/thread-805404-1-1.html

官网:https://www.spigotmc.org/resources/skinsrestorer.2124/

英文Wiki:https://github.com/SkinsRestorer/SkinsRestorerX/wiki

GitHub:https://github.com/SkinsRestorer/SkinsRestorerX

PlaceholderAPI:占位符变量,返回你需要的玩家数据,很多插件的软前置

mcbbs:https://www.mcbbs.net/thread-829732-1-1.html

官网:https://www.spigotmc.org/resources/placeholderapi.6245/

中文Wiki:https://mineplugin.org/PlaceholderAPI

LockettePro:木牌箱子锁

和LWCX相比牌子会占用一格空间,且给予的信任人数有上限,要给很多信任时建议使用圈地,但是使用简单

mcbbs(旧版本,仅供参考):https://www.mcbbs.net/thread-944015-1-1.html

官网:https://www.spigotmc.org/resources/lockettepro-for-1-14-1-15-1-16.74354/

GitHub:https://github.com/brunyman/LockettePro

英文Wiki:https://github.com/connection-lost/LockettePro/wiki

LWCX:箱子锁

和LockettePro相比不会有牌子占用一格空间,添加信任的数量无上限,容器放下即锁

mcbbs(旧版本,仅供参考):https://www.mcbbs.net/thread-892322-1-1.html

官网:https://www.spigotmc.org/resources/lwc-extended.69551/

GitHub:https://github.com/pop4959/LWCX

构建:https://ci.codemc.io/job/pop4959/job/LWCX-dev/

英文Wiki:https://github.com/pop4959/LWCX/wiki

Multiverse-Core:多世界插件,方便管理多个世界,是部分插件的前置

mcbbs:https://www.mcbbs.net/thread-1016455-1-1.html

官网:https://dev.bukkit.org/projects/multiverse-core(可能需要魔法上网)

中文Wiki:https://mineplugin.org/Multiverse-Core

构建:https://ci.onarandombox.com/job/Multiverse-Core/

GitHub:https://github.com/Multiverse/Multiverse-Core/

QuickShop Reremake:商店插件,允许使用箱子,末影箱等容器作为商店出售或收购物品

mcbbs:https://www.mcbbs.net/thread-809496-1-1.html(包含wiki)

官网:https://www.spigotmc.org/resources/quickshop-reremake-1-16-ready-say-hello-with-rgb.62575/

构建:https://ci.codemc.io/job/Ghost-chu/job/QuickShop-Reremake/

GitHub:https://github.com/Ghost-chu/QuickShop-Reremake

PlayerTitle:称号,国产插件

mcbbs:https://www.mcbbs.net/thread-1004671-1-1.html

spigot:https://www.spigotmc.org/resources/playertitle.78048/

FarmProtect:保护农田不被踩坏

mcbbs(旧版本,仅供参考):https://www.mcbbs.net/thread-797619-1-1.html

spigot:https://www.spigotmc.org/resources/farmprotect.6259/

Lite Sign In:签到,国产插件

mcbbs:https://www.mcbbs.net/thread-1056080-1-1.html

spigot:https://www.spigotmc.org/resources/lite-sign-in-1-7-1-16-sign-in-rewards-chest-gui-mysql-sqlite-customizable.79584/

Citizens:NPC插件

mcbbs:https://www.mcbbs.net/thread-797288-1-1.html(带wiki)

spigot:https://www.spigotmc.org/resources/citizens.13811/

Citizens CMD:点击NPC使用指令

mcbbs:https://www.mcbbs.net/thread-1002989-1-1.html

spigot:https://www.spigotmc.org/resources/citizens-cmd.30224/

TrMenu:菜单(2.0版本付费,但是GitHub有下载)

mcbbs:https://www.mcbbs.net/thread-918078-1-1.html

GitHub:https://github.com/TrMenu/TrMenu/actions

TrChat:修改聊天格式

mcbbs:https://www.mcbbs.net/thread-903335-1-1.html

Github:https://github.com/Arasple/TrChat/releases/tag/1.71

TrHologram:悬浮字

mcbbs:https://www.mcbbs.net/thread-923397-1-1.html

Github:https://github.com/Arasple/TrHologram/releases

Plotsquared:地皮

mcbbs:https://www.mcbbs.net/thread-573771-1-1.html

spigot:https://www.spigotmc.org/resources/plotsquared-v5.77506/

MiniMOTD:修改motd

mcbbs:https://www.mcbbs.net/thread-1075003-1-1.html

spigot:https://www.spigotmc.org/resources/minimotd-server-list-motd-plugin-with-rgb-gradients.81254/

TitleManager:修改玩家tab样式和右侧计分板

mcbbs:https://www.mcbbs.net/thread-810394-1-1.html

spigot:https://www.spigotmc.org/resources/titlemanager.1049/

ViaVersion:跨版本,允许其他版本的客户端进入服务器

mcbbs:https://www.mcbbs.net/thread-1023597-1-1.html

spigot:https://www.spigotmc.org/resources/viaversion.19254/

ViaBackwards:跨版本,兼容更低的版本

mcbbs(旧版本,仅供参考):https://www.mcbbs.net/thread-698692-1-1.html

spigot:https://www.spigotmc.org/resources/viabackwards.27448/

LaggRemover:优化

mcbbs(旧版本,仅供参考):https://www.mcbbs.net/thread-715006-1-1.html

官网:https://dev.bukkit.org/projects/laggremover  (可能需要魔法上网)

ScriptBlockPlus:脚本方块,点击/踩踏/挖掘时使用指令

mcbbs:https://www.mcbbs.net/thread-691900-1-1.html

spigot:https://www.spigotmc.org/resources/1-9-1-16-x-scriptblockplus-mechanics.78413/

VeinMiner:连锁挖矿

mcbbs:https://www.mcbbs.net/thread-600757-1-1.html

spigot:https://www.spigotmc.org/resources/veinminer.12038/

Marriage Master:结婚

mcbbs:https://www.mcbbs.net/thread-905947-1-1.html

spigot:https://www.spigotmc.org/resources/marriage-master-mc-1-7-1-16.19273/

IronElevators:铁块电梯

mcbbs:https://www.mcbbs.net/thread-612833-1-1.html

spigot:https://www.spigotmc.org/resources/ironelevators-1-4-6-1-16.19451/

Minecraft服务端配置文件

server.properties

这个文件是所有服务端(上面列出的主流服务端)都会生成的一个配置文件,位于核心Jar文件同级目录中

一些基础的参数需要在此文件中设置,下面会列出一些常用参数的用法(以1.16的为参考)

  1. allow-flight=false 允许玩家在安装添加飞行功能的mod前提下在生存模式下飞行
  2. allow-nether=true 允许玩家进入下界
  3. difficulty=easy 定义服务器的游戏难度
  4. enable-command-block=false 是否启用命令方块
  5. level-seed= 种子
  6. level-type=default 地图所生成的类型 default:标准的世界 flat:超平坦 largebiomes:巨大生物群系
  7. max-players=20 最大玩家数量
  8. max-tick-time=60000 最大刻时长,单位毫秒,当一个游戏刻的时长超过此数值后游戏会强行停止并崩溃(paper会保存存档、插件数据),设置为-1以禁用
  9. motd=A Minecraft Server 多人游戏界面服务器的信息
  10. online-mode=true 在线模式,设置为false允许离线模式的玩家进入服务器
  11. pvp=true 玩家pvp
  12. server-ip= 服务器ip,如果你不是清楚地知道你在改什么,让它留空,不要动它
  13. server-port=25565 服务器端口,如果你要开两个服务端或者有其他程序占用了25565端口的话可以自行修改
  14. view-distance=10 服务端视距,如果卡顿的话可以减小该值,可以设置为6
  15. white-list=false 白名单,如果开启,没有添加过白名单的玩家将会无法进入服务器,如果是离线模式的服务器,添加白名单的玩家必须进入过服务器,否则即使添加了白名单,此玩家也无法进入服务器(离线服务器建议用插件或mod实现白名单)

未列出的内容见 https://minecraft.fandom.com/zh/wiki/Server.properties#Java.E7.89.88_3

bukkit.yml

基于bukkit的服务端会生成此文件,位于核心Jar文件同级目录中

配置参考wiki(英文) https://bukkit.gamepedia.com/Bukkit.yml

spigot.yml

基于spigot的服务端会生成此文件,位于核心Jar文件同级目录中

配置参考wiki(英文) https://www.spigotmc.org/wiki/spigot-configuration/

paper.yml

基于paper的服务端会生成此文件,位于核心Jar文件同级目录中

参考wiki(英文) https://paper.readthedocs.io/en/latest/server/configuration.html

中文参考

以上文件的部分内容汉化+优化参考 https://www.mcbbs.net/thread-478126-1-1.html

插件配置

插件的配置文件一般都会生成在plugins文件夹中的插件同名文件夹内

一般使用yml文件作为配置文件,具体配置方法看插件发布贴作者的说明

yml文件可以直接用文本文档打开,但是没有语法高亮,推荐使用vscode并添加yaml插件

yml语法 https://www.runoob.com/w3cnote/yaml-intro.html (推荐小白看一看,只要了解基础的语法即可)

如果reload时配置文件有语法错误,后台会报一长串错误,并且指令的返回消息可能不会正常显示

mod配置

mod的配置一般在config文件夹中的mod名开头的文件/文件夹中,1.12前文件格式为cfg,之后为toml

一般文件中会有英文注释,如果看不懂不要乱改(先去机翻

这两种文件都可以直接用文本文档打开,但是没有语法高亮,推荐使用vscode并添加对应插件

Minecraft服务端搭建与运行

安装Java

开服需要安装Java (64位机器装64位Java)

安装Java教程

获取核心

首先选择自己要使用的核心和游戏版本

新建一个文件夹,确保其路径没有中文

下载核心后移动到此文件夹

此处注意,forge和fabric的核心是需要通过安装获得的,其他核心大多是一个单独的Jar文件,会自动下载需要的lib文件

移动核心时

  • forge请连着 libraries 文件夹一起
  • fabric请连着 .fabric.fabric-installer 两个文件夹一起

启动

官服的jar文件可以双击打开,但是其他的核心据我所知均需要使用开服脚本,开服脚本教程

现在的文件夹中应该有核心和启动脚本两个文件

win双击start.bat启动服务器,linux在命令行中输入./start.sh (无法执行的看脚本教程中的添加权限)

启动之后如果是没有自动重启的脚本会一闪然后关闭,此时文件夹中会自动生成 eula.txt

打开 eula.txt ,将其中的 false 改成 true (注意不要打错单词),保存并关闭

此时再启动脚本,服务端会正常启动

Minecraft服务端核心介绍及链接

本教程仅包含Java版的核心,基岩版不在此教程范围内

官服

Mojang官方发布的服务端,不支持插件/MOD,只支持数据包

因为Mojang网站的下载不好找并且只有最新版,所以这里放一个第三方的下载链接收集站

https://mcversions.net/

插件服

插件服是只能使用插件(Plugin)的服务端核心,包括以下几个主流的核心

插件服的插件基本通用,版本向前兼容(比如支持1.13的插件,如果没有描述,多半支持1.14及以后的版本)

  1. Bukkit https://getbukkit.org/
  2. Spigot(Bukkit的分支) https://www.spigotmc.org/ (不提供最新版下载,可以自行构建或寻找第三方构建站)
  3. Paper(Spigot的分支|优化性能) https://papermc.io/downloads (粘性活塞刷物品需要手动配置paper.yml启用,刷沙机不可用,配置方法见/blog/服务端配置/
  4. Airplane(Paper的分支|优化性能) https://ci.tivy.ca/
  5. Purpur(Paper的分支|性能最好) https://purpur.pl3x.net/downloads/
  6. 其他基于Bukkit的插件服

MOD服

MOD服是只能使用MOD的服务端核心,根据加载器的不同,分为以下两种核心

  1. Forge https://files.minecraftforge.net/net/minecraftforge/forge/
  2. Fabric https://fabricmc.net/use/

两者的mod不互通(作者标注了互通的除外)

注意,使用MOD服核心时客户端连接服务端需要

  1. 服务端和客户端的加载器版本(Forge/Fabric版本)一致
  2. 服务端和客户端的服务端MOD一致
  3. 服务端和客户端的服务端MOD版本一致

插件MOD服

同时支持插件和mod的服务端核心,有以下特点

  1. 性能比纯插件/MOD服差
  2. 并非兼容所有插件和mod(不兼容不一定是不能加载,也可能是某个功能不可使用/使用时出现异常)
  3. 客户端的连接同样需要满足和上述mod服相同的条件
  4. 新手服主强烈不建议使用

包括以下几个主流核心

  1. Mohist (使用Forge的mod和Bukkit插件,支持高版本) https://mohistmc.com/download/
  2. Arclight (使用Forge的mod和Bukkit插件,支持高版本) https://github.com/IzzelAliz/Arclight/releases
  3. CatServer (使用Forge的mod和Bukkit插件,仅支持1.12.2) https://catmc.org/
  4. Magma (使用Forge的mod和Bukkit插件,写此教程时尚未支持1.16) https://github.com/magmafoundation/Magma
  5. Sponge (使用Forge的mod和Sponge插件,仅支持1.12.2) https://www.spongepowered.org/

Minecraft服务端教程目录

本教程只讲Java版的核心,基岩版不在此教程范围内

搭建服务端相关

核心介绍

核心是开服所必备的东西,种类繁多,这里对其做简单的分类和介绍

开服脚本

一般开服的设置都比较多,每次都用命令行启动非常麻烦,所以使用脚本

安装Forge

Forge是一种mod加载器,安装了Forge,才可以使用mod(forge的mod)

安装Fabric

Fabric是新出来(相比较Forge)的一种加载器 ,安装了Fabric,才可以使用mod(fabric的mod)

搭建服务端

从零开始搭建一个服务端

配置服务端

搭建完服务端之后对齐进行配置(服务端/插件/mod)

插件相关

插件的安装和配置

mod相关

mod的安装和配置

其他开服相关

更换核心

从一个核心换到另一个核心,或者是更新核心

更换地图

更换地图

地址/端口

端口配置和常见连接服务器失败的解决办法

内网穿透

通过内网穿透使不在一个局域网中的朋友也能链接服务端

DDNS动态解析域名

使用ddns而不是内网穿透,带宽上限就是自己网络的带宽上限,少一个中转,延迟也会更低

日志/崩溃报告

日志/崩溃报告怎么看

Minecraft开服脚本

总是有人不看完就跑来问我,所以把常见问题及其解决办法放到最上面

常见问题

Unrecognized VM option 'xxx'

这里是你使用的开服脚本中的某个参数,不被你的Java接受

xxx可能是 +AggressiveOpts 也可能是 +UseCompressedOops 或者是你启动脚本中的其他不被接受的参数

解决办法:

将开服脚本中的包含xxx的那一段参数删除

Unrecognized VM option '+AggressiveOpts' 就删除 -XX:+AggressiveOpts

Unrecognized VM option ' +UseCompressedOops ' 就删除 -XX:+UseCompressedOops

Could not reserve enough space for object heap

设置了过大的内存

解决办法:

将开服脚本中的内存调小(注意,32位java的可用内存受限制,只能使用最大1.4G到1.6G的内存,解决办法是更换64位的Java)

将参数换成 -Xmx1G -Xms1G

内存分配一般是给系统所有可用内存大小的2/3(给系统和其他应用留出空间),如果你电脑的内存低于1G,就不要想着开服了

页面文件太小,无法完成操作

设置了过大的内存

解决办法:

将开服脚本中的内存调小(注意,32位java的可用内存受限制,只能使用最大1.4G到1.6G的内存,解决办法是更换64位的Java)

将参数换成 -Xmx1G -Xms1G

内存分配一般是给系统所有可用内存大小的2/3(给系统和其他应用留出空间),如果你电脑的内存低于1G,就不要想着开服了

1.17及以后版本使用了低于Java16的Java

Forge的报错 Forge的报错 Fabric的报错 Fabric的报错 Paper的报错 Paper的报错 Spigot的报错 Spigot的报错

只要出现了以上图片中类似的报错,就意味着你需要使用Java16

解决办法:(二选一)

  1. 在启动脚本中指定Java路径(推荐)(方法见上面指定Java的脚本)
  2. 卸载其他版本的Java,只留Java16(不推荐)

1.16及以前版本使用了高于(包括)Java16的Java

只要出现了以上图片中类似的报错,就意味着你需要使用Java16之前的版本(不包括Java16,Java8/11等LTS版本都是不错的选择)

解决办法:(二选一)

  1. 在启动脚本中指定Java路径(推荐)(方法见上面指定Java的脚本)
  2. 卸载其他版本的Java,只留Java8/11(不推荐)

注意

本教程中均以server.jar作为核心名字,实际使用时请手动改成你的服务端核心jar名字

开服需要安装Java (64位机器装64位Java)

安装Java教程

通用

开服所用的指令就一条,一般是java开头的那一条,其他部分都是起辅助作用的,比如设置cmd窗口标题、自动重启等

这里拿一个典型的开服指令举例 java -Xmx2G -Xms2G -jar server.jar nogui

这里的 server.jar 是示例,实际使用时请手动改成核心jar的名字

Java

橙色字 java 意为使用可执行文件java,一般java需要在path中(设置path linux win),如果需要指定使用的java的话需要修改path中的java或者使用绝对路径

脚本使用绝对路径指定使用的java(点击展开)

以下的红字为修改的内容
如果你已经有开服命令了,只需要单独替换开头的 java

windows
假设java路径位于 C:\Program Files\Java\jdk1.8.0_301\bin\java
一般的脚本 java -Xmx2G -Xms2G -jar server.jar nogui
需要改为 "C:\Program Files\Java\jdk1.8.0_301\bin\java" -Xmx2G -Xms2G -jar server.jar nogui
linux(不知道是啥的不需要看)
假设java路径位于 /usr/local/jdk1.8.0_301/bin/java
一般的脚本 java -Xmx2G -Xms2G -jar server.jar nogui
需要改为 /usr/local/jdk1.8.0_301/bin/java -Xmx2G -Xms2G -jar server.jar nogui

JVM参数

红色字 -Xmx2G -Xms2g -jar 是jvm参数

设置jvm参数是开服非常重要的一环,使用的最大内存,最小内存,优化参数等都是jvm参数

-Xmx2G 设置最大可用内存为2G,这里红字的2G可以替换成其他内存大小,单位除了G之外可以用M,例如 -Xmx256M

-Xms2G 设置初始内存为2G,这里红字的2G可以替换成其他内存大小,单位除了G之外可以用M,例如 -Xms256M

-jar 意为通过jar文件启动,后面需要接文件名字,如果后面接的jar文件名字错误或者jar文件损坏则会报错

其他优化参数见 https://aikar.co/2018/07/02/tuning-the-jvm-g1gc-garbage-collector-flags-for-minecraft/

MC服务端参数

紫色字 nogui 意为不显示mc自带的ui界面,不管是否添加此参数,服务端始终会将日志输出至命令行

自带的UI界面效果如下(下图是paper的,和原版略有区别)

Windows

创建脚本

在服务端文件夹新建一个txt文件,将其改名为start.bat

若文件没有显示默认的txt扩展名

编辑脚本

右键bat文件,点击编辑

打开后输入下方的开服代码

如果是新建的脚本,文件>另存为 下方的编码选择ANSI,否则中文会乱码,保存

WIN脚本示例

@ECHO OFF
@REM 作者404E
set a=0
echo ------------------------------------------------------------------
echo --                                                              --
echo --                           正在启动                           --
echo --                                                              --
echo ------------------------------------------------------------------
:start
set b = %date:~0,4%.%date:~5,2%.%date:~8,2% %time:~0,2%:%time:~3,2%:%date:~8,2%
title 服务端 重启%a%次 上次重启于%b%
set date1=%date:~0,4%%date:~5,2%%date:~8,2%
set time1=%time:~0,2%%time:~3,2%%time:~6,2%
java -Xms2G -Xmx2G -XX:+UseG1GC -XX:+ParallelRefProcEnabled -XX:MaxGCPauseMillis=200 -XX:+UnlockExperimentalVMOptions -XX:+DisableExplicitGC -XX:+AlwaysPreTouch -XX:G1NewSizePercent=30 -XX:G1MaxNewSizePercent=40 -XX:G1HeapRegionSize=8M -XX:G1ReservePercent=20 -XX:G1HeapWastePercent=5 -XX:G1MixedGCCountTarget=4 -XX:InitiatingHeapOccupancyPercent=15 -XX:G1MixedGCLiveThresholdPercent=90 -XX:G1RSetUpdatingPauseTimePercent=5 -XX:SurvivorRatio=32 -XX:+PerfDisableSharedMem -XX:MaxTenuringThreshold=1 -Dusing.aikars.flags=https://mcflags.emc.gs -Daikars.new.flags=true -jar server.jar nogui
set date2=%date:~0,4%%date:~5,2%%date:~8,2%
set /a c=%time:~0,2%%time:~3,2%%time:~6,2% - %time1%
if %c% LEQ 1 (
    if %date2% == %date1% (
        echo ------------------------------------------------------------------
        echo --                                                              --
        echo --                  :( 启动异常,请检查启动参数                  --
        echo --                  或者咨询其他人,按任意键退出                 --
        echo --                                                              --
        echo ------------------------------------------------------------------
        pause>null
        exit
    )
)
set /a a=%a%+1
echo ------------------------------------------------------------------
echo --                                                              --
echo --                       将在3秒后自动重启                      --
echo --                       按任意键跳过等待                       --
echo --                      或者直接关闭服务端                      --
echo --                                                              --
echo ------------------------------------------------------------------
timeout /T 3
goto start

以上是我用的脚本,优化参数 https://aikar.co/2018/07/02/tuning-the-jvm-g1gc-garbage-collector-flags-for-minecraft/

Linux步骤

创建&编辑脚本

vi start.sh

按i或insert键进入编辑模式

输入下方示例的中的脚本代码

按esc,输入:wq保存

给予可执行权限

使用 sudo chmod +x start.sh 给脚本添加可执行权限(root用户可不加sudo,直接使用chmod)

脚本示例

#!/bin/bash
#作者404E
echo '------------------------------------------------------------------'
echo '-                                                                -'
echo '-                         开始启动服务端                         -'
echo '-                                                                -'
echo '------------------------------------------------------------------'
while true;
do
    java -Xms2G -Xmx2G -XX:+UseG1GC -XX:+ParallelRefProcEnabled -XX:MaxGCPauseMillis=200 -XX:+UnlockExperimentalVMOptions -XX:+DisableExplicitGC -XX:+AlwaysPreTouch -XX:G1NewSizePercent=30 -XX:G1MaxNewSizePercent=40 -XX:G1HeapRegionSize=8M -XX:G1ReservePercent=20 -XX:G1HeapWastePercent=5 -XX:G1MixedGCCountTarget=4 -XX:InitiatingHeapOccupancyPercent=15 -XX:G1MixedGCLiveThresholdPercent=90 -XX:G1RSetUpdatingPauseTimePercent=5 -XX:SurvivorRatio=32 -XX:+PerfDisableSharedMem -XX:MaxTenuringThreshold=1 -Dusing.aikars.flags=https://mcflags.emc.gs -Daikars.new.flags=true -jar server.jar nogui
    echo '------------------------------------------------------------------'
    echo '-                                                                -'
    echo '-                       服务器将在3秒后重启                      -'
    echo '-                     按 ctrl + c 停止服务端                     -'
    echo '-                                                                -'
    echo '------------------------------------------------------------------'
    for i in $(seq 3 -1 1)
    do
        echo -n "·"
        sleep 1s
    done
    echo ''
    echo '------------------------------------------------------------------'
    echo '-                                                                -'
    echo '-                         开始重启服务端                         -'
    echo '-                                                                -'
    echo '------------------------------------------------------------------'
done

以上是我用的脚本,优化参数 https://aikar.co/2018/07/02/tuning-the-jvm-g1gc-garbage-collector-flags-for-minecraft/

重启时自动备份的脚本

#!/bin/bash
#作者404E
echo '------------------------------------------------------------------'
echo '-                                                                -'
echo '-                         开始启动服务端                         -'
echo '-                                                                -'
echo '------------------------------------------------------------------'
while true;
do
    java -Xms2G -Xmx2G -XX:+UseG1GC -XX:+ParallelRefProcEnabled -XX:MaxGCPauseMillis=200 -XX:+UnlockExperimentalVMOptions -XX:+DisableExplicitGC -XX:+AlwaysPreTouch -XX:G1NewSizePercent=30 -XX:G1MaxNewSizePercent=40 -XX:G1HeapRegionSize=8M -XX:G1ReservePercent=20 -XX:G1HeapWastePercent=5 -XX:G1MixedGCCountTarget=4 -XX:InitiatingHeapOccupancyPercent=15 -XX:G1MixedGCLiveThresholdPercent=90 -XX:G1RSetUpdatingPauseTimePercent=5 -XX:SurvivorRatio=32 -XX:+PerfDisableSharedMem -XX:MaxTenuringThreshold=1 -Dusing.aikars.flags=https://mcflags.emc.gs -Daikars.new.flags=true -jar server.jar nogui
    # 备份
    echo '------------------------------------------------------------------'
    echo '-                                                                -'
    echo '-                     服务器将在3秒后开始备份                    -'
    echo '-                     按 ctrl + c 停止服务端                     -'
    echo '-                                                                -'
    echo '------------------------------------------------------------------'
    for i in $(seq 3 -1 1)
    do
    echo -n "·"
    sleep 1s
    done
    # 备份保留个数
    c=5
    if [ ! -d "backup" ];then
    mkdir backup
    fi
    rm -rf backup/$c.tar.gz
    for((i=$c;i>0;i--));
    do if [ -f "backup/"$i".tar.gz" ];then
    mv backup/$i.tar.gz backup/`expr $i + 1`.tar.gz
    fi done
    # 创建备份指令,可自行添加文件夹(将#去掉)
    tar -zcf backup/1.tar.gz world #world_nether world_the_end
    # 备份结束
    echo '------------------------------------------------------------------'
    echo '-                                                                -'
    echo '-                  备份完成  服务器将在3秒后重启                 -'
    echo '-                     按 ctrl + c 停止服务端                     -'
    echo '-                                                                -'
    echo '------------------------------------------------------------------'
    for i in $(seq 3 -1 1)
    do
        echo -n "·"
        sleep 1s
    done
    echo ''
    echo '------------------------------------------------------------------'
    echo '-                                                                -'
    echo '-                         开始重启服务端                         -'
    echo '-                                                                -'
    echo '------------------------------------------------------------------'
done

基于sakura frp的内网穿透

首先你要知道的事情有

  1. sakura frp需要花一块钱实名才能使用
  2. 默认是有带宽限制的(人数不多的话没影响)
  3. 目前能白嫖的节点较少(好用的服务器都被白嫖的占满了)
  4. vip不是必须,但是vip节点和更高的速度确实很香
  5. frp只需要开服或者是对局域网开放的那一方才需要下载使用

注册/登录 账号

在Sakura frp的官网注册 https://www.natfrp.com/

下载frp客户端

进入管理面板 https://www.natfrp.com/user/

点击进入软件下载并选择适合自己操作系统的客户端下载

下载的exe打开并且完成安装

客户端登录

在网页上的管理面板点击进入用户信息

访问密钥默认不显示,鼠标左键点击一次后显示。选中并复制

打开安装好的客户端

创建隧道

此时你应该知道你内网穿透的端口和协议

点击左侧的隧道并且在最上方找到加号,点击创建新隧道

进入隧道创建界面后需要填写的有

  1. 本地ip (如没有特殊情况写 127.0.0.1
  2. 端口 (MC Java服务端默认 25565;Java版客户端每次对局域网开放的端口都是随机的,需要自行填写;基岩版服务端默认 19132
  3. 隧道类型 (MC Java服务端默认 TCP,基岩版服务端默认 UDP
  4. 穿透节点 (选择离自己和联机的朋友都相对较近的区域的节点,最好选择多线的服务器)

其他选项

  1. 隧道名称:留空/自己命名
  2. 备注:同上
  3. 远程端口:可以自己自定义,但是大部分端口已经有人使用,所以大概率要试好几次才能找到一个没人用的端口,故推荐留空让服务器分配

完成后点击创建,弹出的界面询问是否继续创建选择否

开启隧道 & 查看地址

此时隧道虽然创建完毕,但是需要手动开启

手动开启隧道后在左侧找到日志选项,在最下面找到隧道的映射地址,首先自己测试连接正常后即可将地址给别人,让他通过此地址进行连接

此时内网穿透已经完成

注意 & 常见问题

内网穿透的服务器数量少:除非花钱买vip,用vip节点,否则无解,满了的服务器怎么给你用?

客户端对局域网开放关闭重新开之后连接不了:每次对局域网开放的端口都是随机的,需要重新创建隧道(或者使用联机mod设置端口为固定端口)

vip流量:只是放宽了带宽限制,对于人数不是非常多的服务器来说并没有必要,在默认的带宽限制下也是可以正常游玩的

使用内网穿透进入服务器的玩家地址都是127.0.0.1,绝对不要banip,会导致所有通过内网穿透进入服务器的玩家都无法进入服务器

修改DNS

DNS意义

域名系统(Domain Name System,DNS)是Internet上解决网上机器命名的一种系统。就像拜访朋友要先知道别人家怎么走一样,Internet上当一台主机要访问另外一台主机时,必须首先获知其地址,TCP/IP中的IP地址是由四段以“.”分开的数字组成(此处以IPv4的地址为例,IPv6的地址同理),记起来总是不如名字那么方便,所以,就采用了域名系统来管理名字和IP的对应关系。

来自百度百科 https://baike.baidu.com/item/dns/427444#viewPageContent

一般没有设置的时候DNS是运营商提供的,运营商提供的NDS更新慢,解析也慢(起码我这边是这样的)

我使用的是119.29.29.29和223.5.5.5

修改步骤

右键桌面右下角任务栏的网络图标

点击打开网络与Internet设置

点击高级网络设置中的更改适配器选项

打开后选择当前使用的网络右键

如果用的是wifi就选择WLAN,如果用的有限网络就选择以太网或者本地连接,如果不确定就都改一遍

点击Internet协议版本4(TCP/IPv4),然后点击属性

将DNS的两个选项修改为

119.29.29.29223.5.5.5

点击确定,完成dns的修改

win10设置路径(Path)

Path意义

输入指令后计算机会查找对应的可执行文件,查找的路径就是Path

进入设置界面

首先在桌面右键此电脑,点击属性

右键此电脑,点击属性 右键此电脑,点击属性

点击右侧的高级系统设置

点击高级系统设置 点击高级系统设置

点击环境变量

点击环境变量 点击环境变量

进入如下的环境变量设置界面

环境变量设置界面 环境变量设置界面

设置路径

这里有两个设置,一个是用户变量,一个是系统变量,我个人比较喜欢设置系统变量,如果设置用户变量,那换一个用户登录之后就要重新设置一遍,不方便

在系统变量里找到Path,点击右下角的编辑(一定不要点到新建),打开如下界面

Path的编辑界面 Path的编辑界面

这里是我们系统的各种环境变量,里面的内容因电脑而异,不必纠结多了少了

添加Path变量

有两种方式添加路径

  1. 直接在右侧点击新建然后输入路径
  2. 在系统变量里面设置一个路径,然后在这里引用

这里以java为例,假设java安装在D:\Java文件夹中

方法一

点击右侧的新建

新建 新建

在里面输入路径(大部分软件的可执行文件会放在bin文件夹里,java也是如此)

输入D:\Java\bin,然后一路确定

保存后win+r打开cmd界面,并在里面输入java -version检查是否正确,如果返回的是

'java' 不是内部或外部命令,也不是可运行的程序
或批处理文件。

那就代表有问题,反之要是显示了java的具体信息那就是没有问题

方法二

在系统变量里面新建一个变量,并且输入

新建环境变量 新建环境变量

确定之后再进入Path的编辑界面(进入方式同上)

在Path编辑界面里点击新建并且输入 %JAVA_HOME%\bin

这里的%JAVA_HOME%就等于是之前输入的D:\Java

在Path里面添加java的路径 在Path里面添加java的路径

之后也是一路确定

保存后win+r打开cmd界面,并在里面输入java -version检查是否正确,如果返回的是

'java' 不是内部或外部命令,也不是可运行的程序
或批处理文件。

那就代表有问题,反之要是显示了java的具体信息那就是没有问题

其他的路径也是类似的方式添加,这里就不再赘述