Exploiter le relais

Pour votre relais nostrfy : démarrage et arrêt, journaux et statistiques, rechargement à chaud de la configuration, instances multiples et réglage à grande échelle.

Démarrage et arrêt

Démarrez le relais en démon d’arrière-plan :

sh
nostrfy --config nostrfy.toml start

=> nostrfy started (pid 12345)

Ou exécutez-le au premier plan dans le terminal :

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

Arrêter :

sh
nostrfy --config nostrfy.toml stop

Vérifiez qu’il est en marche :

sh
curl http://127.0.0.1:8080/health

=> {"status":"ok"}

Journaux et statistiques

Le démon écrit dans daemon.log_file. Lorsque le fichier dépasse max_log_size_bytes, il subit automatiquement une rotation (nostrfy.log.1, .2… jusqu’à max_log_files générations) :

sh
tail -f nostrfy.log

Le niveau de journalisation est contrôlé par la variable d’environnement RUST_LOG (par ex. RUST_LOG=debug).

Statistiques

Statistiques en direct depuis la CLI :

sh
nostrfy stats

Ou via HTTP :

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

Affiche les connexions, les événements reçus/acceptés/rejetés, la taille de la base, etc. /relay/stats ne demande aucun jeton et est lisible en cross-origin, il sert donc un sous-ensemble public plus étroit : l’espace disque libre de l’hôte, l’indicateur de disque plein, les compteurs d’échecs et la répartition des refus de connexion par motif sont omis (un oracle de capacité de stockage pour un sondeur anonyme). Ils restent dans l’instantané de fichier de nostrfy stats et dans /metrics — qui n’est pas authentifié non plus : isolez-le (api_host ou reverse-proxy) si les chiffres de capacité doivent rester privés.

Métriques Prometheus

sh
curl http://127.0.0.1:8080/metrics

Rechargement à chaud (SIGHUP)

Après avoir modifié le fichier de configuration, rechargez-le sans redémarrage :

sh
kill -HUP $(cat nostrfy.pid)
Appliqué au rechargementRedémarrage requis
Identité du relais, public_urlprivate_key
la plupart des limites, reject_ephemeral, enabled_git, enabled_nip78_auth, landing_page_fileapi_host, metrics_enabled, réglages LiveKit
—enabled_nips / disabled_nips, server.host / port / ws_paths / assets_dir
—database.* (y compris search_index), blossom.*

Le journal avertit lorsqu’un réglage nécessitant un redémarrage a changé.

Exécuter plusieurs instances

nostrfy prend en charge plusieurs relais indépendants sur un même serveur (ports différents). Chaque instance a besoin de son propre server.port, [daemon] pid_file/log_file/stats_file (des valeurs partagées font que la seconde instance refuse de démarrer avec already running), database.path ainsi que (si utilisés) leurs propres 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"

Chaque instance est gérée avec sa propre configuration : nostrfy --config /etc/nostrfy/a.toml start et plus.

Déploiements à grande échelle

Le relais est conçu pour monter à des centaines de milliers de connexions sur un seul hôte — la diffusion live ne réveille que les abonnés pouvant correspondre et la mémoire par connexion reste faible. Pour atteindre le million, un réglage au niveau de l’hôte est nécessaire :

RéglageValeurRaison
ulimit -n / systemd LimitNOFILE≥ 2× les connexions visées (+1000)chaque connexion occupe un fd
net.core.somaxconn≥ 1024File d’accept en attente lors des pics de connexions
net.ipv4.tcp_fin_timeoutfaible (par ex. 10)Libère plus vite les sockets TIME_WAIT
vm.overcommit_memory1 ou 2La carte LMDB est une grande réservation virtuelle creuse

Sous FreeBSD, les paramètres correspondants sont kern.maxfiles / kern.maxfilesperproc plus ulimit -n ainsi que kern.ipc.somaxconn remplace net.core.somaxconn. La mémoire noyau par connexion est d’environ 80 KiB, l’espace utilisateur d’environ 10 KiB : un million de connexions demande donc environ 90 GiB de mémoire noyau + utilisateur en plus de la base.

Débit (événements par seconde)

L’écriture des événements est limitée par deux coûts : la vérification de signature Schnorr (environ 30 à 50 µs par événement) et le vidage disque synchrone effectué par l’écrivain LMDB après chaque lot de commits. Les deux se règlent dans le fichier nostrfy.toml :

RéglageRaison
database.disabled_fsync = trueCommit dans le cache de pages de l’OS (microsecondes) ; une coupure de courant ne perd que les écritures depuis le dernier vidage — commencez par là
Cœurs CPU ≥ 8 vCPULe chemin EVENT par lots vérifie les signatures en parallèle sur les cœurs
database.search_index = falseSupprime l’écriture de l’index de mots NIP-50 par événement pour les instances à forte écriture

La vérification parallèle des signatures vérifie toutes les signatures d’un lot en attente d’un coup, sur un pool de threads (plafonné à 8 ; les lots de moins de 16 événements sont vérifiés en ligne). Les contrôles peu coûteux passent toujours en premier, donc le texte de rejet est identique au chemin séquentiel — seul le travail Schnorr est réparti sur les cœurs. Une compilation mono-thread reste séquentielle.

Limites anti-abus fixes

Quelques limites strictes sont fixes (non configurables) pour que le relais reste réactif sous abus :

  • Un filtre contient au plus 512 entrées ids, authors ou kinds ; les valeurs de tags #... disposent d’un budget séparé de 512 valeurs. Les filtres plus grands sont refusés (CLOSED invalid: ...).
  • max_connections_per_sec_per_ip suit au plus 10 000 IP sources ; une fois plein, les IP inédites sont refusées (fail closed).
  • Les ids des filtres peuvent être des préfixes, mais seuls les id complets de 32 octets et les préfixes de longueur paire correspondent (les entrées impaires/vides sont ignorées en historique comme en diffusion live).
  • Les clés d’index trop longues (valeurs de tags, mots du contenu, tags d au-delà de la limite de taille de clé LMDB) sont ignorées à l’indexation ; l’événement est tout de même stocké.