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 :
nostrfy --config nostrfy.toml start=> nostrfy started (pid 12345)
Ou exécutez-le au premier plan dans le terminal :
nostrfy --config nostrfy.toml start --foregroundArrêter :
nostrfy --config nostrfy.toml stopVérifiez qu’il est en marche :
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) :
tail -f nostrfy.logLe 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 :
nostrfy statsOu via HTTP :
curl http://127.0.0.1:8080/relay/statsAffiche 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
curl http://127.0.0.1:8080/metricsRechargement à chaud (SIGHUP)
Après avoir modifié le fichier de configuration, rechargez-le sans redémarrage :
kill -HUP $(cat nostrfy.pid)| Appliqué au rechargement | Redémarrage requis |
|---|---|
| Identité du relais, public_url | private_key |
| la plupart des limites, reject_ephemeral, enabled_git, enabled_nip78_auth, landing_page_file | api_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 :
[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églage | Valeur | Raison |
|---|---|---|
ulimit -n / systemd LimitNOFILE | ≥ 2× les connexions visées (+1000) | chaque connexion occupe un fd |
net.core.somaxconn | ≥ 1024 | File d’accept en attente lors des pics de connexions |
net.ipv4.tcp_fin_timeout | faible (par ex. 10) | Libère plus vite les sockets TIME_WAIT |
vm.overcommit_memory | 1 ou 2 | La 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églage | Raison |
|---|---|
database.disabled_fsync = true | Commit 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 vCPU | Le chemin EVENT par lots vérifie les signatures en parallèle sur les cœurs |
database.search_index = false | Supprime 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,authorsoukinds; 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_ipsuit au plus 10 000 IP sources ; une fois plein, les IP inédites sont refusées (fail closed).- Les
idsdes 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
dau-delà de la limite de taille de clé LMDB) sont ignorées à l’indexation ; l’événement est tout de même stocké.