執行中繼

針對你的 nostrfy 中繼:啟動與停止、日誌與統計、設定熱重載、多執行個體與大規模調校。

啟動與停止

以背景常駐程式方式啟動中繼:

sh
nostrfy --config nostrfy.toml start

=> nostrfy started (pid 12345)

或在終端機中前景執行:

sh
nostrfy --config nostrfy.toml start --foreground

停止:

sh
nostrfy --config nostrfy.toml stop

驗證已啟動:

sh
curl http://127.0.0.1:8080/health

=> {"status":"ok"}

日誌與統計

常駐程式寫入 daemon.log_file。當檔案超過 max_log_size_bytes 時會 自動輪替(nostrfy.log.1、.2……最多 max_log_files 代):

sh
tail -f nostrfy.log

日誌等級由 RUST_LOG 環境變數控制(例如 RUST_LOG=debug)。

統計

從 CLI 取得即時統計:

sh
nostrfy stats

或透過 HTTP:

sh
curl http://127.0.0.1:8080/relay/stats

顯示連線數、接受/拒絕的事件、資料庫大小等。

Prometheus 指標

sh
curl http://127.0.0.1:8080/metrics

熱重載(SIGHUP)

編輯設定檔後,無需重新啟動即可重載:

sh
kill -HUP $(cat nostrfy.pid)
重載時生效需要重新啟動
中繼身分、public_urlprivate_key
大部分 [limits]、reject_ephemeral、enabled_git、enabled_nip78_authapi_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:

toml
[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_memory1 或 2LMDB 映射是大型稀疏虛擬保留

在 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 標籤)在 索引時會被跳過;事件仍會被儲存。