Cluster-Client
ClusterClient lässt einen Prozess außerhalb des Clusters mit
Actors innerhalb sprechen. Der externe Prozess ist kein
Cluster-Mitglied — kein Gossip, kein Mitgliedschaftsstatus — aber
er kann cluster-interne Actors per bekannten
Receptionist-Kontakten mit tell und ask ansprechen.
import { ClusterClient } from 'actor-ts';
const client = ClusterClient.create({ contacts: ['actor-ts://my-app@10.0.0.5:2552/system/receptionist'],});
// Senden an einen bekannten Cluster-Actor:client.send('/user/api/orders', { kind: 'place', ... });
// Oder über Receptionist per Service-Key:client.sendByKey(ServiceKey.of<ApiMsg>('api'), { kind: 'list-orders' });Wann verwenden
Abschnitt betitelt „Wann verwenden“Drei legitime Anwendungsfälle:
- Externe Services, die nicht in den Actor-Cluster gehören, aber mit ihm reden müssen — ein Python-ML-Service, der an einen Kafka-Actor innerhalb des Clusters postet.
- Mobile-/Desktop-Clients über eine Bridge — eine serverseitige Bridge hält einen ClusterClient + bietet eine REST/WS-API nach außen.
- Cross-Cluster-Föderation — zwei Cluster, bei denen einer mit bestimmten Actors im anderen sprechen muss, ohne zu mergen.
Für typische Setups ist alles Teil des Clusters — ClusterClient ist der Notausgang für Fälle, in denen das nicht möglich ist.
Wie es funktioniert
Abschnitt betitelt „Wie es funktioniert“Der Client:
- Verbindet sich mit einem oder mehreren Kontakten (bekannte
Cluster-Nodes, auf denen ein
ClusterClientReceptionistläuft). - Entdeckt verfügbare Services über den Receptionist.
- Routet Nachrichten zu den richtigen Actors.
- Behandelt Failover, wenn Kontakte unerreichbar werden — verbindet sich zu einem anderen.
Konfiguration
Abschnitt betitelt „Konfiguration“interface ClusterClientSettings { contacts: string[]; // mindestens ein Cluster-Node-Pfad reconnectIntervalMs?: number; acceptableHeartbeatPauseMs?: number;}contacts ist die Liste der Receptionist-Pfade. Der Client wählt
zufällig einen aus, um sich zu verbinden; bei Ausfall fällt er auf
andere zurück.
Für stabile Kontaktadressen deployt die Cluster-Seite typisch
einen ClusterClientReceptionist auf einem festen Pod (oder
sharded Set) an einem bekannten Pfad.
Serverseite — ClusterClientReceptionist
Abschnitt betitelt „Serverseite — ClusterClientReceptionist“import { ClusterClientReceptionist } from 'actor-ts';
system.spawn( ClusterClientReceptionist.props({ cluster, role: 'frontend', // optional — auf bestimmte Nodes beschränken }), 'cluster-client-receptionist',);Der Receptionist legt registrierte Services für externe Clients offen. Actors registrieren:
const receptionistRef = system.actorSelection('/user/cluster-client-receptionist');
receptionistRef.tell({ kind: 'register-service', key: ServiceKey.of<OrdersMsg>('orders'), ref: ordersActor,});Externe Clients können dann sendByKey('orders', msg) machen.
Vergleich mit Cluster-fähigem ActorRef
Abschnitt betitelt „Vergleich mit Cluster-fähigem ActorRef“// Innerhalb des Clusters — Actors sprechen direkt:const ref = await system.actorSelection('actor-ts://my-app@host:2552/user/api').resolveOne();ref.tell(...);
// Außerhalb des Clusters — ClusterClient:const client = ClusterClient.create({ contacts: [...] });client.send('/user/api', ...);Unterschiede:
- Innen: erfordert Cluster-Mitgliedschaft. Refs propagieren per Gossip; du kannst langlebige Refs halten.
- ClusterClient: keine Mitgliedschaft; Refs werden pro Nachricht über den Receptionist aufgelöst.
Wann NICHT verwenden
Abschnitt betitelt „Wann NICHT verwenden“Wohin als Nächstes
Abschnitt betitelt „Wohin als Nächstes“- Refs über Nodes hinweg — Cluster-interne Ref-Semantik zum Vergleich.
- Receptionist — die cluster-interne Service-Registry; ClusterClient baut darauf auf.
- HTTP-Überblick — die häufigere extern zugängliche Alternative.