Makler

(Broker)

von Andreas Krutscher, WI6443

[ Seminarübersicht] ... [Architekturmuster] ... [Literatur] ... [ > ] 


Name

Makler (Broker)

Das Makler Architekturmuster dient der Strukturierung von verteilten Systemen. Getrennte Komponenten interoperieren miteinander, indem sie Dienste entfernter Komponenten aufrufen. Eine Makler-Komponente koordiniert die Kommunikation indem sie Anfragen weiterleitet und Ergebnisse oder Fehlermeldungen übermittelt.


Auch bekannt als

(Für dieses Muster gibt es kein Synonym)


Beispiel

Als Beispiel für ein Brokersystem wollen wir ein City Information System (CIS) betrachten. Es soll für ein Wide Area Network (WAN) entworfen werden. In diesem WAN gibt es einige Computer, die Dienste anbieten: z.B. Informationen über Hotels, Verkehrsbetriebe, Historisches, Sehenswürdigkeiten etc. Es gibt Terminals, mit denen Touristen sich informieren können. Diese Terminals verfügen über einen gewöhnlichen WWW-Browser.
Es wird gefordert, daß die Daten nicht in jedem Terminal lokal gehalten werden, sondern übers Netz verteilt sind. Von dem System erwarten wir, daß es stetig wächst und um neue Dienste erweitert wird. Deshalb ist es sinnvoll, die Dienste voneinander getrennt und unabhängig auf verschiedenen Servern zu halten. Terminals sollen nicht wissen müssen, wo die Dienste liegen. Dadurch können später Dienste verschoben, ersetzen, hinzugefügt oder entfernt werden.
Die Anbieter von Diensten stellen die Forderung, daß Dienste, die sie anbieten auch von aller Welt aus zu erreichen sind um potentielle Touristen zu locken. Das stellt die Überlegung nahe, als Grundlage des CIS das Internet zu benutzen.


Kontext

Die Zielumgebung ist ein verteiltes und möglicherweise heterogenes System von unabhängig zusammen arbeitenden Komponenten.


Problemstellung

Wir wollen ein komplexes Softwaresystem entkoppelter Komponenten erstellen. Das ist besser als monolithische Applikation, weil wir uns so größerer Flexibilität, Wartbarkeit, und Erweiterbarkeit versprechen. Da die Komponenten in irgendeiner Weise zusammenarbeiten sollen müssen wir uns um irgendeine Art von Inter-Prozeß Kommunikation kümmern. Eine Möglichkeit ist, alle Komponenten direkt miteinander zu verbinden - jede Komponente weiß die Adressen aller anderen. Das resultiert jedoch in einer hohen Abhängigkeiten von speziellen Protokollen und schwerer Wartbarkeit. Würde ein Dienst von einem Server auf einen anderen verschoben werden, müßte allen Clients die neue Adresse des Dienstes mitgeteilt werden.
Neben der Inter-Prozeß Kommunikation müssen wir uns auch um die Möglichkeiten des Hinzufügen, Entfernen, Austauschen, Aktivieren und Auffinden von Komponenten Gedanken machen. Änderungen an der Menge der veröffentlichten Dienste sollen nach Möglichkeit nur an einer Stelle im System bekanntgemacht werden müssen.
Für den Entwickler ist noch wichtig, daß es keinen Programmiertechnischen Unterschied macht, ob ein angesprochener Dienst zentralisiert oder verteilt ist. Er will nur die Schnittstelle von Objekten sehen. Die Implementierungsdetails der Dienste sollen verborgen bleiben.


Lösung

Erstelle eine Broker-Komponente um Clients und Server besser zu trennen. Server registrieren sich selber bei der Broker-Komponente, d.h. nachdem ein Dienst auf einem Server gestartet wurde soll er sich bei einem Broker anmelden und sein Interface bekanntgeben.
Clients benutzen Dienste, indem sie eine Anfrage an Broker schicken. Der Broker macht den gewünschten Dienst im System ausfindig und leitet die Anfrage an diesen weiter. Nach Ausführung der Anfrage übermittelt er Ergebnisse oder Fehlermeldungen zurück an den Client.

