小原酱
小原酱
发布于 2025-11-01 / 40 阅读
0
0

为mc服务器加速!端口转发+frp

背景介绍

purecraft是一个跑在电信家庭网络的物理机上的我的世界服务器,物理位置在广东省广州市,网络是中国电信,动态公网v4,我的网络环境是广东韶关移动,由于跨网,我进服后看到玩家都会飞天遁地,一气之下决定搭建一个加速节点。

解决方案:端口转发

由于小原有一台杭州阿里云2h2g200M的服务器,于是聪明的小原立刻想到了用杭州服务器充当中转服务器,通过nginx把tcp流量的25565端口转发到广州服务器源站的25565端口,于是小原打开1panel,点击网站 => 设置 => 配置修改 ,把配置文件改成了下面这样

user  root;
worker_processes  auto;
error_log  /var/log/nginx/error.log notice;
error_log  /dev/stdout notice;
pid        /var/run/nginx.pid;
worker_rlimit_nofile 51200;

events {
    use epoll;
    worker_connections 5120;
    multi_accept on;
}

# TCP/UDP 代理配置
stream {
    # 定义 stream 模块的日志格式
    log_format basic '$remote_addr [$time_local] '
                     '$protocol $status $bytes_sent $bytes_received '
                     '$session_time "$upstream_addr" '
                     '"$upstream_bytes_sent" "$upstream_bytes_received" "$upstream_connect_time"';

    # 定义 Minecraft 服务器转发
    upstream minecraft_backend {
        server 8.148.242.137:25565;
    }

    server {
        listen 25565;
        proxy_pass minecraft_backend;
        proxy_timeout 60s;
        proxy_connect_timeout 10s;
        proxy_buffer_size 16k;
        
        # 使用定义的日志格式
        access_log /var/log/nginx/minecraft_access.log basic;
        error_log /var/log/nginx/minecraft_error.log;
    }
}

