Hollywood ist ein Ultra-Schnell-Actor-Motorbau für Geschwindigkeits- und Latenzanwendungen. Denken Sie an Game -Server, Werbebroker, Handelsmotoren usw., es kann 10 Millionen Nachrichten in weniger als 1 Sekunde verarbeiten.
Das Akteurmodell ist ein Computermodell, das zum Erstellen von hochvertrauten und verteilten Systemen verwendet wird. Es wurde 1973 von Carl Hewitt als eine Möglichkeit eingeführt, komplexe Systeme auf skalierbare und fehlertolerantere Weise zu handhaben.
Im Schauspielermodell ist der grundlegende Baustein ein Akteur, der manchmal als Empfänger in Hollywood bezeichnet wird. Dies ist eine unabhängige Berechnungseinheit, die durch den Austausch von Nachrichten mit anderen Akteuren kommuniziert. Jeder Schauspieler hat seinen eigenen Zustand und sein eigenes Verhalten und kann nur mit anderen Akteuren durch Senden von Nachrichten kommunizieren. Dieses Paradigma für Nachrichten-Passing ermöglicht ein sehr dezentrales und fehlertolerantes System, da die Akteure weiterhin unabhängig arbeiten können, selbst wenn andere Akteure versagen oder nicht verfügbar werden.
Akteure können in Hierarchien organisiert werden, wobei Akteure über höhere Ebene auf niedrigere Akteure der unteren Ebene überwachen und koordinieren. Dies ermöglicht die Erstellung komplexer Systeme, die auf anmutige und vorhersehbare Weise Fehler und Fehler bewältigen können.
Durch die Verwendung des Akteurmodells in Ihrer Anwendung können Sie hoch skalierbare und fehlertolerante Systeme erstellen, die eine große Anzahl von gleichzeitigen Benutzern und komplexen Interaktionen verarbeiten können.
Garantierte Nachrichtenzustellung beim Ausfall des Akteurs (Puffermechanismus)
Fire & Vergessen oder Anfrage & Antwortnachrichten oder beides
Hochleistungs -DRPC als Transportschicht
Optimierte Protopuffer ohne Reflexion
Leicht und sehr anpassbar
Cluster -Unterstützung für das Schreiben verteilter selbst entdeckender Schauspieler
make bench
spawned 10 engines spawned 2000 actors per engine Send storm starting, will send for 10s using 20 workers Messages sent per second 3244217 .. Messages sent per second 3387478 Concurrent senders: 20 messages sent 35116641, messages received 35116641 - duration: 10s messages per second: 3511664 deadletters: 0
go get github.com/anthdm/hollywood/...
Hollywood benötigt Golang Version
1.21
Wir empfehlen Ihnen, ein paar Beispiele zu schreiben, die lokal ausgeführt werden. Lokales Laufen ist etwas einfacher, da der Compiler die verwendeten Typen herausfinden kann. Wenn Sie remote ausgeführt werden, müssen Sie für den Compiler Protobuffer -Definitionen bereitstellen.
Lassen Sie uns eine Hello World -Nachricht durchgehen. Das vollständige Beispiel ist im Ordner Hello World erhältlich. Beginnen wir in Main:
Motor, err: = Schauspieler.newengine (Schauspieler.newengineConfig ())
Dies schafft einen neuen Motor. Der Motor ist der Kern von Hollywood. Es ist verantwortlich für Laicher, Akteure, das Senden von Nachrichten und den Umgang mit dem Lebenszyklus von Schauspielern. Wenn Hollywood die Engine nicht erstellt, wird ein Fehler zurückgegeben. Für die Entwicklung sollten Sie keine Optionen an den Motor weitergeben, damit Sie NIL übergeben können. Wir werden uns die Optionen später ansehen.
Als nächstes müssen wir einen Schauspieler erstellen. Diese werden einige Male als Receivers nach der Schnittstelle bezeichnet, die sie implementieren müssen. Lassen Sie uns einen neuen Schauspieler erstellen, der eine Nachricht druckt, wenn sie eine Nachricht empfängt.
PID: = Engine.spawn (Newhelloer, "Hallo")
Dies führt dazu, dass der Motor einen Schauspieler mit der ID "Hallo" hervorbringt. Der Schauspieler wird von der bereitgestellten Funktion newHelloer erstellt. IDs müssen eindeutig sein. Es wird einen Zeiger zu einer PID zurückgeben. Eine PID ist eine Prozesskennung. Es ist eine einzigartige Kennung für den Schauspieler. Meistens verwenden Sie die PID, um Nachrichten an den Schauspieler zu senden. Gegen Remote -Systeme verwenden Sie die ID, um Nachrichten zu senden, aber auf lokalen Systemen verwenden Sie meistens die PID.
Schauen wir uns die newHelloer -Funktion und den von ihm zurückgegebenen Schauspieler an.
Typ Helloer struct {} func newhelloer () actor.receiver {return & helloer {}
} Einfach genug. Die newHelloer -Funktion gibt einen neuen Schauspieler zurück. Der Schauspieler ist eine Struktur, die den Schauspieler implementiert. Schauen wir uns die Receive an.
Typ Message struct {} func (h *helloer) reciant (ctx *actor.context) {switch msg: = ctx.message (). (Typ) {case actor.initialized: fmt.println ("helloer hat initialisiert") Fall Actor.Started: fmt.println ("Hello hat") Fall Schauspieler. fmt.println ("Hello hat gestoppt") Fall *Nachricht: fmt.println ("Hello World", msg.data)
}
}Sie können sehen, dass wir eine Nachrichtenstruktur definieren. Dies ist die Nachricht, die wir später an den Schauspieler senden werden. Die Empfangsmethode behandelt auch einige andere Nachrichten. Diese Lebenszyklusnachrichten werden vom Motor an den Schauspieler gesendet. Sie werden diese verwenden, um Ihren Schauspieler zu initialisieren
Die Engine übergibt einen Actor.context an die Receive . Dieser Kontext enthält die Nachricht, die PID des Absenders und einige andere Abhängigkeiten, die Sie verwenden können.
Lassen Sie uns nun eine Nachricht an den Schauspieler senden. Wir senden eine message , aber Sie können jede Art von Nachricht senden, die Sie möchten. Die einzige Anforderung ist, dass der Schauspieler in der Lage sein muss, die Nachricht zu verarbeiten. Damit Nachrichten den Kabel überqueren können, müssen sie serialisierbar sein. Damit Protobuf die Nachricht serialisieren kann, muss es ein Zeiger sein. Lokale Nachrichten können von jedem Typ sein.
Schließlich senden wir eine Nachricht an den Schauspieler.
motor.send (PID, "Hallo Welt!")
Dies sendet eine Nachricht an den Schauspieler. Hollywood leitet die Nachricht an den richtigen Schauspieler. Der Schauspieler druckt dann eine Nachricht an die Konsole.
Der Beispiel -Ordner ist der beste Ort, um Hollywood weiter zu lernen und zu erkunden.
Wenn Sie einen Schauspieler hervorbringen, müssen Sie eine Funktion bereitstellen, die einen neuen Schauspieler zurückgibt. Da der Schauspieler spawn ist, können Sie einige einstellbare Optionen bieten.
E.Spawn (Newfoo, "MyActorname")
Manchmal möchten Sie Argumente an den Schauspielerkonstruktor weitergeben. Dies kann durch die Verwendung eines Verschlusses erfolgen. Dies gibt ein Beispiel hierfür im Anforderungsbeispiel. Schauen wir uns den Code an.
Der Standardkonstruktor sieht ungefähr so aus:
func newnameresponder () actor.receiver {return & nameresponder {name: "noname"}
}Um einen neuen Schauspieler mit einem Namen zu erstellen, können Sie Folgendes tun:
func NewCustomnamersponder (Name String) Actor.Producer {return func () actor.receiver {return & nameresponder {name}
}
}Sie können dann den Schauspieler mit dem folgenden Code hervorbringen:
PID: = Engine.spawn (NewCustomnamersponder ("Anthony"), "Name Responder")E.Spawn (Newfoo, "MyActorName", Schauspieler. ) )
Die Optionen sollten ziemlich selbsterklärend sein. Sie können die maximale Anzahl von Neustarts festlegen, was dem Motor mitteilt zu blockieren.
Akteure ohne Staat können als Funktion hervorgebracht werden, weil es schnell und einfach ist.
E.Spawnfunc (func (c *actor.context) {Switch msg: = c.message (). (Typ) {case actor.started: fmt.println ("gestartet") _ = msg
}
}, "foo")Akteure können mit dem Remote -Paket über das Netzwerk über das Netzwerk kommunizieren. Dies funktioniert genauso wie lokale Schauspieler, aber "über dem Draht". Hollywood unterstützt die Serialisierung mit Protobuf.
Remote.new () nimmt eine Höradresse und eine Remote.config -Struktur an.
Sie werden eine neue Fernbedienung mit dem folgenden Code instanziieren:
tlsconfig: = tlsconfig: & tls.config {Zertifikate: [] tls.certificate {cert},
} config: = remote.newconfig (). Withtls (tlsconfig) remote: = remote.new ("0.0.0.0:222", config) Engine, err: = actor.newengine (actor.newengineConfig (). WithRemote (Remote) (Remote) (Remote) (Remote). )Schauen Sie sich die Beispiele für Remote -Akteure und den Chat -Client und den Chat -Client und den Server an, um weitere Informationen zu erhalten.
In einem Produktionssystem wird die Sache irgendwann schief gehen. Schauspieler werden abstürzen, Maschinen scheitern, Nachrichten werden in der Deadletter -Warteschlange landen. Sie können Software erstellen, die diese Ereignisse auf eine anmutige und vorhersehbare Weise durch die Nutzung des Ereignisstroms erstellen kann.
Der EventStream ist eine leistungsstarke Abstraktion, mit der Sie flexible und steckbare Systeme ohne Abhängigkeiten erstellen können.
Abonnieren Sie jeden Akteur eine verschiedene Liste von Systemereignissen
Senden Sie Ihre benutzerdefinierten Ereignisse an alle Abonnenten
Beachten Sie, dass Ereignisse, die von keinem Schauspieler behandelt werden, fallen gelassen werden. Sie sollten einen Akteur für den Ereignisstrom abonnieren lassen, um Ereignisse zu erhalten. Als Minimum möchten Sie DeadLetterEvent umgehen. Wenn Hollywood einen Schauspieler keine Nachricht übermittelt, sendet er einen DeadLetterEvent an den Event -Stream.
Jedes Ereignis, das die actor.LogEvent -Schnittstelle erfüllt, wird mit der Schweregradstufe, der Nachricht und den Attributen des vom actor.LogEvent log() -Methode festgelegten Ereignismethode an den Standardprotokoll angemeldet.
actor.ActorInitializedEvent wurde ein Akteur initialisiert, aber seine actor.Started message nicht bearbeitet.
actor.ActorStartedEvent , ein Schauspieler, hat begonnen
actor.ActorStoppedEvent , ein Schauspieler, hat gestoppt
actor.DeadLetterEvent , eine Nachricht wurde nicht an einen Schauspieler übermittelt
actor.ActorRestartedEvent , ein Schauspieler hat nach einem Absturz/einer Panik neu gestartet.
actor.RemoteUnreachableEvent , sendet eine Nachricht über den Kabel an eine Fernbedienung, die nicht erreichbar ist.
cluster.MemberJoinEvent , ein neues Mitglied bei der Cluster beigetreten
cluster.MemberLeaveEvent , ein neues Mitglied, hat den Cluster verlassen
cluster.ActivationEvent , ein neuer Akteur wird auf dem Cluster aktiviert
cluster.DeactivationEvent , ein Schauspieler, wird auf dem Cluster deaktiviert
Es gibt ein EventStream -Überwachungsbeispiel, das Ihnen zeigt, wie Sie den Ereignisstrom verwenden. Es verfügt über zwei Schauspieler, einer ist instabil und wird jede Sekunde zum Absturz bringen. Der andere Schauspieler ist dem Ereignisstrom abonniert und unterhält einige Zähler für verschiedene Ereignisse wie Abstürze usw.
Die Anwendung wird einige Sekunden lang und der Gift des instabilen Schauspielers ausgeführt. Anschließend wird der Monitor mit einer Anfrage abfragt. Da Schauspieler im Motor herumschweben, ist dies die Art und Weise, wie Sie mit ihnen interagieren. Main druckt dann das Ergebnis der Abfrage und die Anwendung wird beendet.
Wir verwenden das Funktionsoptionsmuster. Alle Funktionsoptionen befinden sich im Schauspielerpaket und starten ihren Namen mit "Engineopt". Derzeit ist die einzige Möglichkeit, eine Fernbedienung bereitzustellen. Dies geschieht durch
r: = remote.new (remote.config {listenaddr: addr}) Engine, err: = actor.newengine (actor.EngineOptremote (r))ADDR ist eine Zeichenfolge mit dem Format "Host: Port".
Sie können Ihren Empfängern benutzerdefinierte Middleware hinzufügen. Dies kann nützlich sein, um Kennzahlen zu speichern, Daten für Ihre Empfänger auf actor.Started zu speichern und actor.Stopped laden.
Beispiele zum Implementieren von benutzerdefinierten Middleware finden Sie im Middleware -Ordner in den Beispielen
Hollywood hat einige eingebautes Protokollieren. Es wird den Standardprotokoll aus dem log/slog -Paket verwendet. Sie können den Logger nach Ihrem Geschmack konfigurieren, indem Sie den Standardprotokoll mit slog.SetDefaultLogger() einstellen. Auf diese Weise können Sie die Protokollebene, das Format und die Ausgabe anpassen. Weitere Informationen finden Sie im slog -Paket.
Beachten Sie, dass einige Ereignisse möglicherweise beim Standard -Logger angemeldet DeadLetterEvent , actor.LogEvent ActorStartedEvent Weitere Informationen finden Sie im Abschnitt EventStream oben.
make test
Schließen Sie sich unserer Discord -Community mit über 2000 Mitgliedern an, um Fragen und einen schönen Chat zu erzielen.
Dieses Projekt wird derzeit in der Produktion von folgenden Organisationen/Projekten verwendet:
Sensora IoT
Hollywood ist unter der MIT -Lizenz lizenziert.