執行中繼
針對你的 nostrfy 中繼:啟動與停止、日誌與統計、設定熱重載、多執行個體與大規模調校。
啟動與停止
以背景常駐程式方式啟動中繼:
nostrfy --config nostrfy.toml start=> nostrfy started (pid 12345)
或在終端機中前景執行:
nostrfy --config nostrfy.toml start --foreground停止:
nostrfy --config nostrfy.toml stop驗證已啟動:
curl http://127.0.0.1:8080/health=> {"status":"ok"}
日誌與統計
常駐程式寫入 daemon.log_file。當檔案超過 max_log_size_bytes 時會
自動輪替(nostrfy.log.1、.2……最多 max_log_files 代):
tail -f nostrfy.log日誌等級由 RUST_LOG 環境變數控制(例如 RUST_LOG=debug)。
統計
從 CLI 取得即時統計:
nostrfy stats或透過 HTTP:
curl http://127.0.0.1:8080/relay/stats顯示連線數、接受/拒絕的事件、資料庫大小等。
Prometheus 指標
curl http://127.0.0.1:8080/metrics熱重載(SIGHUP)
編輯設定檔後,無需重新啟動即可重載:
kill -HUP $(cat nostrfy.pid)| 重載時生效 | 需要重新啟動 |
|---|---|
| 中繼身分、public_url | private_key |
| 大部分 [limits]、reject_ephemeral、enabled_git、enabled_nip78_auth | api_host、metrics_enabled、LiveKit 設定 |
| — | enabled_nips / disabled_nips、server.host / port / ws_paths |
| — | database.*(含 search_index)、blossom.* |
當需要重新啟動的設定發生變化時,日誌會發出警告。
執行多個執行個體
nostrfy 支援在同一台伺服器上執行多個獨立中繼(不同連接埠)。每個執行個體需要自己的 server.port、[daemon] 的 pid_file/log_file/stats_file (共用值會讓第二個執行個體以 already running 拒絕啟動)、 database.path,以及(如使用)各自的 api_host / blossom.host:
[server]
port = 8080
[database]
path = "/var/lib/nostrfy-a"
[daemon]
pid_file = "/var/run/nostrfy-a.pid"
log_file = "/var/log/nostrfy-a.log"
stats_file = "/var/lib/nostrfy-a/stats.json"
[server]
port = 8081
[database]
path = "/var/lib/nostrfy-b"
[daemon]
pid_file = "/var/run/nostrfy-b.pid"
log_file = "/var/log/nostrfy-b.log"
stats_file = "/var/lib/nostrfy-b/stats.json"每個執行個體用各自的設定管理:nostrfy --config /etc/nostrfy/a.toml start 等。
大規模部署
該中繼設計為可在單一主機上擴展到數十萬連線 — 即時投遞只喚醒能符合事件的訂閱者, 且每連線記憶體佔用很小。推向百萬級需要主機級調校:
| 設定 | 值 | 原因 |
|---|---|---|
ulimit -n / systemd LimitNOFILE | ≥ 目標連線數的 2 倍(+1000) | 每個連線佔用一個 fd |
net.core.somaxconn | ≥ 1024 | 連線突發時的待處理 accept 佇列 |
net.ipv4.tcp_fin_timeout | 較低(例如 10) | 更快回收 TIME_WAIT 通訊端 |
vm.overcommit_memory | 1 或 2 | LMDB 映射是大型稀疏虛擬保留 |
在 FreeBSD 上,對應的參數是 kern.maxfiles / kern.maxfilesperproc 加 ulimit -n,並用 kern.ipc.somaxconn 替代 net.core.somaxconn。
每連線的核心記憶體約 80 KiB、使用者空間約 10 KiB,因此一百萬連線在資料庫之外大約需要 90 GiB 的
核心 + 使用者記憶體。
輸送量(每秒事件數)
事件寫入受兩項成本約束:Schnorr 簽章驗證(每個事件約 30-50 µs)和 LMDB 寫入器在每個提交批次後
執行的同步磁碟清除。兩者都可以在 nostrfy.toml 中調整:
| 設定 | 原因 |
|---|---|
database.disabled_fsync = true | 提交到作業系統頁快取(微秒級);斷電只會遺失上次清除以來的寫入 — 從這裡開始 |
| CPU 核心 ≥ 8 vCPU | 批次 EVENT 路徑跨核心平行驗證簽章 |
database.search_index = false | 為寫入密集型執行個體去掉每事件的 NIP-50 詞索引寫入 |
平行簽章驗證在待處理批次中一次驗證所有簽章,使用工作執行緒池 (上限 8;少於 16 個事件的批次內聯驗證)。每個事件的廉價檢查仍然先行,因此拒絕 原因文字與循序路徑完全相同 — 只有 Schnorr 工作分散到各核心。單執行緒 建置保持循序執行。
固定的反濫用界線
為保持中繼在濫用下仍能回應,有幾項硬性界線是固定的(不可設定):
- 單一過濾器最多攜帶 512 個
ids、authors或kinds條目;#...標籤值每個過濾器共享單獨的 512 值預算。更大的過濾器會被拒絕(CLOSED invalid: ...)。 max_connections_per_sec_per_ip最多追蹤 10,000 個來源 IP;滿時,未見過的 IP 會被拒絕(fail closed)。ids過濾器中的事件 id 可以是前綴,但只有完整的 32 位元組 id 和偶數長度 前綴才能符合(奇數長度/空條目在歷史與即時投遞中都會被忽略)。- 過長的索引鍵(標籤值、內容詞、超出 LMDB 鍵大小限制的
d標籤)在 索引時會被跳過;事件仍會被儲存。