http {
    include       mime.types;
    default_type  application/octet-stream;
    
    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';
    
    access_log  /var/log/nginx/access.log  main;
    access_log /dev/stdout main;  # 容器环境下有用
    
    server_tokens off;  # 安全推荐
    sendfile   on;
    tcp_nopush on;       
    tcp_nodelay on;  

    server_names_hash_bucket_size 512;
    client_header_buffer_size 32k;
    large_client_header_buffers 4 32k;
    client_max_body_size 50m;
    keepalive_timeout 60;
    keepalive_requests 100;

    gzip on;
    gzip_min_length  1k;
    gzip_buffers     4 16k;
    gzip_http_version 1.1;
    gzip_comp_level 2;
    gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
    gzip_vary on;
    gzip_proxied expired no-cache no-store private auth;
    gzip_disable "MSIE [1-6]\.";

    # 连接限制配置
    limit_conn_zone $binary_remote_addr zone=perip:10m;
    limit_conn_zone $server_name zone=perserver:10m;

    # 包含路径配置
    include /usr/local/openresty/nginx/conf/conf.d/*.conf;
    include /usr/local/openresty/nginx/conf/default/*.conf;
    include /usr/local/openresty/1pwaf/data/conf/waf.conf;
}

然后保存,1p面板自动重载了配置文件,这个时候中转加速节点就搭建起来了。

然后小原把地址添加进游戏,进服后按下f3+3,分别测量了源站和加速后的数据,结果如下:

加速前

加速前

加速后

很明显加速后稳定了很多,但是平均延迟和最低延迟变高了,为什么呢?

因为当小原直连时数据是这样被发送的:

韶关移动 => 广州移动 => 跨网服务器 => 广州电信 => 服务器源站 (简化版,不代表实际数据)

如果用中转之后是这样子的:

我们直接看路由追踪数据

ComputerName           : ***.***.***
RemoteAddress          : 118.178.*.*
InterfaceAlias         : 以太网 4
SourceAddress          : 192.168.5.9
PingSucceeded          : True
PingReplyDetails (RTT) : 40 ms
TraceRoute             : 192.168.5.1
                         172.20.0.1
                         0.0.0.0
                         0.0.0.0
                         0.0.0.0
                         0.0.0.0
                         0.0.0.0
                         120.199.237.98
                         0.0.0.0
                         0.0.0.0
                         0.0.0.0
                         0.0.0.0
                         118.178.183.*
traceroute to ***.*******.meowhead.cn (113.109.243.218), 30 hops max, 60 byte packets
 1  10.12.208.166 (10.12.208.166)  2.256 ms  2.272 ms  2.225 ms
 2  10.12.208.77 (10.12.208.77)  6.757 ms 11.73.92.214 (11.73.92.214)  5.824 ms 11.73.92.174 (11.73.92.174)  6.845 ms
 3  10.255.101.101 (10.255.101.101)  2.093 ms 11.94.57.57 (11.94.57.57)  1.953 ms 10.216.254.230 (10.216.254.230)  1.766 ms
 4  * 11.94.131.221 (11.94.131.221)  2.987 ms 11.94.129.46 (11.94.129.46)  3.052 ms
 5  10.216.239.78 (10.216.239.78)  3.840 ms 10.216.239.74 (10.216.239.74)  3.837 ms 10.216.239.62 (10.216.239.62)  3.273 ms
 6  122.224.214.69 (122.224.214.69)  4.153 ms 115.238.21.118 (115.238.21.118)  3.761 ms 122.224.214.73 (122.224.214.73)  3.332 ms
 7  220.191.200.233 (220.191.200.233)  8.221 ms 115.233.23.165 (115.233.23.165)  6.919 ms 220.191.200.221 (220.191.200.221)  6.754 ms
 8  * 202.97.13.53 (202.97.13.53)  23.007 ms 202.97.47.9 (202.97.47.9)  20.990 ms
 9  * 183.56.34.30 (183.56.34.30)  24.136 ms *
10  218.19.217.226 (218.19.217.226)  29.870 ms  29.289 ms 113.98.79.130 (113.98.79.130)  31.559 ms
11  113.109.243.218 (113.109.243.218)  27.587 ms  25.120 ms  26.950 ms
12  113.109.*.* (113.109.243.218)  27.650 ms  26.974 ms  26.108 ms

很明显一跳一跳又一跳,为什么这样子会更稳定呢?因为阿里云自带BGP,没有跨网,丢包下降,但是跳数增加了,延迟就提升了,几乎在中国东边绕了一圈,直接变成减速器了,但是DeepSeek觉得虽然跳数增加,但延迟可能反而降低:

  • Windows直连: 40ms (跨运营商:移动→电信)

  • 通过跳板: 40ms(移动) + 27ms(电信) ≈ 67ms

想了半天的小原想起了一句话:实践是检验真理的唯一标准。

于是小原便发到了服务器群里面:

没想到对服主提升巨大,并加到了群公告里面!

玩了一个星期的小原发现其他北方地区玩家是提升巨大了,但她自己玩有个蛋用,于是一气之下让同学帮忙实名阿里云,用新用户优惠买广州服务器重新配。

这次为了降低占用和节省时间,小原使用了GMSSH,输入服务器IP和SSH密码后直接在线进入面板,无需下载/安装,进入后用wget下载Nginx最新代码,解压,make

在GMSSH应用商店中下载Nginx管理器,选择Nginx默认安装到的位置,选择默认配置,和上面一样如法炮制,但是这次小原想到了动态公网ip变化后,如果没有重新解析,这个转发将无法工作,想重新解析只能重启,所以这次她配置了

resolver 223.5.5.5 119.29.29.29 valid=20s;

resolver_timeout 5s;

但是过了几天她发现并没有什么卵用,一样会报错,并且不知道源站服务器是不是挂了,于是她决定改用frp。

为什么要选Frp呢?因为Frp可以解决动态公网ip变化无法实时感知的问题,大幅度提高了稳定性

因为正常来说端口转发获取ip依赖ddns的域名,当公网ip变化过一会后,ddns才能检测到公网ip变化(即使只有3-5s重测都是有空窗期的),当ddns检测到ip变化后会通知dns域名解析商,将域名指向新的ip地址,这个时候dns广播时间几乎是不可控的,还有运营商dns缓存,公共dns解析节点缓存……会导致最长可达10分钟的解析不同步,正常来说短3-8s游戏就断线重连了,超过10s对于玩家来说都明显感受到被退出主界面了,但当我们使用frp,运营商更换ip后,网络重新连接后,第一个心跳包到达服务器最多不会超过3s,这个时候对于玩家来说就是突然卡了一下或者无感,效果是非常好的。

在我们介绍实现之前先补充一下服务器的相关信息:

杭州阿里云——Ubuntu24.04 2h2g200M

广州阿里云——Centos9 2h2g200M

广州电信家里云——windows ?h32g??M

解决方案:Frp

用Frp之前我们先来了解一下Frp,Frp有服务端(Frps)和客户端(Frpc)组成,在Frps中需要配置一个端口和密钥,在Frpc中通过相同的端口密钥连接服务器,然后在客户端配置文件中还需要包含你需要穿透的端口和协议类型。

Frp需要把客户端安装在运行MC游戏服务器的同一台机子上,必须要腐竹支持才能配置,上文提到,所以小原给腐竹简单说明了一下就开始配frps了,由服主在服务器配置frpc。

划重点:

从v0.52.0版本开始,frp 开始支持TOML、YAML和JSON 作为配置文件格式。

请注意,INI已被弃用,并将在未来的发布中移除新功能只能在TOML、YAML或JSON中使用。希望使用这些新功能的用户应相应地切换其配置格式。

——Frp官网

所以我们的服务器很简单,只要这样子:

bindPort: 896*
#(你的端口)我这个端口比较神人,所以不能告诉你
auth:
  token: "你的链接口令"

# 可选:日志配置
log:
  level: "info"
  maxDays: 3
  disablePrintColor: false

然后客户端通过

serverAddr: "服务器地址"
serverPort: 89**
#端口
auth:
  token: "你的链接口令,和服务器的要一模一样"

proxies:
  - name: "minecraft"
    type: "tcp"
    localIP: "127.0.0.1"
    localPort: 25565
    remotePort: 25565

  - name: "rdp"
    type: "tcp"
    localIP: "127.0.0.1"
    localPort: 3389
    remotePort: 3389

链接上服务器,

有人可能就想问了:为什么要转发rdp啊?因为运维让我也顺便转发一下rdp。

总之这样子就是好了,然后就可以进游戏看看了。

平均18ms,emm...一般般吧,起码不用重启了。

好了结束了,给个图:


评论