Zum Inhalt springen
Deutsch

Aggregate Seed Provider

AggregateSeedProvider umwickelt mehrere Seed Provider und probiert sie der Reihe nach, gibt das erste nicht-leere Ergebnis zurück. Nützlich, wenn:

  • Du erst DNS willst, mit Fallback auf statische Seeds, wenn DNS nicht erreichbar ist.
  • Derselbe Code in mehreren Umgebungen läuft: K8s für Prod, statische Config für lokales Dev.
  • Du Disaster Recovery machst — primärer Discovery-Mechanismus
    • Backup.
import {
Cluster,
AggregateSeedProvider,
KubernetesApiSeedProvider,
DnsSeedProvider,
ConfigSeedProvider,
} from 'actor-ts';
const provider = new AggregateSeedProvider([
new KubernetesApiSeedProvider({ namespace, labelSelector, containerPort: 2552 }),
new DnsSeedProvider({ service: '_actor-ts._tcp.example.com' }),
new ConfigSeedProvider({ seeds: ['fallback-1:2552', 'fallback-2:2552'] }),
]);
const seeds = await provider.lookup();
await Cluster.join(system, { host, port, seeds });

nicht leer + kein Fehler

leer / Fehler

nicht leer

leer / Fehler

lookup

provider[0].lookup versuchen

Ergebnis?

provider[1].lookup versuchen

Ergebnis?

provider[2]... versuchen

...irgendwann [] zurückgeben

wenn alle fehlschlagen

Ergebnis zurückgeben

Ergebnis zurückgeben

Der Provider stoppt beim ersten nicht-leeren Ergebnis. Eine leere Liste von einem Provider triggert den Fallback zum nächsten; ein Fehler triggert ebenfalls einen Fallback (mit geloggtem Error auf Debug-Level).

Wenn jeder Provider fehlschlägt oder leer zurückgibt, resolved lookup() zu []Cluster.join des Clusters bootstrapt sich dann entweder selbst oder retried (abhängig von seinen eigenen Settings).

new AggregateSeedProvider([
new ConfigSeedProvider({ envVar: 'ACTOR_TS_SEEDS' }), // 1.: Env-Var
new KubernetesApiSeedProvider({ // 2.: K8s-API
namespace: process.env.K8S_NAMESPACE ?? '',
labelSelector: 'app=actor-ts',
containerPort: 2552,
}),
]);

Lokales Dev: export ACTOR_TS_SEEDS=localhost:2552 → nutzt die Env-Var. In K8s ist die Env-Var nicht gesetzt; fällt durch zur K8s-API.

new AggregateSeedProvider([
new DnsSeedProvider({ service: '_actor-ts._tcp.example.com' }),
new ConfigSeedProvider({
seeds: ['known-stable-node-1:2552', 'known-stable-node-2:2552'],
}),
]);

Erst DNS probieren; wenn leer zurückkommt (DNS-Server-Schluckauf, beim Bootstrap noch keine Records), bekannte stabile statische IPs nutzen.

new AggregateSeedProvider([
new KubernetesApiSeedProvider({ namespace: 'primary-region', ... }),
new KubernetesApiSeedProvider({ namespace: 'failover-region', ... }),
]);

In einem Multi-Region-Deployment erst die lokale Region probieren; wenn lokal keine Pods laufen, versuchen, dem Failover-Region-Cluster beizutreten. Aggressiv — macht nur Sinn, wenn die Regionen tatsächlich State teilen sollen.

new AggregateSeedProvider([
new KubernetesApiSeedProvider({ ... }), // wirft 403 außerhalb K8s
new ConfigSeedProvider({ seeds: ['10.0.0.1:2552'] }),
]);

Ein 403 von der K8s-API → geloggt + übersprungen → fällt durch zum Config Provider. Das macht Aggregate zum richtigen Werkzeug für “dieser Code-Pfad läuft überall” — das K8s-Lookup wird einfach zum No-op, wo K8s nicht verfügbar ist.

Fehler werden auf Debug-Level geloggt — standardmäßig leise. Konfiguriere das System auf debug, wenn du Sichtbarkeit willst, welche Provider es probiert / nicht geschafft haben.

Der erste Provider, der ein nicht-leeres Ergebnis zurückgibt, wird genutzt. Teste die Reihenfolge explizit:

ReihenfolgeEffekt
K8s, dann DNSK8s gewinnt in K8s-Deployments; DNS ist der Fallback.
DNS, dann K8sDNS gewinnt überall; K8s feuert nur, wenn DNS nicht erreichbar ist.

Den bevorzugten Provider zuerst; den Fallback zuletzt.