Files

172 lines
7.9 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# NetStable
NetStable 是一个独立的 Go Web 测速项目,用于测试“打开网页的用户浏览器”到“部署服务器”的上传、下载和延迟。用户打开网页即可开始测试,页面会实时显示下载速度、上传速度、延迟、稳定评分和历史时序曲线。
## 功能
- 同一时间只允许一个用户真正进行测速。
- 其他用户发起请求时会进入 FIFO 队列,页面和 CLI 会显示当前排第几位,并在前面的用户完成后自动开始。
- 启动时可设置程序理论最高带宽,例如 `-bandwidth-limit-mbps 30` 将测试流量限制到 30 Mbps。
- 页面展示当前设置的理论最高限值。
- 一次测试按阶段执行:先连续下载指定时长,再连续上传同样时长。页面固定提供 `15s``30s` 两档,默认 `30s`
- 手动停止、刷新页面或 CLI 中断时会取消当前会话并释放队列,后续用户会自动前移。
- 下载/上传峰值使用连续样本的持续吞吐口径,避免单个短请求计时误差造成虚高峰值。
- 保存每次测试的完整样本曲线、摘要、脱敏后的用户 IP、地区和运营商信息;ISP 缺失时显示“未知运营商”。
- 所有历史测试用户数据通过网页和 `/api/records` 提供。
- 历史时序图展示不同时段的平均下载速度变化。
- 页面通过 SSE 心跳维持一条辅助长连接,用于显示连接状态和服务配置。
- CLI 支持 HTTP 模式和 `iperf3` 模式;`iperf3` 模式由服务端在线随机生成一次性高端口,并复用同一个全局测速锁。
- 页面可复制一键下载测试命令:用户服务器会从当前网站下载 CLI 二进制,然后立即发起测试。
- 内置 GitHub 开源 `ip2region_v4.xdb` IPv4 数据库,优先离线解析地区和 ISP,避免外部 API 限流。
- 静态页面嵌入二进制,部署时只需要上传一个可执行文件。
## 本地运行
```bash
go test ./...
go run ./cmd/netstable -listen 127.0.0.1:18080 -data data/records.jsonl
```
打开 `http://127.0.0.1:18080/`
## 构建
```bash
make test
make build
```
生成文件位于 `dist/netstable`
更新内置 IP 数据库:
```bash
make update-ip-db
```
## Release 二进制
线上可以通过 Gitea Release 发布可直接下载的二进制压缩包,不建议把二进制提交到 Git 仓库。
仓库设置为 public 后,用户不需要登录即可下载 Release 附件。把下面命令中的 `https://gitea.example.com/owner/netstable` 替换成实际 public 仓库地址即可一键下载并启动:
```bash
VERSION=v0.1.0 REPO=https://gitea.example.com/owner/netstable sh -c 'set -e; arch=$(uname -m); case "$arch" in x86_64) arch=amd64;; aarch64|arm64) arch=arm64;; *) echo "unsupported arch: $arch"; exit 1;; esac; tmp=$(mktemp -d); curl -fsSL "$REPO/releases/download/$VERSION/netstable-$VERSION-linux-$arch.tar.gz" | tar -xz -C "$tmp"; sudo install -m 0755 "$tmp/netstable" /usr/local/bin/netstable; sudo mkdir -p /var/lib/netstable; sudo /usr/local/bin/netstable -listen 0.0.0.0:18080 -data /var/lib/netstable/records.jsonl'
```
生成 Linux release 附件:
```bash
make release VERSION=v0.1.0
```
生成内容:
- `dist/netstable-v0.1.0-linux-amd64.tar.gz`
- `dist/netstable-v0.1.0-linux-arm64.tar.gz`
- `dist/checksums.txt`
在 Gitea 的仓库页面创建 Release,标签填 `v0.1.0`,然后上传上述附件。用户可以直接下载后运行:
```bash
tar -xzf netstable-v0.1.0-linux-amd64.tar.gz
chmod +x netstable
./netstable -listen 0.0.0.0:18080 -data /var/lib/netstable/records.jsonl -downloads-dir /var/lib/netstable/downloads
```
## Linux 部署
```bash
scp dist/netstable root@SERVER:/usr/local/bin/netstable
ssh root@SERVER 'mkdir -p /var/lib/netstable && chmod +x /usr/local/bin/netstable'
```
可直接启动:
```bash
/usr/local/bin/netstable -listen 0.0.0.0:18080 -data /var/lib/netstable/records.jsonl -downloads-dir /var/lib/netstable/downloads
```
也可以使用 `deploy/netstable.service`
```bash
scp deploy/netstable.service root@SERVER:/etc/systemd/system/netstable.service
ssh root@SERVER 'systemctl daemon-reload && systemctl enable --now netstable'
```
## CLI 测试
同一个二进制也可以作为客户端,在其他服务器上直接测试到部署节点的上传、下载和延迟。CLI 会复用 Web API,所以仍然遵守“同一时间只允许一个用户测速”的锁;如果前面有人正在测,CLI 会显示当前排队位置并持续等待,轮到自己后自动开始。
HTTP 模式不依赖外部程序:
```bash
./netstable client -server http://103.46.93.38:18080 -duration 30
```
网页复制的一键命令会先下载 CLI 再测试,适合用户服务器没有 `netstable` 的情况:
```bash
arch=$(uname -m); case "$arch" in x86_64) arch=amd64;; aarch64|arm64) arch=arm64;; *) echo "unsupported arch: $arch"; exit 1;; esac; tmp=$(mktemp -d); curl -fsSL 'http://103.46.93.38:18080/downloads/netstable-linux-'"$arch"'.tar.gz' | tar -xz -C "$tmp" && chmod +x "$tmp/netstable" && "$tmp/netstable" client -server 'http://103.46.93.38:18080' -duration 30
```
`iperf3` 模式需要客户端和服务端都安装 `iperf3`。CLI 会先请求服务端创建一次性会话,服务端随机开放一个临时高端口,测试结束后回写记录并释放锁:
```bash
./netstable client -mode iperf3 -server http://103.46.93.38:18080 -duration 30 -protocol tcp
```
UDP 示例:
```bash
./netstable client -mode iperf3 -server http://103.46.93.38:18080 -duration 30 -protocol udp -bandwidth-mbps 30
```
反向下载测试,即服务端发送到 CLI 客户端:
```bash
./netstable client -mode iperf3 -server http://103.46.93.38:18080 -duration 30 -reverse
```
输出 JSON
```bash
./netstable client -server http://103.46.93.38:18080 -duration 30 -json
```
常用参数:
- `-server`: NetStable 服务端地址。
- `-mode`: `http``iperf3`,默认 `http`
- `-duration`: 每阶段时长,先下载同样秒数,再上传同样秒数。
- `-timeout`: HTTP 请求超时,单位毫秒;`iperf3` 模式中也作为测试时长之外的额外等待时间,默认 `3000`
- `-target`: 保存到记录里的目标标签,默认使用 `-server` 的 host。
- `-download-bytes`: 每次下载请求大小,默认 4 MiB。
- `-upload-bytes`: 每次上传请求大小,默认 2 MiB。
- `-protocol`: `iperf3` 模式使用 `tcp``udp`,默认 `tcp`
- `-reverse`: `iperf3` 反向模式,服务端向 CLI 客户端发送流量。
- `-bandwidth-mbps`: `iperf3` 目标带宽,默认跟随服务端 `-bandwidth-limit-mbps`
- `-iperf3-path`: `iperf3` 可执行文件路径,默认 `iperf3`
- `-quiet`: 不输出每个样本,只输出最终摘要。
## 参数
- `-listen`: HTTP 监听地址,默认 `:8080`;部署示例使用高端口 `18080`
- `-data`: JSONL 记录文件,默认 `data/records.jsonl`
- `-static`: 可选静态资源目录;为空时使用嵌入资源。
- `-downloads-dir`: 可选二进制下载目录。目录中可放 `netstable-linux-amd64.tar.gz``netstable-linux-arm64.tar.gz`,通过 `/downloads/` 提供给网页一键命令下载。
- `-geo-base`: 在线 IP 归属地 API fallback 地址,默认 `https://ipapi.co`,并在默认源限流时自动尝试 `https://ipinfo.io`;内置 `ip2region` 会优先查询,设为空可关闭在线 fallback。
- `-geo-timeout`: IP 归属地查询超时,默认 `2s`
- `-trust-proxy-headers`: 是否信任 `CF-Connecting-IP``X-Real-IP``X-Forwarded-For`。直连公网时不要开启;放在可信反向代理后面时开启。
- `-bandwidth-limit-mbps`: 程序理论最高带宽限制,单位 Mbps。示例:服务器 50 Mbps,希望测速程序最多使用 30 Mbps,则设置为 `30`;默认 `0` 表示不限速。
- `-iperf3-path`: 服务端启动一次性 `iperf3` 会话时使用的可执行文件路径,默认 `iperf3`
## Gitea
仓库可以直接推送到 Gitea。设置 remote 后执行:
```bash
git remote add origin <gitea-repo-url>
git push -u origin codex/go-network-stability-tester
```