Zum Inhalt springen
Deutsch

Discovery im Überblick

“Discovery” in actor-ts umfasst zwei getrennte Anliegen:

AnliegenMechanismusWann
Cluster-BootstrapSeed ProviderEinmal beim Start des Nodes — wie dieser Node seine Peers findet.
Runtime-Service-LookupReceptionistWährend des Betriebs — wie Actors einander per Service Key finden.

Beide teilen den Namen “Discovery”, weil beide Lookup-basiertes Addressing sind, aber die Protokolle und Anwendungsfälle sind verschieden.

Seed Provider beantworten: “Welche Adressen soll ich beim Join-Zeitpunkt als Cluster-Seeds probieren?”

import { Cluster, KubernetesApiSeedProvider } from 'actor-ts';
const provider = new KubernetesApiSeedProvider({
namespace: 'my-app',
labelSelector: 'app=actor-ts',
containerPort: 2552,
});
const seeds = await provider.lookup();
await Cluster.join(system, { host, port, seeds });

Vier Provider werden mitgeliefert:

ProviderVerwendung
ConfigSeedProviderStatische Liste aus Env-Vars / Config.
DnsSeedProviderDNS-SRV-Record-Auflösung.
KubernetesApiSeedProviderLive-Pod-Listing via K8s-API.
AggregateSeedProviderMehrere Provider mit Fallback verketten.

Wähle nach deiner Deployment-Umgebung:

  • K8sKubernetesApiSeedProvider.
  • VMs mit DNS-SDDnsSeedProvider.
  • Statische Deployments / Docker ComposeConfigSeedProvider.
  • Mehrere Umgebungen / DR-SzenarienAggregateSeedProvider.

Für die meisten Apps wählst du einen Provider, konfigurierst ihn einmal und gehst weiter. Siehe Joining und Seeds für das vollständige Join-Protokoll.

Der Receptionist beantwortet: “Welche Actors sind unter diesem Service Key registriert, irgendwo im Cluster?”

import { Receptionist, ServiceKey } from 'actor-ts';
// Auf node-A:
const receptionist = system.extension(ReceptionistId).start(cluster);
const key = ServiceKey.of<MyMsg>('my-service');
receptionist.register(key, myActor);
// Auf node-B:
const refs = await receptionist.find(key); // → ActorRef[] über den ganzen Cluster

Ein cluster-weites Service-Registry. Jeder Node hostet einen Receptionist-Actor; Registrierungen sind lokal autoritativ; Peers erfahren über Gossip von fremden Registrierungen.

Nimm den Receptionist, wenn:

  • Actor-Location ist dynamisch — Actors kommen und gehen, und Consumer sollen keine Pfade hartkodieren.
  • Mehrere Actors teilen sich einen Service — N Worker registrieren sich alle unter demselben Key; Consumer sehen sie alle.
  • Cross-Node-Discovery wird gebraucht — einen Actor finden, unabhängig davon, welcher Node ihn hostet.

Siehe Receptionist für die vollständige API.

FrageWerkzeug
Wie findet DIESER Node Peers zum Joinen?Seed Provider
Wie findet ein Actor zur Laufzeit einen anderen Actor?Receptionist
Wie routet ein HTTP-Loadbalancer Requests an meine Pods?K8s Service (nicht das hier)
Wie entdeckt ein Service-Mesh-Proxy Backends?Service Mesh (nicht das hier)

Die Discovery des Frameworks ist für Cluster-Internes. Externer Service Discovery (Consul, Eureka, Service Meshes) ist Sache deiner Infrastruktur; actor-ts holt sich daraus beim Start seine Peer-Adressen, beteiligt sich sonst aber nicht.

Ein typisches K8s-Deployment:

// 1. Seed Discovery — wie dieser Pod beim Start Peers findet
const seeds = await new KubernetesApiSeedProvider({
namespace: process.env.K8S_NAMESPACE!,
labelSelector: 'app=actor-ts',
containerPort: 2552,
}).lookup();
await Cluster.join(system, { host, port, seeds });
// 2. Receptionist — für Runtime-Actor-Lookup
const receptionist = system.extension(ReceptionistId).start(cluster);
// Den API-Actor dieses Pods registrieren:
receptionist.register(
ServiceKey.of<ApiMsg>('api'),
system.spawn(Props.create(() => new ApiActor()), 'api'),
);
// Andere Actors finden ihn:
const apis = await receptionist.find(ServiceKey.of<ApiMsg>('api'));

Seed Provider laufen einmal; der Receptionist läuft kontinuierlich.