Discovery im Überblick
“Discovery” in actor-ts umfasst zwei getrennte Anliegen:
| Anliegen | Mechanismus | Wann |
|---|---|---|
| Cluster-Bootstrap | Seed Provider | Einmal beim Start des Nodes — wie dieser Node seine Peers findet. |
| Runtime-Service-Lookup | Receptionist | Wä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
Abschnitt betitelt „Seed Provider“Seed Provider beantworten: “Welche Adressen soll ich beim Join-Zeitpunkt als Cluster-Seeds probieren?”
import { Cluster, ClusterOptions, KubernetesApiSeedProvider, KubernetesApiSeedProviderOptions } from 'actor-ts';
const kubernetesApiSeedProviderOptions = KubernetesApiSeedProviderOptions.create() .withNamespace('my-app') .withServiceName('actor-ts') .withSystemName('my-app') .withPort(2552);const provider = new KubernetesApiSeedProvider( kubernetesApiSeedProviderOptions,);
const addresses = await provider.lookup();const seeds = addresses.map((address) => address.toString());
const clusterOptions = ClusterOptions.create() .withHost(host) .withPort(port) .withSeeds(seeds);await Cluster.join(system, clusterOptions);Vier Provider werden mitgeliefert:
| Provider | Verwendung |
|---|---|
ConfigSeedProvider | Statische Liste aus Env-Vars / Config. |
DnsSeedProvider | DNS-SRV-Record-Auflösung. |
KubernetesApiSeedProvider | Live-Pod-Listing via K8s-API. |
AggregateSeedProvider | Mehrere Provider mit Fallback verketten. |
Wähle nach deiner Deployment-Umgebung:
- K8s →
KubernetesApiSeedProvider. - VMs mit DNS-SD →
DnsSeedProvider. - Statische Deployments / Docker Compose →
ConfigSeedProvider. - Mehrere Umgebungen / DR-Szenarien →
AggregateSeedProvider.
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.
Ein Lookup ist noch keine Antwort
Abschnitt betitelt „Ein Lookup ist noch keine Antwort“Ein Provider liefert, was er gerade jetzt sieht. Bei einem
gleichzeitigen Start ist das auf jedem Node eine andere Menge — DNS ist
mitten in der Propagation, ein Pod ist Ready, bevor seine IP
veröffentlicht ist, die K8s-API paginiert eine unvollständige Liste —
und ein Node, der auf die erste Antwort hin joint, bildet einen Cluster
aus seiner eigenen Teilsicht.
Wenn deine Nodes gemeinsam mit dynamischen Adressen starten, konsumiere
lookup() nicht direkt. Der
Cluster-Bootstrap umschließt jeden
Provider von dieser Seite: er pollt, bis sich die zurückgegebene Menge
nicht mehr ändert, und lässt dann genau einen Node den Cluster bilden.
Die Provider hier bleiben exakt wie sie sind — Bootstrap ist eine Phase
darüber, kein Ersatz.
Receptionist
Abschnitt betitelt „Receptionist“Der Receptionist beantwortet: “Welche Actors sind unter diesem Service Key registriert, irgendwo im Cluster?”
import { Find, ReceptionistId, Register, ServiceKey } from 'actor-ts';
// Auf node-A:const receptionist = system.extension(ReceptionistId).start(cluster);const key = ServiceKey.of<MyMessage>('my-service');
receptionist.tell(new Register(key, myActor));
// Auf node-B — Find antwortet mit einem Listing (dessen .refs sind die// passenden Actors über den ganzen Cluster) an den als Reply-Ziel// angegebenen Actor:receptionist.tell(new Find(key, replyTo));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.
Seed Provider vs. Receptionist
Abschnitt betitelt „Seed Provider vs. Receptionist“| Frage | Werkzeug |
|---|---|
| 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.
Wann du beides nutzen könntest
Abschnitt betitelt „Wann du beides nutzen könntest“Ein typisches K8s-Deployment:
// 1. Seed Discovery — wie dieser Pod beim Start Peers findetconst kubernetesApiSeedProviderOptions = KubernetesApiSeedProviderOptions.create() .withNamespace(process.env.K8S_NAMESPACE!) .withServiceName('actor-ts') .withSystemName('my-app') .withPort(2552);const addresses = await new KubernetesApiSeedProvider( kubernetesApiSeedProviderOptions,).lookup();const seeds = addresses.map((address) => address.toString());
const clusterOptions = ClusterOptions.create() .withHost(host) .withPort(port) .withSeeds(seeds);await Cluster.join(system, clusterOptions);
// 2. Receptionist — für Runtime-Actor-Lookupconst receptionist = system.extension(ReceptionistId).start(cluster);
// Den API-Actor dieses Pods registrieren:receptionist.tell(new Register( ServiceKey.of<ApiMessage>('api'), system.spawn(ApiActor, 'api'),));
// Andere Actors finden ihn — das Listing wird an das Reply-Ziel geliefert:receptionist.tell(new Find(ServiceKey.of<ApiMessage>('api'), replyTo));Seed Provider laufen einmal; der Receptionist läuft kontinuierlich.
Wohin als Nächstes
Abschnitt betitelt „Wohin als Nächstes“Seed Provider
Abschnitt betitelt „Seed Provider“- Config — statische Liste.
- DNS — SRV-/A-Records.
- Kubernetes-API — Pod-Listing.
- Aggregate — mit Fallback verketten.
Receptionist
Abschnitt betitelt „Receptionist“- Receptionist — das Service-Registry.
Verwandtes
Abschnitt betitelt „Verwandtes“- Joining und Seeds — der Join-Handshake, der Seed Provider konsumiert.
- Cluster-Bootstrap — Stable Observation über einem Provider, plus Initial-Seed-Wahl.
- Cluster im Überblick — das Membership-Modell, das beiden zugrunde liegt.
