Relay betreiben

Für Ihr nostrfy-Relay: Start und Stopp, Logs und Statistiken, Hot-Reload der Konfiguration, mehrere Instanzen und Tuning für große Maßstäbe.

Starten und stoppen

Starten Sie das Relay als Hintergrund-Daemon:

sh
nostrfy --config nostrfy.toml start

=> nostrfy started (pid 12345)

Oder im Vordergrund im Terminal ausführen:

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

Stoppen:

sh
nostrfy --config nostrfy.toml stop

Prüfen Sie, ob es läuft:

sh
curl http://127.0.0.1:8080/health

=> {"status":"ok"}

Logs und Statistiken

Der Daemon schreibt nach daemon.log_file. Wenn die Datei max_log_size_bytes überschreitet, rotiert sie automatisch (nostrfy.log.1, .2 … bis zu max_log_files Generationen):

sh
tail -f nostrfy.log

Die Log-Stufe wird über die RUST_LOG-Umgebungsvariable gesteuert (z. B. RUST_LOG=debug).

Statistiken

Live-Statistiken aus der CLI:

sh
nostrfy stats

Oder über HTTP:

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

Zeigt Verbindungen, akzeptierte/abgelehnte Events, DB-Größe und mehr.

Prometheus-Metriken

sh
curl http://127.0.0.1:8080/metrics

Hot-Reload (SIGHUP)

Nach dem Bearbeiten der Konfigurationsdatei ohne Neustart neu laden:

sh
kill -HUP $(cat nostrfy.pid)
Gilt beim ReloadNeustart nötig
Relay-Identität, public_urlprivate_key
die meisten [limits], reject_ephemeral, enabled_git, enabled_nip78_authapi_host, metrics_enabled, LiveKit-Einstellungen
—enabled_nips / disabled_nips, server.host / port / ws_paths
—database.* (inkl. search_index), blossom.*

Das Log warnt, wenn eine neustartpflichtige Einstellung geändert wurde.

Mehrere Instanzen betreiben

nostrfy unterstützt mehrere unabhängige Relays auf einem Server (verschiedene Ports). Jede Instanz braucht einen eigenen server.port, eigene [daemon]-Dateien pid_file/log_file/stats_file (geteilte Werte lassen die zweite Instanz mit already running ablehnen), database.path sowie (falls genutzt) eigene 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"

Jede Instanz wird mit eigener Konfiguration verwaltet: nostrfy --config /etc/nostrfy/a.toml start und mehr.

Bereitstellungen in großem Maßstab

Das Relay ist darauf ausgelegt, auf einem einzelnen Host auf Hunderttausende von Verbindungen zu skalieren — die Live-Zustellung weckt nur Abonnenten, die zu einem Event passen könnten, und der Speicher pro Verbindung bleibt klein. Für Millionen ist Host-Tuning nötig:

EinstellungWertGrund
ulimit -n / systemd LimitNOFILE≥ 2× der Zielverbindungen (+1000)jede Verbindung belegt einen fd
net.core.somaxconn≥ 1024Ausstehende Accept-Queue bei Verbindungsspitzen
net.ipv4.tcp_fin_timeoutniedrig (z. B. 10)Gibt TIME_WAIT-Sockets schneller frei
vm.overcommit_memory1 oder 2Die LMDB-Map ist eine große dünne virtuelle Reservierung

Unter FreeBSD sind die entsprechenden Parameter kern.maxfiles / kern.maxfilesperproc plus ulimit -n, während kern.ipc.somaxconn net.core.somaxconn ersetzt. Der Kernel-Speicher pro Verbindung beträgt etwa 80 KiB, der Userspace etwa 10 KiB, sodass eine Million Verbindungen zusätzlich zur Datenbank rund 90 GiB Kernel- und Userspace-Speicher benötigt.

Durchsatz (Events pro Sekunde)

Das Schreiben von Events wird von zwei Kosten begrenzt: der Schnorr-Signaturprüfung (etwa 30–50 µs pro Event) und dem synchronen Festplatten-Flush, den der LMDB-Writer nach jedem Commit-Batch ausführt. Beides lässt sich in nostrfy.toml abstimmen:

EinstellungGrund
database.disabled_fsync = trueCommit in den OS-Page-Cache (Mikrosekunden); ein Stromausfall verliert nur Schreibvorgänge seit dem letzten Flush — hier anfangen
CPU-Kerne ≥ 8 vCPUDer Batch-EVENT-Pfad verifiziert Signaturen parallel über Kerne
database.search_index = falseLässt für schreibintensive Instanzen den NIP-50-Wortindex pro Event weg

Die parallele Signaturprüfung verifiziert alle Signaturen eines ausstehenden Batches auf einmal in einem Pool von Worker-Threads (maximal 8; Batches unter 16 Events werden inline geprüft). Die günstigen Prüfungen jedes Events laufen weiterhin zuerst, daher ist der Ablehnungstext identisch zum sequenziellen Pfad — nur die Schnorr-Arbeit wird über Kerne verteilt. Ein Single-Thread-Build bleibt sequenziell.

Feste Anti-Missbrauchsgrenzen

Einige harte Grenzen sind fest (nicht konfigurierbar), damit das Relay unter Missbrauch ansprechbar bleibt:

  • Ein Filter enthält höchstens 512 ids, authors oder kinds-Einträge; #...-Tag-Werte haben ein eigenes Budget von 512 Werten. Größere Filter werden abgelehnt (CLOSED invalid: ...).
  • max_connections_per_sec_per_ip verfolgt höchstens 10.000 Quell-IPs; ist der Speicher voll, werden unbekannte IPs abgelehnt (fail closed).
  • ids-Filter dürfen Präfixe enthalten, aber nur vollständige 32-Byte-IDs und Präfixe gerader Länge passen (ungerade/leere Einträge werden sowohl in der Historie als auch bei der Live-Zustellung ignoriert).
  • Überlange Indexschlüssel (Tag-Werte, Inhaltswörter, d -Tags jenseits der LMDB-Schlüsselgrenze) werden beim Indexieren übersprungen; das Event wird dennoch gespeichert.