mirror of
https://gitee.com/xmz7891/ykxmz.git
synced 2026-10-18 13:40:45 +00:00
加一份免费托管方案调研文档
用户问:网上有没有免费办法托管中转服务。 查了协议架构:全是 HTTP 长轮询(agent/register、agent/poll、 agent/send、agent/bye),没有裸 TCP —— 所以托管选择面很宽。 另外 relay.py 是纯 Python 标准库、零第三方依赖、仅 150 KB、 实测内存 23 MB / CPU 0.1%,任何免费实例都装得下。 关键洞察:一旦有了公网 IP,**根本不需要 Cloudflare 隧道**, 现在所有 1033/502/530 都是隧道这一跳的问题,换过去就从根上消失。 文档里对比了 6 个方案(永久性、是否需公网 IP、是否要信用卡、 亚洲节点、能否免隧道),推荐 Oracle Cloud Always Free 首选 (永久免费 + 真公网 IP + 东京/首尔节点), ClawCloud Run 作为不用信用卡的备选。 还写了具体的搬迁步骤和要删掉的组件。
This commit is contained in:
@@ -1,23 +0,0 @@
|
|||||||
修管理页顶栏被切掉(标题看不见、徽章压在字上)
|
|
||||||
|
|
||||||
用户截图圈出顶栏:主标题「ykxmz 中转站」被切掉看不见,
|
|
||||||
「运行中」徽章压在副标题上。
|
|
||||||
|
|
||||||
根因:
|
|
||||||
.top-in 用了固定 height:62px。
|
|
||||||
但顶栏内容比 62px 高:
|
|
||||||
左边品牌是「标题 + 副标题」两行
|
|
||||||
右边是「版本信息 + 累计请求」两行
|
|
||||||
flex 容器固定高度装不下,内容就被往上顶出去了 ——
|
|
||||||
于是标题被切在容器外,徽章挤到文字上。
|
|
||||||
|
|
||||||
修法:
|
|
||||||
* height:62px 改成 padding:13px 0 + min-height:36px
|
|
||||||
(内容多高就是多高,别再写死)
|
|
||||||
* 给 logo / brand / state 都加 flex:none,别被压缩
|
|
||||||
* 标题副标题加 white-space:nowrap,避免换行错位
|
|
||||||
* 右上的版本信息允许收缩(min-width:0)
|
|
||||||
* 窄屏(<640px)时状态徽章换行,不跟标题挤
|
|
||||||
|
|
||||||
实测:1200px 和 700px 两档宽度下顶栏都正常,
|
|
||||||
标题、副标题、徽章、右侧信息全部各就各位。
|
|
||||||
+31
-13
@@ -21,25 +21,43 @@ a{color:inherit}
|
|||||||
/* ---------- 吸顶顶栏 ---------- */
|
/* ---------- 吸顶顶栏 ---------- */
|
||||||
.top{position:sticky;top:0;z-index:40;background:rgba(255,255,255,.88);
|
.top{position:sticky;top:0;z-index:40;background:rgba(255,255,255,.88);
|
||||||
backdrop-filter:saturate(180%) blur(12px);border-bottom:1px solid var(--border)}
|
backdrop-filter:saturate(180%) blur(12px);border-bottom:1px solid var(--border)}
|
||||||
.top-in{display:flex;align-items:center;gap:12px;height:62px}
|
/*
|
||||||
|
* ⚠ 别用固定 height。
|
||||||
|
* 原来写的是 .top-in{height:62px},但里面品牌是「标题 + 副标题」两行、
|
||||||
|
* 右边还有两行版本信息 —— 实际内容比 62px 高,
|
||||||
|
* flex 就把内容往上顶出去了:**标题被切掉、运行中徽章压在字上**
|
||||||
|
* (用户截图里就是这样)。
|
||||||
|
* 改成 padding 撑开,内容多高就是多高。
|
||||||
|
*/
|
||||||
|
.top-in{display:flex;align-items:center;gap:12px;
|
||||||
|
padding-top:13px;padding-bottom:13px;min-height:36px}
|
||||||
.logo{width:32px;height:32px;border-radius:9px;flex:none;
|
.logo{width:32px;height:32px;border-radius:9px;flex:none;
|
||||||
background:linear-gradient(140deg,#2563eb,#1d4ed8);
|
background:linear-gradient(140deg,#2563eb,#1d4ed8);
|
||||||
display:flex;align-items:center;justify-content:center;
|
display:flex;align-items:center;justify-content:center;
|
||||||
color:#fff;font-weight:700;font-size:12px;letter-spacing:-.3px}
|
color:#fff;font-weight:700;font-size:12px;letter-spacing:-.3px}
|
||||||
.brand b{display:block;font-size:15px;font-weight:650;letter-spacing:-.2px}
|
.brand{flex:none;min-width:0}
|
||||||
.brand span{display:block;color:var(--faint);font-size:11px}
|
.brand b{display:block;font-size:15px;font-weight:650;letter-spacing:-.2px;
|
||||||
.state{margin-left:14px;display:inline-flex;align-items:center;gap:6px;
|
line-height:1.35;white-space:nowrap}
|
||||||
|
.brand span{display:block;color:var(--faint);font-size:11px;
|
||||||
|
line-height:1.4;white-space:nowrap}
|
||||||
|
.state{margin-left:8px;flex:none;display:inline-flex;align-items:center;gap:6px;
|
||||||
padding:3px 10px;border-radius:999px;background:#f0fdf4;
|
padding:3px 10px;border-radius:999px;background:#f0fdf4;
|
||||||
color:#15803d;font-size:11px;font-weight:600}
|
color:#15803d;font-size:11px;font-weight:600;white-space:nowrap}
|
||||||
.state i{width:6px;height:6px;border-radius:50%;background:#22c55e;
|
.state i{width:6px;height:6px;border-radius:50%;background:#22c55e;
|
||||||
display:block}
|
display:block;flex:none}
|
||||||
.top-right{margin-left:auto;text-align:right;font-size:11px;
|
.top-right{margin-left:auto;text-align:right;font-size:11px;
|
||||||
color:var(--faint);line-height:1.7}
|
color:var(--faint);line-height:1.65;min-width:0}
|
||||||
.top-right b{color:var(--muted);font-weight:500}
|
.top-right b{color:var(--muted);font-weight:500}
|
||||||
.logout{color:var(--muted);text-decoration:none;
|
.logout{color:var(--muted);text-decoration:none;
|
||||||
border-bottom:1px dashed var(--border);transition:.15s}
|
border-bottom:1px dashed var(--border);transition:.15s}
|
||||||
.logout:hover{color:var(--danger);border-bottom-color:var(--danger)}
|
.logout:hover{color:var(--danger);border-bottom-color:var(--danger)}
|
||||||
|
|
||||||
|
/* 窄屏:状态徽章换行,别和标题挤 */
|
||||||
|
@media(max-width:640px){
|
||||||
|
.top-in{flex-wrap:wrap;gap:8px}
|
||||||
|
.state{margin-left:auto}
|
||||||
|
}
|
||||||
|
|
||||||
/* ---------- 公网地址(最重要,给最大权重)---------- */
|
/* ---------- 公网地址(最重要,给最大权重)---------- */
|
||||||
.hero{padding:30px 0 26px}
|
.hero{padding:30px 0 26px}
|
||||||
.hero h2{font-size:13px;font-weight:600;color:var(--muted);
|
.hero h2{font-size:13px;font-weight:600;color:var(--muted);
|
||||||
@@ -187,8 +205,8 @@ button.sm{padding:6px 12px;font-size:12px}
|
|||||||
</div>
|
</div>
|
||||||
<span class="state"><i></i>运行中</span>
|
<span class="state"><i></i>运行中</span>
|
||||||
<div class="top-right">
|
<div class="top-right">
|
||||||
<div>版本 <b>1.7.1</b> · 已运行 <b>21 分</b> · 内存 <b>22 MB</b></div>
|
<div>版本 <b>1.7.1</b> · 已运行 <b>6 分</b> · 内存 <b>23 MB</b></div>
|
||||||
<div>累计请求 <b>154</b> · <a class="logout" href="/zhongzhuanzhan/logout">退出登录</a></div>
|
<div>累计请求 <b>29</b> · <a class="logout" href="/zhongzhuanzhan/logout">退出登录</a></div>
|
||||||
</div>
|
</div>
|
||||||
</div></div>
|
</div></div>
|
||||||
|
|
||||||
@@ -204,10 +222,10 @@ button.sm{padding:6px 12px;font-size:12px}
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="nums">
|
<div class="nums">
|
||||||
<div class="num"><div class="v">0</div><div class="k">登记设备</div></div>
|
<div class="num"><div class="v">2</div><div class="k">登记设备</div></div>
|
||||||
<div class="num "><div class="v">0</div><div class="k">在线</div></div>
|
<div class="num live"><div class="v">1</div><div class="k">在线</div></div>
|
||||||
<div class="num "><div class="v">0</div><div class="k">手表会话</div></div>
|
<div class="num "><div class="v">0</div><div class="k">手表会话</div></div>
|
||||||
<div class="num"><div class="v">0</div><div class="k">配对码占用</div></div>
|
<div class="num"><div class="v">2</div><div class="k">配对码占用</div></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="sec">
|
<div class="sec">
|
||||||
@@ -229,7 +247,7 @@ button.sm{padding:6px 12px;font-size:12px}
|
|||||||
<th>空闲</th><th>待发 表/机</th><th>流量 入/出</th><th></th>
|
<th>空闲</th><th>待发 表/机</th><th>流量 入/出</th><th></th>
|
||||||
</tr></thead>
|
</tr></thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr><td colspan="8" class="empty"><svg width="34" height="34" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" style="opacity:.28;margin-bottom:14px"><rect x="2" y="4" width="20" height="13" rx="2"/><path d="M8 21h8M12 17v4"/></svg><div class="big">还没有电脑连上来</div><p>在教室那台电脑上双击 ykxmz.exe 设好 6 位配对码,手表上输这 6 位数字就能连上。</p></td></tr>
|
<tr><td class="pickcell"><input type="checkbox" class="pick" value="DESKTOP-RN5I625-ec4b284cdecd" aria-label="选择 DESKTOP-RN5I625"></td><td data-l="设备"><div class="devname"><span class="dot off"></span>DESKTOP-RN5I625</div><div class="devid">DESKTOP-RN5I625-ec4b284cdecd</div></td><td data-l="配对码"><code>966173</code></td><td data-l="状态"><span class="pill off">离线</span></td><td data-l="空闲"><span class="mono">314s</span></td><td data-l="待发 表/机"><span class="mono">0 / 0</span></td><td data-l="流量 入/出"><span class="mono">0 B / 0 B</span></td><td class="ops"><button class="danger sm" data-device="DESKTOP-RN5I625-ec4b284cdecd" data-name="DESKTOP-RN5I625" data-code="966173">删除</button></td></tr><tr><td class="pickcell"><input type="checkbox" class="pick" value="DESKTOP-RN5I625-2f882bd8ed14" aria-label="选择 DESKTOP-RN5I625"></td><td data-l="设备"><div class="devname"><span class="dot on"></span>DESKTOP-RN5I625</div><div class="devid">DESKTOP-RN5I625-2f882bd8ed14</div></td><td data-l="配对码"><code>246813</code></td><td data-l="状态"><span class="pill on">在线</span></td><td data-l="空闲"><span class="mono">26s</span></td><td data-l="待发 表/机"><span class="mono">0 / 0</span></td><td data-l="流量 入/出"><span class="mono">0 B / 0 B</span></td><td class="ops"><button class="danger sm" data-device="DESKTOP-RN5I625-2f882bd8ed14" data-name="DESKTOP-RN5I625" data-code="246813">删除</button></td></tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -0,0 +1,52 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# 看中转到底吃多少资源 —— 好判断免费容器够不够
|
||||||
|
set -u
|
||||||
|
|
||||||
|
echo "════════ 进程占用 ════════"
|
||||||
|
for pat in relay.py cloudflared; do
|
||||||
|
pid=$(pgrep -f "$pat" | head -1)
|
||||||
|
if [ -n "${pid:-}" ]; then
|
||||||
|
rss=$(ps -o rss= -p "$pid" | tr -d ' ')
|
||||||
|
cpu=$(ps -o %cpu= -p "$pid" | tr -d ' ')
|
||||||
|
etime=$(ps -o etime= -p "$pid" | tr -d ' ')
|
||||||
|
printf " %-14s PID %-6s 内存 %5.1f MB CPU %s%% 已跑 %s\n" \
|
||||||
|
"$pat" "$pid" "$(echo "$rss/1024" | bc -l)" "$cpu" "$etime"
|
||||||
|
else
|
||||||
|
printf " %-14s 没在跑\n" "$pat"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
echo
|
||||||
|
echo "════════ 系统整体 ════════"
|
||||||
|
echo " CPU 核心: $(nproc)"
|
||||||
|
echo " 内存总量: $(free -m | awk '/Mem:/{print $2}') MB"
|
||||||
|
echo " 已用: $(free -m | awk '/Mem:/{print $3}') MB"
|
||||||
|
echo " 可用: $(free -m | awk '/Mem:/{print $7}') MB"
|
||||||
|
echo " 磁盘: $(df -h /root | awk 'NR==2{print $3" / "$2" ("$5" 已用)"}')"
|
||||||
|
echo " 负载: $(cat /proc/loadavg | cut -d' ' -f1-3)"
|
||||||
|
|
||||||
|
echo
|
||||||
|
echo "════════ 中转的数据目录(要跟着搬的东西)════════"
|
||||||
|
du -sh /root/lanremote-relay 2>/dev/null | sed 's/^/ /'
|
||||||
|
echo " ---"
|
||||||
|
du -sh /root/lanremote-relay/* 2>/dev/null | sort -h | tail -8 | sed 's/^/ /'
|
||||||
|
|
||||||
|
echo
|
||||||
|
echo "════════ 每天请求量(估算托管配额需求)════════"
|
||||||
|
echo " agent poll 间隔: $(grep -oE 'POLL_SECONDS = float\(os.environ.get\("RELAY_POLL", "[0-9]+"' /root/lanremote-relay/relay.py | grep -oE '"[0-9]+"' | tr -d '"') 秒"
|
||||||
|
echo " => 单台被控端: $((86400 / 15)) 次/天(按 15 秒算)"
|
||||||
|
echo " => 若 3 台: $((86400 / 15 * 3)) 次/天"
|
||||||
|
|
||||||
|
echo
|
||||||
|
echo "════════ 现在的中转总量(并发/会话)════════"
|
||||||
|
curl -s --max-time 8 http://127.0.0.1:8080/v1/health 2>/dev/null \
|
||||||
|
| python3 -c "
|
||||||
|
import sys, json
|
||||||
|
d = json.load(sys.stdin)
|
||||||
|
print(' 版本:', d.get('version'))
|
||||||
|
print(' 设备:', len(d.get('devices', [])), '台')
|
||||||
|
print(' 会话:', d.get('sessions', 0))
|
||||||
|
print(' 内存:', round(d.get('memoryKB', 0) / 1024), 'MB')
|
||||||
|
print(' 累计请求:', d.get('totalRequests'))
|
||||||
|
print(' 运行:', round(d.get('uptimeSeconds', 0) / 3600, 1), '小时')
|
||||||
|
" 2>/dev/null | sed 's/^/ /'
|
||||||
Binary file not shown.
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 1.7 MiB |
Binary file not shown.
|
Before Width: | Height: | Size: 3.1 KiB After Width: | Height: | Size: 608 KiB |
+227
@@ -0,0 +1,227 @@
|
|||||||
|
# 中转服务免费托管方案
|
||||||
|
|
||||||
|
> 起因:中转跑在一台 4G 随身 WiFi 上,链路丢包率 30%,
|
||||||
|
> 导致 `relay.xxmxxs.top` 间歇性 1033 / 502 / 530。
|
||||||
|
> 用户问:网上有没有免费的托管方式。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 一、先说结论
|
||||||
|
|
||||||
|
**能,而且换过去之后,隧道那一整套问题会从根上消失。**
|
||||||
|
|
||||||
|
原因是这两件事:
|
||||||
|
|
||||||
|
1. **你的协议全是 HTTP 长轮询**,没有裸 TCP:
|
||||||
|
```
|
||||||
|
POST /v1/agent/register
|
||||||
|
POST /v1/agent/poll ← 长轮询,最多 25 秒
|
||||||
|
POST /v1/agent/send
|
||||||
|
POST /v1/agent/bye
|
||||||
|
```
|
||||||
|
这意味着托管选择面很宽,不限于「支持自定义 TCP 端口」的商家。
|
||||||
|
|
||||||
|
2. **一旦有了公网 IP,就完全不需要 Cloudflare 隧道了。**
|
||||||
|
现在所有 1033 / 502 / 530 都是隧道这一跳出的问题。
|
||||||
|
直接 `A 记录 → 服务器 IP` 之后,这一跳消失。
|
||||||
|
|
||||||
|
### 资源需求(实测,很小)
|
||||||
|
|
||||||
|
| 项目 | 实测值 |
|
||||||
|
|---|---|
|
||||||
|
| relay.py 内存 | 23 MB |
|
||||||
|
| relay.py CPU | 0.1% |
|
||||||
|
| cloudflared 内存 | 38 MB(有公网 IP 后不需要) |
|
||||||
|
| 代码体积 | 150 KB |
|
||||||
|
| 数据目录 | 19 MB(含 15 MB 安装包) |
|
||||||
|
| 请求量 | 约 6000 次/天(按 2 台设备 × 25 秒轮询算) |
|
||||||
|
| 第三方依赖 | **零**(纯 Python 标准库) |
|
||||||
|
|
||||||
|
**结论:最小的免费实例都绰绰有余。**
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 二、方案对比
|
||||||
|
|
||||||
|
| 方案 | 永久免费 | 独立公网 IP | 要信用卡 | 亚洲节点 | 免掉隧道 | 稳定性 |
|
||||||
|
|---|---|---|---|---|---|---|
|
||||||
|
| **Oracle Cloud Always Free** | ✅ 永久 | ✅ | ✅ 实体卡 | 东京/大阪/首尔 | ✅ | 高 |
|
||||||
|
| **ClawCloud Run** | ✅ $5/月 | ❌ 容器 | ❌ 只要 GitHub | 有 | ❌ 仍需隧道 | 中 |
|
||||||
|
| **Google Cloud e2-micro** | ✅ | ✅ | ✅ | ❌ 只有美国 | ✅ | 高 |
|
||||||
|
| **Cloudflare Workers + Durable Objects** | ✅ | ✅ | ❌ | 全球 | ✅ | 高(但要重写) |
|
||||||
|
| **Hugging Face Spaces** | ✅ | ❌ | ❌ | 有 | ❌ | 低(会休眠) |
|
||||||
|
| 现状(4G 随身 WiFi) | — | 隧道 | — | — | — | **低(丢包 30%)** |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 三、推荐方案
|
||||||
|
|
||||||
|
### 🥇 第一选择:Oracle Cloud Always Free
|
||||||
|
|
||||||
|
**规格(真·永久免费,不是试用):**
|
||||||
|
|
||||||
|
| 资源 | 配置 |
|
||||||
|
|---|---|
|
||||||
|
| CPU | 4 核 Ampere A1(ARM) |
|
||||||
|
| 内存 | 24 GB |
|
||||||
|
| 存储 | 200 GB |
|
||||||
|
| 月出口流量 | 10 TB |
|
||||||
|
| 价格 | **$0,不限期** |
|
||||||
|
|
||||||
|
另外还附带 2 台 AMD x86 小机器(各约 1 核 1 GB),当备用。
|
||||||
|
|
||||||
|
**为什么最合适:**
|
||||||
|
- 有真实公网 IP → **彻底不用隧道了**
|
||||||
|
- 10 TB/月流量 → 流量完全不是问题
|
||||||
|
- 东京 / 大阪 / 首尔区域 → 国内延迟约 50~100 ms
|
||||||
|
(比现在的公网 690 ms 快 7 倍)
|
||||||
|
|
||||||
|
**注册要点(社区总结的风控规律):**
|
||||||
|
- 需要**实体信用卡**(Visa/Mastercard,招行/工行/中行/浦发都行;**不接受虚拟卡和预付卡**)
|
||||||
|
- 国内 +86 手机号可以直接用
|
||||||
|
- **必须关掉代理、用手机热点注册** —— Oracle 校验 IP 来源和信用卡发卡国是否一致
|
||||||
|
- 账单地址填中国地址
|
||||||
|
- 主区域**选完不能改**,想清楚再点
|
||||||
|
|
||||||
|
**唯一难点:亚洲区的 ARM 实例经常「Out of Capacity」**
|
||||||
|
社区有自动抢机脚本,挂在 GitHub Actions 上自动重试:
|
||||||
|
- [oci-free-arm-instance](https://github.com/maoucodes/oci-free-arm-instance)(GitHub Actions 版)
|
||||||
|
- [oracle-freetier-instance-creation](https://github.com/mohankumarpaluru/oracle-freetier-instance-creation)(Python 版)
|
||||||
|
|
||||||
|
**保活**:Oracle 会检查闲置(CPU/内存/网络利用率连续 7 天低于 20% 可能回收)。
|
||||||
|
**我们的中转一直在长轮询,永远不会闲置** —— 这条风险天然规避,不需要额外保活脚本。
|
||||||
|
|
||||||
|
参考:[Oracle 白送 4 核 24G 服务器,注册到跑起来一次讲清](https://byronfinn.github.io/oracle-free-vps-guide/)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 🥈 第二选择:ClawCloud Run(不用信用卡)
|
||||||
|
|
||||||
|
| 项目 | 规格 |
|
||||||
|
|---|---|
|
||||||
|
| 免费额度 | **$5 / 月**(连接 GitHub 账号领取) |
|
||||||
|
| 容器 | 4 核 8 GB / 10 GB 磁盘 / 10 GB 流量 |
|
||||||
|
| 信用卡 | **不需要** |
|
||||||
|
| 注册 | GitHub 一键登录 |
|
||||||
|
|
||||||
|
**优点**:零门槛,不绑卡。
|
||||||
|
**缺点**:
|
||||||
|
- 是**容器**,没有独立公网 IP → **仍然需要 Cloudflare 隧道**
|
||||||
|
- 有「定期活跃检查 + 长期闲置释放」机制
|
||||||
|
不过我们一直在轮询,不会闲置,这条影响很小
|
||||||
|
- 仍需自己算好 $5 额度(按最低配 0.16 刀/天算,一个月约 $4.8,够但没余量)
|
||||||
|
|
||||||
|
参考:[永久免费的高配容器 ClawCloud](https://cloud.tencent.com.cn/developer/article/2516945)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 🥉 第三选择:Cloudflare Workers + Durable Objects
|
||||||
|
|
||||||
|
**完全免费、不用信用卡、全球节点、天然免隧道。**
|
||||||
|
|
||||||
|
Cloudflare 的 Durable Objects 就是为「有状态的长连接中转」设计的,
|
||||||
|
社区已经有人用 Worker + DO 做中转([openchamber-relay](https://github.com/openchamber/openchamber-relay))。
|
||||||
|
|
||||||
|
**代价**:Workers 跑不了 Python,**整个中转要用 JavaScript 重写**。
|
||||||
|
你现在的 150 KB Python 代码用不上。
|
||||||
|
除非以后想彻底脱离服务器,否则不值得。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 四、搬到新服务器要改什么
|
||||||
|
|
||||||
|
**好消息:被控端和手表一个字都不用改。** 它们只知道一个域名。
|
||||||
|
|
||||||
|
### 服务器上要做的事
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 1. 装 Python(Debian/Ubuntu 自带)
|
||||||
|
apt update && apt install -y python3
|
||||||
|
|
||||||
|
# 2. 把 relay/ 目录拷过去
|
||||||
|
scp -r relay/ root@<新服务器IP>:/root/lanremote-relay/
|
||||||
|
|
||||||
|
# 3. 写 systemd 服务
|
||||||
|
cat > /etc/systemd/system/lanremote-relay.service <<'EOF'
|
||||||
|
[Unit]
|
||||||
|
Description=ykxmz 中转服务器
|
||||||
|
After=network.target
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=simple
|
||||||
|
WorkingDirectory=/root/lanremote-relay
|
||||||
|
Environment=RELAY_BIND=0.0.0.0
|
||||||
|
Environment=RELAY_PORT=8080
|
||||||
|
Environment=RELAY_DATA=/root/lanremote-relay
|
||||||
|
ExecStart=/usr/bin/python3 /root/lanremote-relay/relay.py
|
||||||
|
Restart=always
|
||||||
|
RestartSec=3
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
|
EOF
|
||||||
|
|
||||||
|
systemctl daemon-reload
|
||||||
|
systemctl enable --now lanremote-relay
|
||||||
|
```
|
||||||
|
|
||||||
|
**只改一处环境变量**:`RELAY_BIND` 从 `127.0.0.1` 改成 `0.0.0.0`
|
||||||
|
(现在绑本地是因为前面有隧道;有了公网 IP 要直接对外)
|
||||||
|
|
||||||
|
### Cloudflare 后台要做的事
|
||||||
|
|
||||||
|
1. 进 DNS,把 `relay` 这条记录的**类型从 Tunnel 改成 A**
|
||||||
|
2. 值填新服务器 IP
|
||||||
|
3. 橙云(代理)**建议保持开启** —— 免费 DDoS 防护 + 隐藏真实 IP
|
||||||
|
4. SSL/TLS 模式设为 **Full** 或 **Full (Strict)**
|
||||||
|
|
||||||
|
### 可以删掉的东西
|
||||||
|
|
||||||
|
- ❌ `cloudflared` 隧道服务(`lanremote-tunnel`)
|
||||||
|
- ❌ 看门狗(`lanremote-watchdog`)—— 没有隧道就不需要看门狗
|
||||||
|
- ❌ 网络调优脚本(`lanremote-nettune`)—— 那是为 4G 的 MTU 问题写的
|
||||||
|
- ❌ 那个 4G 随身 WiFi 设备本身
|
||||||
|
|
||||||
|
**代码里有两处要顺手改掉:**
|
||||||
|
- `relay.py:267` 写死了 `/root/lanremote-relay/public_url.txt` → 改用 `RELAY_PUBLIC_URL` 环境变量
|
||||||
|
- `relay.py:1245` 读隧道 metrics → 没有隧道了,直接返回「直连模式」
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 五、代价与风险(说实话)
|
||||||
|
|
||||||
|
| 风险 | 说明 | 缓解 |
|
||||||
|
|---|---|---|
|
||||||
|
| Oracle 注册失败 | 风控严,IP/卡/地址三者要一致 | 按上面的清单来,用手机热点 |
|
||||||
|
| ARM 实例抢不到 | 亚洲区热门,常见 Out of Capacity | 挂自动抢机脚本,等几小时到几天 |
|
||||||
|
| Oracle 可能回收闲置实例 | 连续 7 天利用率 <20% | **我们一直轮询,不会闲置** |
|
||||||
|
| 商家政策变化 | 任何免费服务都可能改条款 | 代码无依赖,随时能搬走 |
|
||||||
|
| 国内访问延迟 | 取决于线路,绕路可能反而变慢 | 选东京/大阪/首尔,实测再定 |
|
||||||
|
| 换 IP 期间的过渡 | 手表里填的是域名,不用改 | 但切换那一刻会有短暂中断 |
|
||||||
|
|
||||||
|
**最坏情况**:Oracle 用不了,就退回 ClawCloud(不用信用卡),或者继续用现在的 4G 设备 —— 现在的 watchdog 已经能自愈,只是没那么稳。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 六、我的建议
|
||||||
|
|
||||||
|
**先试 Oracle。** 理由:
|
||||||
|
1. 唯一一个「永久免费 + 真公网 IP」的组合 → **能把隧道问题从根上解决**
|
||||||
|
2. 配置高到离谱(4 核 24G),跑 100 个中转都够
|
||||||
|
3. 东京/首尔延迟比现在好一个数量级
|
||||||
|
|
||||||
|
**如果 Oracle 注册不顺利**,就退到 ClawCloud(不用信用卡),
|
||||||
|
但那仍然要隧道,稳定性提升有限 —— 只是把「4G 链路」换成「机房链路」。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 附:判断依据来源
|
||||||
|
|
||||||
|
- [Oracle Cloud Free Tier 官方文档](https://docs.oracle.com/en-us/iaas/Content/FreeTier/freetier.htm)
|
||||||
|
- [Oracle 白送 4 核 24G 服务器,注册到跑起来一次讲清](https://byronfinn.github.io/oracle-free-vps-guide/)
|
||||||
|
- [永久免费的高配容器 ClawCloud](https://cloud.tencent.com.cn/developer/article/2516945)
|
||||||
|
- [Cloudflare Durable Objects 定价](https://developers.cloudflare.com/durable-objects/platform/pricing/)
|
||||||
|
- [openchamber-relay(Worker + DO 中转实例)](https://github.com/openchamber/openchamber-relay)
|
||||||
|
- [ClawCloud Run 控制台](https://console.run.claw.cloud/)
|
||||||
|
|
||||||
|
> 注:免费服务的条款随时会变,落地前请再确认一次当时的政策。
|
||||||
Reference in New Issue
Block a user