{"id":31124,"date":"2019-10-31T21:39:36","date_gmt":"2019-10-31T18:39:36","guid":{"rendered":"https:\/\/prohoster.info\/blog\/stroitelnye-bloki-raspredelennyh-prilozhenij-vtoroe-priblizhenie\/"},"modified":"2019-10-31T21:39:36","modified_gmt":"2019-10-31T18:39:36","slug":"stroitelnye-bloki-raspredelennyh-prilozhenij-vtoroe-priblizhenie","status":"publish","type":"post","link":"https:\/\/prohoster.info\/de\/blog\/administrirovanie\/stroitelnye-bloki-raspredelennyh-prilozhenij-vtoroe-priblizhenie","title":{"rendered":"Bausteine verteilter Anwendungen. Zweite Ann\u00e4herung","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p><strong>Ank\u00fcndigung<\/strong><\/p>\n<p><\/p>\n<p><em>Kollegen, ich plane f\u00fcr Mitte des Sommers die Ver\u00f6ffentlichung eines weiteren Artikels \u00fcber das Design von Systemen f\u00fcr den Massendienst: \u201eExperiment VTrade\u201c \u2013 der Versuch, ein Framework f\u00fcr Handelssysteme zu schreiben. Der Zyklus wird die Theorie und Praxis des Aufbaus von B\u00f6rsen, Auktionen und Gesch\u00e4ften behandeln. Am Ende des Artikels lade ich dazu ein, \u00fcber die f\u00fcr Sie interessantesten Themen abzustimmen.<br \/>\n<\/em><\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Bausteine verteilter Anwendungen. Zweite Ann\u00e4herung\" src=\"\/wp-content\/uploads\/2019\/04\/358996733e805327b587176f4f992aea.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Dies ist der abschlie\u00dfende Artikel des Zyklus \u00fcber verteilte reaktive Anwendungen in Erlang\/Elixir. In <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/post\/446028\/\">dem ersten Artikel<\/a><\/noindex> lassen sich die theoretischen Grundlagen der reaktiven Architektur finden. <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/post\/446108\/\">Der zweite Artikel<\/a><\/noindex> illustriert die grundlegenden Muster und Mechanismen zum Aufbau solcher Systeme.<\/p>\n<p><\/p>\n<p>Heute werden wir die Fragen zur Weiterentwicklung der Codebasis und der Projekte insgesamt ansprechen. <\/p>\n<p><noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<h2 id=\"organizaciya-servisov\">Organisation der Dienste<\/h2>\n<p><\/p>\n<p>Im echten Leben m\u00fcssen bei der Entwicklung eines Dienstes oft mehrere Interaktionsmuster in einem Controller kombiniert werden. Zum Beispiel sollte der Dienst users, der f\u00fcr die Verwaltung der Benutzerprofile des Projekts zust\u00e4ndig ist, auf req-resp-Anfragen reagieren und \u00fcber Aktualisierungen der Profile \u00fcber pub-sub informieren. Dieser Fall ist ziemlich einfach: Hinter dem Messaging steht ein Controller, der die Logik des Dienstes implementiert und Aktualisierungen ver\u00f6ffentlicht.<\/p>\n<p><\/p>\n<p>Die Situation wird komplizierter, wenn wir einen ausfallsicheren verteilten Dienst implementieren m\u00fcssen. Stellen wir uns vor, dass sich die Anforderungen an users ge\u00e4ndert haben: <\/p>\n<p><\/p>\n<ol>\n<li>Jetzt muss der Dienst Anfragen auf 5 Knoten im Cluster verarbeiten, <\/li>\n<li>die M\u00f6glichkeit haben, Hintergrundverarbeitungsaufgaben auszuf\u00fchren, <\/li>\n<li>und auch in der Lage sein, dynamisch die Listen der Abonnements f\u00fcr die Aktualisierungen der Profile zu verwalten.<\/li>\n<\/ol>\n<p><\/p>\n<p><em>Hinweis:<\/em> Die Frage der konsistenten Speicherung und Replikation von Daten betrachten wir nicht. Angenommen, diese Fragen wurden zuvor gel\u00f6st und in der System existiert bereits eine zuverl\u00e4ssige und skalierbare Speicherungsschicht, und die Handler haben Mechanismen f\u00fcr die Interaktion mit dieser.<\/p>\n<p><\/p>\n<p>Die formale Beschreibung des Dienstes users hat sich kompliziert. Aus Sicht des Programmierers sind die \u00c4nderungen dank der Verwendung von Messaging minimal. Um das erste Anliegen zu erf\u00fcllen, m\u00fcssen wir das Load Balancing an der req-resp-Schnittstelle einrichten. <\/p>\n<p><\/p>\n<p>Die Anforderung zur Verarbeitung von Hintergrundaufgaben tritt h\u00e4ufig auf. In den Benutzern kann es sich dabei um die \u00dcberpr\u00fcfung von Benutzerdokumenten, die Verarbeitung hochgeladener Medien oder die Synchronisierung von Daten mit sozialen Netzwerken handeln. Diese Aufgaben m\u00fcssen innerhalb des Clusters verteilt und der Fortschritt \u00fcberwacht werden. Daher haben wir zwei L\u00f6sungsm\u00f6glichkeiten: entweder das Aufgabenverteilungsschema aus dem vorherigen Artikel verwenden oder, falls dies nicht passt, einen benutzerdefinierten Task-Planer schreiben, der den Pool der Bearbeiter auf die ben\u00f6tigte Weise verwaltet. <\/p>\n<p><\/p>\n<p>Punkt 3 erfordert die Erweiterung des Pub-Sub-Schemas. Und zur Umsetzung m\u00fcssen wir nach der Erstellung des Pub-Sub-Austauschpunkts zus\u00e4tzlich den Controller dieses Punkts im Rahmen unseres Services starten. Dadurch nehmen wir quasi die Logik der Subscription- und Unsubscription-Verarbeitung aus der Messaging-Schicht und implementieren sie in den Benutzern.<\/p>\n<p><\/p>\n<p>Letztendlich hat die Dekomposition der Aufgabe gezeigt, dass wir zur Erf\u00fcllung der Anforderungen 5 Instanzen des Services auf verschiedenen Knoten starten und eine zus\u00e4tzliche Entit\u00e4t \u2013 den Pub-Sub-Controller \u2013 schaffen m\u00fcssen, der f\u00fcr die Subscription verantwortlich ist.<br \/>\nF\u00fcr den Start von 5 Bearbeitern ist keine Anpassung des Codes des Services erforderlich. Die einzige zus\u00e4tzliche Ma\u00dfnahme ist die Konfiguration der Lastverteilungsregeln am Austauschpunkt, \u00fcber die wir sp\u00e4ter sprechen werden.<br \/>\nAu\u00dferdem gibt es eine zus\u00e4tzliche Komplexit\u00e4t: Der Pub-Sub-Controller und der benutzerdefinierte Task-Planer m\u00fcssen in einer einzigen Instanz arbeiten. Wiederum sollte der Messaging-Service, als fundamentale Komponente, einen Mechanismus zur Wahl eines Leaders bereitstellen.<\/p>\n<p><\/p>\n<h3 id=\"vybor-lidera\">Wahl eines Leaders<\/h3>\n<p><\/p>\n<p>In verteilten Systemen ist die Wahl eines Leaders das Verfahren zur Ernennung eines einzigen Prozesses, der f\u00fcr die Planung der verteilten Verarbeitung einer bestimmten Last verantwortlich ist. <\/p>\n<p><\/p>\n<p>In Systemen, die nicht zur Zentralisierung neigen, kommen universelle Algorithmen und konsensorientierte Algorithmen wie Paxos oder Raft zum Einsatz.<br \/>\nDa Messaging ein Broker und ein zentrales Element ist, kennt es alle Controller des Services \u2013 Kandidaten f\u00fcr die F\u00fchrungsrolle. Messaging kann einen Leader ohne Abstimmung ernennen.<\/p>\n<p><\/p>\n<p>Alle Dienste erhalten nach dem Start und der Verbindung zu dem Austauschpunkt eine Systemnachricht <code>#'$leader'{exchange = ?EXCHANGE, pid = LeaderPid, servers = Servers}<\/code>. Falls <code>LeaderPid<\/code> mit <code>pid<\/code> dem aktuellen Prozess \u00fcbereinstimmt, wird er zum Leader ernannt, und die Liste <code>Servers<\/code> enth\u00e4lt alle Knoten und ihre Parameter.<br \/>\nIm Moment des Erscheinens eines neuen und der Abschaltung eines funktionierenden Knotens im Cluster erhalten alle Service-Controller <code>#'$slave_up'{exchange = ?EXCHANGE, pid = SlavePid, options = SlaveOpts}<\/code> und <code>#'$slave_down'{exchange = ?EXCHANGE, pid = SlavePid, options = SlaveOpts}<\/code> entsprechend.<\/p>\n<p><\/p>\n<p>So wissen alle Komponenten \u00fcber alle \u00c4nderungen Bescheid, und im Cluster gibt es zu jedem Zeitpunkt garantiert einen F\u00fchrer.<\/p>\n<p><\/p>\n<h2 id=\"posredniki\">Vermittler<\/h2>\n<p><\/p>\n<p>Um komplexe verteilte Verarbeitungsprozesse zu realisieren und bestehende Architekturen zu optimieren, ist es sinnvoll, Vermittler einzusetzen.<br \/>\nUm den Code der Dienste nicht zu \u00e4ndern und beispielsweise Aufgaben der zus\u00e4tzlichen Verarbeitung, Routing oder Protokollierung von Nachrichten zu l\u00f6sen, kann vor dem Dienst ein Proxy-Handler aktiviert werden, der die gesamte zus\u00e4tzliche Arbeit \u00fcbernimmt.<\/p>\n<p><\/p>\n<p>Ein klassisches Beispiel f\u00fcr die Optimierung von Pub-Sub ist eine verteilte Anwendung mit einem Gesch\u00e4fts-Kern, der Ereignisse \u00fcber Aktualisierungen generiert, wie z.B. Preis\u00e4nderungen auf dem Markt, und einer Zugriffsschicht \u2013 N Server, die WebSocket-APIs f\u00fcr Web-Clients bereitstellen.<br \/>\nWenn man es \u201edirekt angeht\u201c, sieht die Bedienung des Clients wie folgt aus:<\/p>\n<p><\/p>\n<ul>\n<li>Der Client stellt eine Verbindung zur Plattform her. Auf der Serverseite, die den Verkehr terminiert, wird ein Prozess gestartet, der diese Verbindung bedient.<\/li>\n<li>Im Kontext des bedienenden Prozesses erfolgt die Autorisierung und das Abonnieren von Updates. Der Prozess ruft die Methode subscribe f\u00fcr die Themen auf.<\/li>\n<li>Nach der Ereignisgenerierung im Kern wird es an die Prozesse geliefert, die die Verbindungen bedienen.<\/li>\n<\/ul>\n<p><\/p>\n<p>Stellen wir uns vor, wir haben 50000 Abonnenten f\u00fcr das Thema \u201enews\u201c. Die Abonnenten sind gleichm\u00e4\u00dfig auf 5 Server verteilt. Infolgedessen wird jedes Update, das an den Austauschpunkt kommt, 50000-mal repliziert: 10000-mal auf jeden Server, je nach Anzahl der Abonnenten auf diesem. Nicht gerade ein effizientes Schema, oder?<br \/>\nUm die Situation zu verbessern, f\u00fchren wir einen Proxy ein, der denselben Namen wie der Austauschpunkt hat. Der globale Namensregistrar sollte in der Lage sein, den n\u00e4chsten Prozess nach Namen zur\u00fcckzugeben, das ist wichtig.<\/p>\n<p><\/p>\n<p>Lassen Sie uns diesen Proxy auf den Servern der Zugriffsschicht starten, und alle unsere Prozesse, die die WebSocket-API bedienen, abonnieren ihn statt dem urspr\u00fcnglichen Pub-Sub-Austauschpunkt im Kern. Der Proxy abonniert den Kern nur im Falle eines einzigartigen Abonnements und repliziert die eingehende Nachricht bei allen seinen Abonnenten.<br \/>\nInsgesamt werden zwischen dem Kern und den Zugangsservern 5 Nachrichten \u00fcbermittelt, anstelle von 50000.<\/p>\n<p><\/p>\n<h2 id=\"marshrutizaciya-i-balansirovka\">Routing und Lastverteilung<\/h2>\n<p><\/p>\n<h3 id=\"req-resp\">Req-Resp<\/h3>\n<p><\/p>\n<p>In der aktuellen Implementierung des Messaging gibt es 7 Strategien zur Verteilung von Anfragen:<\/p>\n<p><\/p>\n<ul>\n<li><code>default<\/code>. Die Anfrage wird an alle Controller \u00fcbermittelt.<\/li>\n<li><code>round-robin<\/code>. Es erfolgt eine Durchlauf- und zirkul\u00e4re Verteilung der Anfragen zwischen den Controllern.<\/li>\n<li><code>Konsens<\/code>. Die Controller, die den Dienst betreuen, teilen sich in einen F\u00fchrer und gef\u00fchrte auf. Anfragen werden nur an den F\u00fchrer \u00fcbermittelt.<\/li>\n<li><code>Konsens &amp; round-robin<\/code>. In der Gruppe gibt es einen F\u00fchrer, aber die Anfragen werden unter allen Mitgliedern verteilt.<\/li>\n<li><code>sticky<\/code>. Es wird eine Hash-Funktion berechnet und einem bestimmten Handler zugeordnet. Folgende Anfragen mit dieser Signatur gelangen zu diesem Handler.<\/li>\n<li><code>sticky-fun<\/code>. Bei der Initialisierung des Austauschpunkts wird zus\u00e4tzlich eine Funktion zur Berechnung des Hashes \u00fcbergeben f\u00fcr <code>sticky<\/code> . die Lastverteilung.<\/li>\n<li><code>Spa\u00df<\/code>. \u00c4hnlich wie sticky-fun, jedoch kann zus\u00e4tzlich umgeleitet, abgelehnt oder vorverarbeitet werden. <\/li>\n<\/ul>\n<p><\/p>\n<p>Die Verteilungsstrategie wird bei der Initialisierung des Austauschpunkts festgelegt.<\/p>\n<p><\/p>\n<p>. Neben der Lastverteilung erm\u00f6glicht Messaging das Taggen von Entit\u00e4ten. Lassen Sie uns die Arten von Tags im System betrachten:<\/p>\n<p><\/p>\n<ul>\n<li>Verbindungstag. Erlaubt es zu verstehen, \u00fcber welche Verbindung die Ereignisse eingegangen sind. Wird verwendet, wenn der Controller-Prozess sich mit einem Austauschpunkt verbindet, jedoch mit verschiedenen Routing-Schl\u00fcsseln. <\/li>\n<li>Dienstetag. Erm\u00f6glicht es, Handler f\u00fcr einen Dienst in Gruppen zu b\u00fcndeln und die Routing- und Lastverteilungsf\u00e4higkeiten zu erweitern. F\u00fcr das req-resp-Muster ist das Routing linear. Wir senden eine Anfrage an den Austauschpunkt, der sie dann an den Dienst weiterleitet. Aber wenn wir die Handler in logische Gruppen aufteilen m\u00fcssen, erfolgt die Aufteilung mit Hilfe von Tags. Bei Angabe eines Tags wird die Anfrage an eine bestimmte Gruppe von Controllern weitergeleitet.<\/li>\n<li>Anfragetag. Erm\u00f6glicht es, Antworten zu unterscheiden. Da unser System asynchron ist, muss beim Verarbeiten der Antworten des Dienstes die M\u00f6glichkeit bestehen, einen RequestTag beim Senden der Anfrage anzugeben. Anhand dieses Tags k\u00f6nnen wir verstehen, auf welche Anfrage unsere Antwort eingegangen ist.<\/li>\n<\/ul>\n<p><\/p>\n<h3 id=\"pub-sub\">Pub-sub<\/h3>\n<p><\/p>\n<p>F\u00fcr pub-sub ist alles etwas einfacher. Wir haben einen Austauschpunkt, an dem Nachrichten ver\u00f6ffentlicht werden. Der Austauschpunkt verteilt die Nachrichten an die Abonnenten, die sich f\u00fcr die gew\u00fcnschten Routing-Schl\u00fcssel angemeldet haben (man kann sagen, dass dies das Pendant zu Themen ist).<\/p>\n<p><\/p>\n<h2 id=\"masshtabiruemost-i-otkazoustoychivost\">Skalierbarkeit und Fehlertoleranz<\/h2>\n<p><\/p>\n<p>Die Skalierbarkeit des Systems insgesamt h\u00e4ngt vom Grad der Skalierbarkeit der Schichten und Komponenten des Systems ab:<\/p>\n<p><\/p>\n<ul>\n<li>Die Dienste skalieren, indem zus\u00e4tzliche Knoten mit den Prozessoren dieses Dienstes zum Cluster hinzugef\u00fcgt werden. W\u00e4hrend des praktischen Betriebs kann eine optimale Lastverteilungsstrategie ausgew\u00e4hlt werden.<\/li>\n<li>Der Messaging-Dienst selbst l\u00e4sst sich im Rahmen eines separaten Clusters im Allgemeinen entweder durch Verlagerung von stark beanspruchten Austauschpunkten auf separate Knoten des Clusters oder durch Hinzuf\u00fcgen von Proxy-Prozessen in besonders belastete Zonen des Clusters skalieren.<\/li>\n<li>Die Skalierbarkeit des gesamten Systems als Merkmal h\u00e4ngt von der Flexibilit\u00e4t der Architektur und der M\u00f6glichkeit ab, einzelne Cluster zu einer gemeinsamen logischen Einheit zusammenzufassen.<\/li>\n<\/ul>\n<p><\/p>\n<p>Die Einfachheit und Geschwindigkeit der Skalierung bestimmen oft den Erfolg eines Projekts. Messaging in der aktuellen Ausf\u00fchrung w\u00e4chst mit der Anwendung. Selbst wenn wir nicht genug Cluster mit 50-60 Maschinen haben, k\u00f6nnen wir auf F\u00f6deration zur\u00fcckgreifen. Leider geht das Thema F\u00f6deration \u00fcber den Rahmen dieses Artikels hinaus.<\/p>\n<p><\/p>\n<h2 id=\"rezervirovanie\">Reservierung<\/h2>\n<p><\/p>\n<p>Bei der Diskussion zur Lastverteilung haben wir bereits die Redundanz der Dienstcontroller angesprochen. Allerdings sollte auch der Messaging-Dienst redundant sein. Im Falle eines Ausfalls eines Knotens oder einer Maschine muss Messaging automatisch wiederhergestellt werden, und zwar in k\u00fcrzester Zeit.<\/p>\n<p><\/p>\n<p>In meinen Projekten verwende ich zus\u00e4tzliche Knoten, die die Last im Falle eines Ausfalls \u00fcbernehmen. In Erlang gibt es eine Standardimplementierung des verteilten Modus f\u00fcr OTP-Anwendungen. Der verteilte Modus f\u00fchrt die Wiederherstellung im Falle eines Fehlers durch, indem die ausgefallene Anwendung auf einem anderen zuvor gestarteten Knoten ausgef\u00fchrt wird. Der Prozess ist transparent, nach einem Ausfall wechselt die Anwendung automatisch auf den Failover-Knoten. Weitere Informationen zu dieser Funktion finden Sie hier. <noindex><a rel=\"nofollow\" href=\"http:\/\/erlang.org\/doc\/design_principles\/distributed_applications.html\">hier<\/a><\/noindex>.<\/p>\n<p><\/p>\n<h2 id=\"proizvoditelnost\">Leistung<\/h2>\n<p><\/p>\n<p>Lassen Sie uns zumindest ann\u00e4hernd die Leistung von RabbitMQ und unserem benutzerdefinierten Messaging vergleichen.<br \/>\nIch habe gefunden <noindex><a rel=\"nofollow\" href=\"https:\/\/docs.openstack.org\/developer\/performance-docs\/test_results\/mq\/rabbitmq\/cmsm\/index.html\">offizielle Ergebnisse<\/a><\/noindex> der RabbitMQ-Testreihe vom OpenStack-Team.<\/p>\n<p><\/p>\n<p>Im Punkt 6.14.1.2.1.2.2 des Originals wird das Ergebnis von RPC CAST angegeben:<br \/>\n<img decoding=\"async\" alt=\"Bausteine verteilter Anwendungen. Zweite Ann\u00e4herung\" src=\"\/wp-content\/uploads\/2019\/04\/95f615d241d70a4523fe3c400179b8e6.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Vorl\u00e4ufig werden keine zus\u00e4tzlichen Einstellungen im Betriebssystem oder der Erlang-VM vorgenommen. Die Bedingungen f\u00fcr das Testen sind:<\/p>\n<p><\/p>\n<ul>\n<li>erl opts: +A1 +sbtu.<\/li>\n<li>Der Test auf einem einzelnen Erlang-Knoten wird auf einem Laptop mit einem \u00e4lteren i7 im mobilen Format durchgef\u00fchrt.<\/li>\n<li>Die Cluster-Tests werden auf Servern mit einem 10G-Netzwerk durchgef\u00fchrt.<\/li>\n<li>Der Code l\u00e4uft in Docker-Containern. Netzwerk im NAT-Modus.<\/li>\n<\/ul>\n<p><\/p>\n<p>Testcode:<\/p>\n<p><\/p>\n<pre><code class=\"erlang\">req_resp_bench(_) -&gt;\n  W = perftest:comprehensive(10000,\n    fun() -&gt;\n      messaging:request(?EXCHANGE, default, ping, self()),\n      receive\n        #'$msg'{message = pong} -&gt; ok\n      after 5000 -&gt;\n        throw(timeout)\n      end\n    end\n  ),\n  true = lists:any(fun(E) -&gt; E &gt;= 30000 end, W),\n  ok.<\/code><\/pre>\n<p><\/p>\n<p><em>Szenario 1:<\/em> Der Test wird auf einem Laptop mit einem \u00e4lteren i7-Mobilprozessor durchgef\u00fchrt. Test, Messaging und Service laufen auf demselben Knoten in demselben Docker-Container:<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">Sequentiell 10000 Zyklen in ~0 Sekunden (26987 Zyklen\/s)\nSequentiell 20000 Zyklen in ~1 Sekunden (26915 Zyklen\/s)\nSequentiell 100000 Zyklen in ~4 Sekunden (26957 Zyklen\/s)\nParallel 2 100000 Zyklen in ~2 Sekunden (44240 Zyklen\/s)\nParallel 4 100000 Zyklen in ~2 Sekunden (53459 Zyklen\/s)\nParallel 10 100000 Zyklen in ~2 Sekunden (52283 Zyklen\/s)\nParallel 100 100000 Zyklen in ~3 Sekunden (49317 Zyklen\/s)<\/code><\/pre>\n<p><\/p>\n<p><em>Szenario 2<\/em>: 3 Knoten, die auf verschiedenen Maschinen unter Docker (NAT) laufen.<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">Sequentiell 10000 Zyklen in ~1 Sekunden (8684 Zyklen\/s)\nSequentiell 20000 Zyklen in ~2 Sekunden (8424 Zyklen\/s)\nSequentiell 100000 Zyklen in ~12 Sekunden (8655 Zyklen\/s)\nParallel 2 100000 Zyklen in ~7 Sekunden (15160 Zyklen\/s)\nParallel 4 100000 Zyklen in ~5 Sekunden (19133 Zyklen\/s)\nParallel 10 100000 Zyklen in ~4 Sekunden (24399 Zyklen\/s)\nParallel 100 100000 Zyklen in ~3 Sekunden (34517 Zyklen\/s)<\/code><\/pre>\n<p><\/p>\n<p>In allen F\u00e4llen \u00fcberschritt die CPU-Auslastung nicht 250%<\/p>\n<p><\/p>\n<h2 id=\"itogi\">Ergebnisse<\/h2>\n<p><\/p>\n<p>Ich hoffe, dieser Zyklus wirkt nicht wie ein Bewusstseinsdump und meine Erfahrung wird sowohl Forschern im Bereich der verteilten Systeme als auch Praktikern, die am Anfang ihrer Reise stehen, um verteilte Architekturen f\u00fcr ihre Gesch\u00e4ftssysteme aufzubauen und interessiert auf Erlang\/Elixir schauen, aber sich unsicher sind, ob es sich lohnt...<\/p>\n<p><\/p>\n<p>Foto <noindex><a rel=\"nofollow\" href=\"https:\/\/unsplash.com\/photos\/Q4bmoSPJM18\">@chuttersnap<\/a><\/noindex><\/p>\n<p class=\"for_users_only_msg\">Nur registrierte Benutzer k\u00f6nnen an der Umfrage teilnehmen. <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/auth\/login\/\">Bitte einloggen<\/a><\/noindex>.<\/p>\n<h2 class=\"default-block__polling-title\">Welche Themen sollte ich im Rahmen des Zyklus \u201eExperiment VTrade\u201c ausf\u00fchrlich behandeln?<\/h2>\n<ul class=\"content-list content-list_polling\">\n<li class=\"content-list__item content-list__item_polling\">\n<p>                    Theorie: M\u00e4rkte, Auftr\u00e4ge und deren G\u00fcltigkeitsdauer: TAG, GTD, GTC, IOC, FOK, MOO, MOC, LOO, LOC<\/p>\n<\/li>\n<li class=\"content-list__item content-list__item_polling\">\n<p>                    Orderbuch. Theorie und Praxis der Implementierung eines Buches mit Gruppierungen<\/p>\n<\/li>\n<li class=\"content-list__item content-list__item_polling\">\n<p>                    Visualisierung des Handels: Ticks, Balken, Aufl\u00f6sungen. Wie man speichert und wie man verbindet<\/p>\n<\/li>\n<li class=\"content-list__item content-list__item_polling\">\n<p>                    Backoffice. Planung und Entwicklung. Mitarbeiter\u00fcberwachung und Vorfalluntersuchung<\/p>\n<\/li>\n<li class=\"content-list__item content-list__item_polling\">\n<p>                    API. Lassen Sie uns herausfinden, welche Schnittstellen ben\u00f6tigt werden und wie sie implementiert werden k\u00f6nnen<\/p>\n<\/li>\n<li class=\"content-list__item content-list__item_polling\">\n<p>                    Datenhaltung: PostgreSQL, Timescale, Tarantool in Handelssystemen<\/p>\n<\/li>\n<li class=\"content-list__item content-list__item_polling\">\n<p>                    Reaktivit\u00e4t in Handelssystemen<\/p>\n<\/li>\n<li class=\"content-list__item content-list__item_polling\">\n<p>                    Sonstiges. Ich werde es in den Kommentaren schreiben<\/p>\n<\/li>\n<\/ul>\n<p>    6 Benutzer haben abgestimmt. 4 Benutzer haben sich enthalten.<br \/>\n<br \/>Quelle: <a content=\"nofollow\" rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/post\/446344\/\">habr.com<\/a><\/p>","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"excerpt":{"rendered":"<p>\u0410\u043d\u043e\u043d\u0441 \u041a\u043e\u043b\u043b\u0435\u0433\u0438, \u0432 \u0441\u0435\u0440\u0435\u0434\u0438\u043d\u0435 \u043b\u0435\u0442\u0430 \u044f \u043f\u043b\u0430\u043d\u0438\u0440\u0443\u044e \u0432\u044b\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u0435\u0449\u0435 \u043e\u0434\u0438\u043d \u0446\u0438\u043a\u043b \u0441\u0442\u0430\u0442\u0435\u0439 \u043f\u043e \u043f\u0440\u043e\u0435\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044e \u0441\u0438\u0441\u0442\u0435\u043c \u043c\u0430\u0441\u0441\u043e\u0432\u043e\u0433\u043e \u043e\u0431\u0441\u043b\u0443\u0436\u0438\u0432\u0430\u043d\u0438\u044f: \u201c\u042d\u043a\u0441\u043f\u0435\u0440\u0438\u043c\u0435\u043d\u0442 VTrade\u201d \u2014 \u043f\u043e\u043f\u044b\u0442\u043a\u0430 \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a \u0434\u043b\u044f \u0442\u043e\u0440\u0433\u043e\u0432\u044b\u0445 \u0441\u0438\u0441\u0442\u0435\u043c. \u0412 \u0446\u0438\u043a\u043b\u0435 \u0431\u0443\u0434\u0435\u0442 \u0440\u0430\u0437\u043e\u0431\u0440\u0430\u043d\u0430 \u0442\u0435\u043e\u0440\u0438\u044f \u0438 \u043f\u0440\u0430\u043a\u0442\u0438\u043a\u0430 \u043f\u043e\u0441\u0442\u0440\u043e\u0435\u043d\u0438\u044f \u0431\u0438\u0440\u0436\u0438, \u0430\u0443\u043a\u0446\u0438\u043e\u043d\u0430 \u0438 \u043c\u0430\u0433\u0430\u0437\u0438\u043d\u0430. \u0412 \u043a\u043e\u043d\u0446\u0435 \u0441\u0442\u0430\u0442\u044c\u0438 \u043f\u0440\u0435\u0434\u043b\u0430\u0433\u0430\u044e \u043f\u0440\u043e\u0433\u043e\u043b\u043e\u0441\u043e\u0432\u0430\u0442\u044c \u0437\u0430 \u043d\u0430\u0438\u0431\u043e\u043b\u0435\u0435 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u044b\u0435 \u0432\u0430\u043c \u0442\u0435\u043c\u044b. \u042d\u0442\u043e \u0437\u0430\u0432\u0435\u0440\u0448\u0430\u044e\u0449\u0430\u044f \u0441\u0442\u0430\u0442\u044c\u044f \u0446\u0438\u043a\u043b\u0430 \u043f\u043e \u0440\u0430\u0441\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u044b\u043c \u0440\u0435\u0430\u043a\u0442\u0438\u0432\u043d\u044b\u043c [&hellip;]<\/p>\n","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"author":1,"featured_media":23092,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[688],"tags":[],"class_list":["post-31124","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-administrirovanie"],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 5.0.1.1 - aioseo.com -->\n\t<meta name=\"description\" content=\"\u0410\u043d\u043e\u043d\u0441 \u041a\u043e\u043b\u043b\u0435\u0433\u0438, \u0432 \u0441\u0435\u0440\u0435\u0434\u0438\u043d\u0435 \u043b\u0435\u0442\u0430 \u044f \u043f\u043b\u0430\u043d\u0438\u0440\u0443\u044e \u0432\u044b\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u0435\u0449\u0435 \u043e\u0434\u0438\u043d \u0446\u0438\u043a\u043b \u0441\u0442\u0430\u0442\u0435\u0439 \u043f\u043e \u043f\u0440\u043e\u0435\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044e \u0441\u0438\u0441\u0442\u0435\u043c \u043c\u0430\u0441\u0441\u043e\u0432\u043e\u0433\u043e \u043e\u0431\u0441\u043b\u0443\u0436\u0438\u0432\u0430\u043d\u0438\u044f: \u201c\u042d\u043a\u0441\u043f\u0435\u0440\u0438\u043c\u0435\u043d\u0442 VTrade\u201d \u2014 \u043f\u043e\u043f\u044b\u0442\u043a\u0430 \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a \u0434\u043b\u044f \u0442\u043e\u0440\u0433\u043e\u0432\u044b\u0445.\" \/>\n\t<meta name=\"robots\" content=\"max-image-preview:large\" \/>\n\t<meta name=\"author\" content=\"Yuri Gagarin\"\/>\n\t<link rel=\"canonical\" href=\"https:\/\/prohoster.info\/de\/blog\/administrirovanie\/stroitelnye-bloki-raspredelennyh-prilozhenij-vtoroe-priblizhenie\" \/>\n\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.1.1\" \/>\n\t\t<meta property=\"og:locale\" content=\"de_DE\" \/>\n\t\t<meta property=\"og:site_name\" content=\"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b\" \/>\n\t\t<meta property=\"og:type\" content=\"article\" \/>\n\t\t<meta property=\"og:title\" content=\"\ud83e\udd47\u0421\u0442\u0440\u043e\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u0431\u043b\u043e\u043a\u0438 \u0440\u0430\u0441\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u044b\u0445 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439. \u0412\u0442\u043e\u0440\u043e\u0435 \u043f\u0440\u0438\u0431\u043b\u0438\u0436\u0435\u043d\u0438\u0435 | ProHoster\" \/>\n\t\t<meta property=\"og:description\" content=\"\u0410\u043d\u043e\u043d\u0441 \u041a\u043e\u043b\u043b\u0435\u0433\u0438, \u0432 \u0441\u0435\u0440\u0435\u0434\u0438\u043d\u0435 \u043b\u0435\u0442\u0430 \u044f \u043f\u043b\u0430\u043d\u0438\u0440\u0443\u044e \u0432\u044b\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u0435\u0449\u0435 \u043e\u0434\u0438\u043d \u0446\u0438\u043a\u043b \u0441\u0442\u0430\u0442\u0435\u0439 \u043f\u043e \u043f\u0440\u043e\u0435\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044e \u0441\u0438\u0441\u0442\u0435\u043c \u043c\u0430\u0441\u0441\u043e\u0432\u043e\u0433\u043e \u043e\u0431\u0441\u043b\u0443\u0436\u0438\u0432\u0430\u043d\u0438\u044f: \u201c\u042d\u043a\u0441\u043f\u0435\u0440\u0438\u043c\u0435\u043d\u0442 VTrade\u201d \u2014 \u043f\u043e\u043f\u044b\u0442\u043a\u0430 \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a \u0434\u043b\u044f \u0442\u043e\u0440\u0433\u043e\u0432\u044b\u0445.\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/prohoster.info\/de\/blog\/administrirovanie\/stroitelnye-bloki-raspredelennyh-prilozhenij-vtoroe-priblizhenie\" \/>\n\t\t<meta property=\"og:image\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:secure_url\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:width\" content=\"350\" \/>\n\t\t<meta property=\"og:image:height\" content=\"350\" \/>\n\t\t<meta property=\"article:published_time\" content=\"2019-10-31T18:39:36+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2019-10-31T18:39:36+00:00\" \/>\n\t\t<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<meta property=\"article:author\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<!-- All in One SEO -->\n\n","aioseo_head_json":{"title":"\ud83e\udd47Bausteine verteilter Anwendungen. Zweite Ann\u00e4herung | ProHoster","description":"Ank\u00fcndigung: Kollegen, ich plane Mitte Sommer, einen weiteren Zyklus von Artikeln \u00fcber das Design von Systemen f\u00fcr den Massenservice zu ver\u00f6ffentlichen: \"Experiment VTrade\" - der Versuch, ein Framework f\u00fcr Handelsanwendungen zu schreiben.","canonical_url":"https:\/\/prohoster.info\/de\/blog\/administrirovanie\/stroitelnye-bloki-raspredelennyh-prilozhenij-vtoroe-priblizhenie","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"de_DE","og:site_name":"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b","og:type":"article","og:title":"\ud83e\udd47\u0421\u0442\u0440\u043e\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u0431\u043b\u043e\u043a\u0438 \u0440\u0430\u0441\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u044b\u0445 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439. \u0412\u0442\u043e\u0440\u043e\u0435 \u043f\u0440\u0438\u0431\u043b\u0438\u0436\u0435\u043d\u0438\u0435 | ProHoster","og:description":"\u0410\u043d\u043e\u043d\u0441 \u041a\u043e\u043b\u043b\u0435\u0433\u0438, \u0432 \u0441\u0435\u0440\u0435\u0434\u0438\u043d\u0435 \u043b\u0435\u0442\u0430 \u044f \u043f\u043b\u0430\u043d\u0438\u0440\u0443\u044e \u0432\u044b\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u0435\u0449\u0435 \u043e\u0434\u0438\u043d \u0446\u0438\u043a\u043b \u0441\u0442\u0430\u0442\u0435\u0439 \u043f\u043e \u043f\u0440\u043e\u0435\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044e \u0441\u0438\u0441\u0442\u0435\u043c \u043c\u0430\u0441\u0441\u043e\u0432\u043e\u0433\u043e \u043e\u0431\u0441\u043b\u0443\u0436\u0438\u0432\u0430\u043d\u0438\u044f: \u201c\u042d\u043a\u0441\u043f\u0435\u0440\u0438\u043c\u0435\u043d\u0442 VTrade\u201d \u2014 \u043f\u043e\u043f\u044b\u0442\u043a\u0430 \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a \u0434\u043b\u044f \u0442\u043e\u0440\u0433\u043e\u0432\u044b\u0445.","og:url":"https:\/\/prohoster.info\/de\/blog\/administrirovanie\/stroitelnye-bloki-raspredelennyh-prilozhenij-vtoroe-priblizhenie","og:image":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:secure_url":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:width":350,"og:image:height":350,"article:published_time":"2019-10-31T18:39:36+00:00","article:modified_time":"2019-10-31T18:39:36+00:00","article:publisher":"https:\/\/www.facebook.com\/prohoster","article:author":"https:\/\/www.facebook.com\/prohoster"},"aioseo_meta_data":{"post_id":"31124","title":null,"description":null,"keywords":null,"keyphrases":null,"primary_term":null,"canonical_url":null,"og_title":null,"og_description":null,"og_object_type":"default","og_image_type":"default","og_image_url":null,"og_image_width":null,"og_image_height":null,"og_image_custom_url":null,"og_image_custom_fields":null,"og_video":null,"og_custom_url":null,"og_article_section":null,"og_article_tags":null,"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"default","twitter_image_url":null,"twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_title":null,"twitter_description":null,"schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":[],"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"","isEnabled":true},"graphs":[]},"schema_type":null,"schema_type_options":null,"pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":null,"robots_max_videopreview":null,"robots_max_imagepreview":"large","priority":null,"frequency":null,"local_seo":null,"seo_analyzer_scan_date":"2026-01-21 04:39:19","breadcrumb_settings":null,"limit_modified_date":false,"reviewed_by":null,"ai":null,"created":"2021-03-01 03:22:34","updated":"2026-01-21 04:39:19","focus_keyword":null,"additional_keywords":null,"truseo_locale":null},"gt_translate_keys":[{"key":"link","format":"url"}],"_links":{"self":[{"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/posts\/31124","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/comments?post=31124"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/posts\/31124\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/media\/23092"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/media?parent=31124"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/categories?post=31124"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/tags?post=31124"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}