Vorteile dieses Systems:

  • Clients können Anfragen an bevorzugte Server schicken
  • ohne sich um low-level Inter-Prozeß-Kommunikation zu kümmern
  • Der Broker kann flexibel reagieren (Services austauschen etc...)
  • Das Broker-Muster reduziert die Komplexität des Gesamtsystems
  • Verteilung ist transparent für den Entwickler
  • Wie wird das erreicht? Durch Einführung eines Objektmodells. Dienste sind in Objekten gekapselt die über eine Schnittstellenbeschreibung ihre Dienste nach Außen verfügbar machen. Hierbei werden zwei Kern-Technologien vereinigt: Verteilte Systeme und Objekttechnologie. Die Objekt-Modelle von Programmiersprachen werden dazu um die Fähigkeit erweitert, nicht nur Objekte anzusprechen, die im jeweiligen Programmkontext lokal verfügbar sind. Vielmehr kann schon während der Entwicklung von Applikationen auf Objekte zugegriffen werden, die in einem anderen Prozeß oder gar auf einem entfernten Rechner existieren. Dabei ist es egal, in welcher Programmiersprache diese Objekte implementiert sind und unter welchem Betriebssystem sie laufen.


    Struktur

    Server

    Ein Server veröffentlicht seine Funktionen - Operationen und Attribute - über Schnittstellen und macht sie über eine Interface Definition Language (IDL) oder durch einen binären Standard, der von Clients verstanden wird verfügbar. Es gibt Server, die ihre Dienste für viele andere Applikationen anbieten und solche, die ihre Dienste an genau eine Applikation, Domäne oder einen Prozeß richten.
    In unserem CIS-Beispiel gibt es WWW-Dienste, die durch HTTPD (HTTP-Deamons, -Server) implementiert sind. Sie bieten ihre Dienste in Form von HTML-Dokumenten an. Sie warten auf einem definierten Port (80) auf Anfragen von Clients. Eine Antworte auf eine eingegangene Anfrage wird mittels eines Datenstroms (Data-Stream) an den Client zurückgeschickt. Anfragen können Parameter enthalten (CGI-Scripts), die auf dem Server ausgewertet werden. So ist eine Suche nach Hotelräumen und deren Reservierung möglich. Außerdem bieten manche Server Java-Applets an, die auf dem Client ausgeführt werden. Mit Applets wird  z.B. ein Weg im Stadtplan animiert darstellen.
     
    Server Mitarbeiter 
  • Server-seitiger Proxy
  • Broker

  •  
    Verantwortlichkeit 
  • Implementiert Dienst
  • Registrieren beim lokalen Broker
  • Antworten und Ausnahmen an Client über s.-s. Proxy senden
  • Client

    Clients sind Applikationen, die die Dienste eines Servers nutzen. Für den Aufruf eines Dienstes wird eine Anfrage an den Broker geschickt. Dieser übermittelt dann die Resultate oder Fehlermeldungen.
    Im Gegensatz zum traditionellen Client-Server Modell steht das dynamische Modell, in dem auch Server als Clients agieren können. Ob eine Komponente ein Client oder ein Server ist, ist dann nicht statisch definiert.
    In unserem Beispiel sind die Clients einfache WWW-Browser, die nicht direkt, sondern über Provider (z.B. Compuserve, AOL oder T-Online) mit dem Internet verbunden sind. Die Provider agiert in solchen Fällen als Broker, die die Anfragen weiterleiten. Das Verbindungsprotokoll eines Providers ist möglicherweise unterschiedlich von dem im Internet vorherrschenden TCP/IP Protokoll.
     
    Client Mitarbeiter 
  • Client-seitiger Proxy
  • Broker

  •  
    Verantwortlichkeit 
  • Implementiert Funktionalität für Benutzer
  • Sendet Anfrage über c.-s. Proxy an einen Server
  • Broker

    Der Broker (Makler) ist verantwortlich für die Übermittlung der Anfragen und Ergebnisse. Er muß die Möglichkeit haben, den Empfänger einer Anfrage basierend auf einem System-Identifikator ausfindig zu machen. Er bietet eine Programmierschnittstelle (API) für Clients und Server, damit diese sich registrieren können oder die Schnittstellen entfernter Objekte abfragen können.
    Empfängt ein Broker eine Anfrage, so prüft dieser zuerst, ob der gewünschte Dienst lokal verfügbar ist. Ist dies der Fall, so stellt der Broker die Anfrage direkt zu. Sollte der Dienst inaktiv sein, so aktiviert er diesen. Ist der Dienst nicht lokal verfügbar, so leitet der Broker die Anfrage über eine Bridge-Komponente an einen entfernten Broker weiter, der die Anfrage dann entgegen nimmt und bearbeitet.
    Abhängig von den Forderungen an das Gesamtsystem sind weitere Dienste wie Name Service und Marshalling erforderlich. Durch einen Name Service werden Server und Clients über einen Namen identifizierbar gemacht. Marshalling macht Daten systemübergreifend kompatibel (z.B. „ä“ -> „ä“; 8bit -> 7bit ).
    Ein Broker in unserem CIS-Beispiel ist die Kombination eines Internet-Zugangs und die Internet Infrastruktur selbst. Jede Information muß durch ein Gateway geschleust werden. Clients benutzen URL's (Names) um Server zu adressieren. Anhand des Serveradreß-Anteils ermittelt der Broker die IP-Adresse (Name-Service, DNS) eines Servers. Clients benutzen das Gateway ihres Providers als Interface zum Broker.
     
    Broker Mitarbeiter 
  • Client
  • Server
  • Client-seitiger Proxy
  • Server-seitiger Proxy
  • Bridge
  • Verantwortlichkeit 
  • Registriert Server
  • Bietet APIs
  • Übermittelt Nachrichten
  • Fehlererkennung, -behandlung
  • Operiert mit anderen Brokern zusammen
  • Findet Server
  • Clientseitiger Proxy

    Der Proxy ist eine Layerkomponente zwischen dem Client und dem Broker. Er bietet zusätzliche Transparenz. Entfernte Objekte erscheinen wie lokale. Ein Proxy verbirgt u.a. die Inter-Prozess Kommunikation vor dem Client. Seine Aufgaben sind das Erzeugen und Löschen von Speicherbereichen für Cachingzwecke und das Marshalling (s.o.). Oft sorgt ein Proxy für die Anpassung des Broker-Objektmodells an das der Client-Applikation.
     
    Clientseitiger Proxy Mitarbeiter 
  • Client
  • Broker

  •  
    Verantwortlichkeit 
  • Kapselt system-spezifische Funktionalität
  • Vermittelt zwischen Client und Broker
  • Serverseitiger Proxy

    Ein Serverseitiger Proxy funktioniert generell wie ein clientseitiger Proxy. Er ist verantwortlich für...
  • Empfang von Anfragen
  • Entpacken der Nachrichten
  • Unmarshalling
  • Aufruf des entsprechenden Dienstes beim Server

  • Das gleiche gilt natürlich in umgekehrter Reihenfolge, also für das Zurücksenden der Resultate synonym.
    In unserem Beispiel brauchen wir uns um Proxies nicht zu kümmern, da sowohl die Server als auch die Clients eigene Implementierungen von Proxies haben um mit ihren Providern zu kommunizieren.
     
    Serverseitiger Proxy Mitarbeiter 
  • Server
  • Broker
  • Verantwortlichkeit 
  • Ruft Dienste des Servers auf
  • Kapselt system-spezifische Funktionalität
  • Vermittelt zwischen Server und Broker
  • Bridge

    Die Brücke (Bridge) ist eine optionale Komponenten. Sie besorgt die Anpassung zwischen verschiedenen Brokersystemen auf heterogenen Netzen. Im CIS-Beispiel können wir Brücken ebenso außer Acht lassen, da alle Broker das gleiche Protokoll verwenden (TCP/IP).
     
    Bridge Mitarbeiter 
  • Broker
  • Bridge
  • Verantwortlichkeit 
  • Kapslet Netzwerk-spezifische Funktionalität
  • Vermittelt zwischen dem lokalem Broker und der Bridge eines entfernten Brokers
  • Brokervarianten

    Direkte Kommunikation. Hier baut der Broker eine Verbindung zwischen einem Client und dem gewünschten Server auf. Client und Server kommunizieren danach eigenständig. Beispiele hierfür sind eine Telefon- oder Telnet-Verbindung. Der Vorteil ist, daß die Kommunikation sehr schnell ist. Als Konsequenz ist hinzunehmen, daß beide beteiligten Parteien das gleiche Protokoll verstehen müssen. Diese Brokervariante wird hier nicht weiter betrachtet werden.

    Indirekte Kommunikation. Der Broker kommuniziert mit Clients und Servern. Es existiert keine direkte Verbindung. Beispiele sind der Telegrammdienst oder eine eMail-Anfrage an einen Server, der seine Ergebnisse per Mail an den Client zurückschickt. In unserem Beispiel haben wir nur mit indirekter Kommunikation zu tun.

    Darstellung der teilhabenden Komponenten in einem Klassendiagramm

     


    Interaktionen

    Szenario I: Registrierung eines Servers bei einem Broker

    Der Broker startet bei der Initialisierung des Systems (erstes Objekt) und geht in einen Wartezustand (Main event loop) über. Der Benutzer startet eine Server-Applikation, der Server initialisiert sich selbst und registriert sich beim Broker. Der Broker empfängt die Registrierung und extrahiert alle wesentlichen Daten und speichern sie in seine Datenbank. Das ist notwendig, damit er später den Server lokalisieren und Aktivieren kann. Nach erfolgreicher Registrierung sendet er eine Bestätigung an den Server zurück. Dieser empfängt die Bestätigung und verzweigt in eine Warteschleife, in der er auf Client-Anfragen wartet.

    Szenario II: Client sendet eine Anfrage an einen lokalen Server

    Im hier dargestellten fall wird der Client solange blockiert, bis er die Antwort des Servers erhält. In diesem Fall erfolgt ein synchroner Aufruf . Ein asynchroner Aufruf ist auch denkbar. Dann wäre der Client für andere Aufgaben frei während er auf die Antwort von Server wartet.
    Nachdem die Client-Applikation gestartet wurde erfolgt ein Aufruf einer Methode eines entfernten Servers. Der clientseitiger Proxy packt alle Parameter und relevaten Informationen und sendet sie zum Broker. Der Broker ermittelt nun den Standort des Servers. Ist dieser lokal verfügbar, so wird die Anfrage an den Proxy des lokalen Servers weitergeleitet. Ist der Dienst auf einem entfernten Rechner verfügbar, so wird wie in Szenario III dargestellt verfahren. Hier empfängt der serverseitige Proxy die Anfrage vom Broker und entpackt die enthaltenen Daten wie z.B. den Methodennamen. Diese Daten verwendet der Proxy um den entsprechenden Dienst des Servers mit den angegebenen Parametern aufzurufen. Nach Abarbeitung des Dienstes empfängt der Proxy die Resultate vom Server und packt sie für den Rücktransport zum Broker. Der Broker leitet sie seinerseits an den clientseitigen Proxy weiter. Dieser empfängt die Antwort und entpackt die darin enthaltenen Resultate und übergibt sie an den Client. Schlußendlich fährt der Client mit seiner Arbeit fort.

    Szenario III: Interaktion zwischen zwei Brokern über Brückenelemente

    Nachdem Broker A eine Anfrage erhalten hat ermittelt er die Adresse des zuständigen Servers. Er stellt fest, daß dieser nicht lokal verfügbar ist. Deswegen muß er die Anfrage an den zuständigen Broker weiterleiten. Hierzu wird die Nachricht vom  Broker A an seine Brücke A geschickt. Diese konvertiert die Nachricht in ein systemunabhängiges Format und verschickt sie an die Brücke des Brokers B. Brücke B wandelt die Nachricht in das Broker B-spezifische Format um. Nun erledigt Broker B alle notwendigen Schritte wie in Szenario II.


    Implementierung

    1. Definiere ein Objekt-Modell, oder verwende ein bestehendes

    Das Objekt-Modell hat großen Einfluß auf den gesamten Rest des Systems und deren Entwicklung. Es bildet die Fassade des Servers nach außen hin. Zuerst sind semantische Fragen des Modells zu betrachten, z.B. ob das Modell Erweiterbarkeit, also Vererbungsmechanismen wie sie bei IBM's SOM/DSOM möglich sind unterstützen soll. Eine Kernfrage ist dabei, wie Methoden definiert und aufgerufen werden. Wie sollen Serverobjekte erstellt und wieder zerstört werden? Wie wird der interne Zustand eines Servers definiert? Diese und andere Fragestellungen sind dabei zu betrachten. Interne Zustände der Server sollen von Clients aus nicht erreichbar, aber über Anfragen an ihren lokalen Broker greifbar sein.
    Das Objektmodell muß definieren: Objektnamen, Objekte, Anfragen, Werte, unterstützte Typen, Typerweiterungen, Ausnahmen (Exceptions), Schnittstellen und Operationen.

    2. Entscheide, wie die Zusammenarbeit zwischen den Komponenten organisiert ist

    Dies betrifft im wesentlichen die Bekanntmachung von Schnittstellen. Hier gibt es zwei generelle Möglichkeiten: Einen binären Standard oder eine textuelle Interface Definition Laguage (IDL). Beide Standards beschreiben die Schnittstelle eines Dienstes für die Verwendung durch Clients. Welchen Ansatz man wählt hängt nicht zuletzt von der Programmiersprache ab, die man verwenden will. Ein binärer Standard wie beispielsweise OLE (Microsoft Object Linking and Embedding) muß durch die Programmiersprache direkt unterstützt werden.
    Eine IDL ist flexibler und für viele Programmiersprachen verfügbar (siehe CORBA). Manchmal werden beide gemischt verwenden (IBM's SOM).

    3. Spezifiziere die APIs der Broker

    Die Client-Seite muß die entsprechende Funktionalität besitzen, um Anfragen zu erstellen und an den Broker abzuschicken und Ergebnisse abzufragen. Die Schnittstelle des Brokers muß dafür entsprechende Methoden anbieten. Die API des Brokers kann z.B. auch Methoden enthalten, über die ermittelt werden kann, ob ein verteiltes Objekt überhaupt existiert o.ä.. Server benötigen einen Ausschnitt der Broker-API um sich zu registrieren. Da dies statisch (per Voreinstellung) oder dynamisch (zur Laufzeit) erfolgen kann, muß der Broker ggf. für beide Möglichkeiten eine Methode in seiner API bereithalten.
    Der Broker muß System-eindeutige Namen vergeben können. Diese kann er z.B. Server zuteilen, wenn sie sich beim Broker registrieren. Auch das betrifft die API des Brokers. Schlußendlich muß die API auch Netzwerkfunktionalitäten zur Kommunikation zwischen Clients, Servern und Broker abdecken.

    4. Benutze Proxy-Objekte um Implementierungsdetails zu verbergen

    Auf der Clientseite repräsentiert ein Proxy stellvertretend einen entfernten Server. Umgekehrtes gilt auf der Serverseite. Die Aufgaben eines Proxy können hierbei sein:
  • Anpassungen an verschiedene Netzwerksysteme
  • Packen von Daten

  • Proxyobjekte Sind immer Teil des jeweiligen Clients bzw. Serverprozesses, für den sie "arbeiten". Bei CORBA-Entwicklungen werden sie vom IDL-Compiler automatisch erzeugt und sind Teil der resultierenden Software.

    5. Entwerfe die Broker-Komponente

    Dies geschieht parallel zu den Schritten 3 und 4. Folgende Schritte sind im einzelnen nötig:
    1. Zuordnung von Parameter, Objektnamen und Methodennamen zu Inter-Prozess Kommunikation.
    2. Jede Workstation besitzt einen Broker. Zur nahtlosen Kommunikation sind Routing-Algorithmen zu implementieren.
    3. Der Broker muß sich die Adresse des sendenden Client merken um Resultate richtig zustellen zu können (z.B. Port-Nummer; in Anfrage mit codieren)
    4. Evtl. ist Marshalling implementieren, wenn dies nicht schon im Proxy geschehen ist
    5. Einen Puffer für Nachrichten entwerfen, wenn asynchrone Kommunikation erlaubt sein soll
    6. Einen Direktory-Service um Service-Namen reale Server zuordnen zu können. Beim TCP/IP Netzwerkprotokoll kann die Zuordnung über Portnummern erfolgen
    7. Naming-Service, wenn Namen dynamisch zugeteilt werden sollen
    8. Wenn dynamische Methodenaufrufe erlaubt sind, dann muß der Broker Typinformationen zu Methoden von Servern speichern
    9. Entwickle eine geeignete Fehlerbehandlung. Wenn eine Komponente einen Fehler erzeugt, dann muß dieser an Client weitergeleitet werden, damit er darauf reagieren kann. Treten zur Laufzeit Fehler in der Übertragung auf, so ist eine Fehlerbehandlung sehrviel komplizierter. Erst recht, wenn die Komponenten asynchron arbeiten (s.o.). Es ist zu definieren, was der Broker zu tun hat, wenn ein Fehler auftritt. Was ist beispielsweise zu tun, wenn der angesprochene Dienst gar nicht existiert oder wenn der Client den Dienst nicht benutzen darf?

    10. Wenn man eine geeignete Fehlerbehandlung nicht systematisch plant, kann das Testen und Debuggen der entwickelten Client- und/oder Server-Applikationen ein langwieriger Prozeß werden.

    6. Entwickle IDL-Compiler

    Wenn eine eigene IDL preferiert wird, dann müssen dazu Compiler für verschiedene Programmiersprachen entwickelt werden. Ein Compiler übersetzt Schnittstellen-Beschreibung von Diensten in den Code der aktuellen Programmiersprache. So kann ein Client (im Quelltext) Server-Klassen wie lokal definierte Klassen der jeweiligen Programmiersprache ansprechen und verwenden.


    Varianten

    Ein Broker für Direkt-Kommunikation schwächt die Restriktive ab, daß Kommunikation nur über den Broker geschieht. In diesem Fall gibt der Broker die Adresse des Servers bekannt. Der Client verbindet sich dann selbst mit dem Server. Eine weitere Variante ist die sog. „off-board“-Kommunikation. Hierbei kommuniziert der Client direkt mit dem Broker auf der Serverseite.

    Der Zustelldienst-Broker entscheidet anhand der Nachricht, was zu tun ist. Er eignet sich für Systeme, die sich auf Nachrichtenübermittlung spezialisiert haben (z.B. Datex-P) und eine Vollduplex Kommunikation zwischen Proxy und Broker nicht zulassen.

    Händlersysteme. Hier sind die Dienste entscheidender als die Server. Anfragen können vom Broker an mehrere Server mit demselben Dienst geschickt werden.

    Adapter Broker System. Bei diesem System wird nicht-objektorientierten Programmen der Anstrich einer objektorientierten Schnittstelle gegeben indem Implementierungsdetails verborgen und nach außen hin durch ein neues Interface ersetzt werden. Der Broker verfügt über ein zusätzliches Layer, das diese Adapterfunktion implementiert. Mögliche Anwendung: Datenbank-Adapter.

    Ein Rückruf Broker System arbeitet ereignisgesteuert. Es gibt hierbei keine Unterscheidung zwischen Clients und Servern. Stattdessen gibt es Ereignisse und Ereignisbehandlungsroutinen. Server registrieren ihre Ereignisbehandlungsroutinen beim Broker, die durch Ereignisse ausgelöst werden.


    Bekannte Verwendung

    CORBA. Hier wurde das Broker Muster angewendet. Es gibt Corba-Implementierungen für verschiedene Plattformen. CORBA unterstützt auch die Direkt-Kommunikation-Variante (IONA Technologies' Orbix)
    IBM SOM/DSOM kombiniert CORBA IDL mit seinem binärem Protokoll. Es unterstützt Unterklassenbildung (Vererbung) von binären Schnittstellen. Ableitung sind auch in einer anderer Programmiersprache als die der Elternklasse möglich.

    Microsoft OLE 2.x propagiert einen binären Standard.

    Das World Wide Web ist das größte existierende Broker-System.

    ATM-P ist ein Zustelldienst Broker System. Siemens hat in einem Hausprojekt ein Telefonsystem basierend auf ATM entwickelt.


    Konsequenzen

    Vorteile des Broker-Systems:

    Konsequenzen:


    Verwandte Muster

    Frank Buschmann e.a. [BMR96]: Erich Gamma e.a. [Gam95]:

    [ Seminarübersicht] ... [Architekturmuster] ... [Literatur] ... [ > ]