Patterns in der Softwarearchitektur: Das Broker-Muster
Das Broker Pattern strukturiert verteilte Softwaresysteme, die mit entfernten Dienstaufrufen interagieren.
- Rainer Grimm
Patterns sind eine wichtige Abstraktion in der modernen Softwareentwicklung und Softwarearchitektur. Sie bieten eine klar definierte Terminologie, eine saubere Dokumentation und das Lernen von den Besten. Das Broker-Pattern strukturiert verteilte Softwaresysteme, die mit entfernten Dienstaufrufen interagieren. Es ist fĂĽr die Koordinierung der Kommunikation, ihrer Ergebnisse und Ausnahmen verantwortlich.
Das Broker Pattern aus dem Buch "Pattern-Oriented Software Architecture, Volume 1" hilft dabei, viele Herausforderungen verteilter Systeme zu lösen. Das kann etwa sein, den richtigen Dienstanbieter zu finden, sicher mit ihm zu kommunizieren, die richtige Programmiersprache zu verwenden oder mit Fehlern umzugehen. Ich werde in diesem Artikel nicht ins Detail gehen. Er soll nur einen groben Überblick über das Broker-Pattern geben. Weitere Informationen finden sich in dem Buch "Pattern-Oriented Software Architecture, Volume 1".
Broker
Zweck
- Ein komplexes Softwaresystem sollte als eine Reihe von entkoppelten und interagierenden Teilsystemen entworfen werden.
- Der verwendete Dienst sollte fĂĽr den Client transparent sein.
- Dies hat die folgenden Konsequenzen:
- Alle Teilsysteme mĂĽssen ĂĽber ein Interprozess-Kommunikationsprotokoll (IPC) miteinander kommunizieren.
- Ein Teilsystem muss seinen passenden Dienst finden.
- Die Dienste mĂĽssen verwaltet werden.
Lösung
- Man fĂĽhrt einen Broker ein, der den Dienstanbieter und den Dienstnutzer zusammenbringt.
- Der Dienstanbieter meldet sich bei dem Broker an.
- Der Client stellt eine Anfrage an den Broker, der ihn dann mit dem Dienstanbieter verbindet.
- Der Broker stellt die Infrastruktur fĂĽr die Kommunikation, das Auffinden und die Konfiguration der Subsysteme ĂĽber eine einfache API bereit.
Struktur
Der Broker besteht aus fĂĽnf Komponenten:
Client
- Implementiert die Anwendungsfunktionalität und
- sendet Anfragen an den Server ĂĽber den
clientseitig Proxy.
clientseitig Proxy
- Kapselt systemspezifische Funktionen,
- spricht die Sprache des Clients und
- vermittelt zwischen dem Client und dem Broker.
Server
- Implementiert Dienste und
- meldet sich beim Broker an.
serverseitig Proxy
- Ruft Server-Dienste auf,
- spricht die Sprache des Servers
- kapselt systemspezifische Funktionen und
- vermittelt zwischen dem Server und dem Broker.
Broker
- Registriert Server und meldet sie ab,
- überträgt Nachrichten und Fehler und
- findet Server.
Es gibt noch weitere interessante Aspekte der Broker-Architektur.
Interface Definition Language
Normalerweise werden die Dienste, die der Server anbietet, in einer Interface Definition Language (IDL) festgelegt. Sie ist die Basis fĂĽr den clientseitgen Proxy und den serverseitigen Proxy. Hier sind die beiden typischen Schritte:
- Verwenden der Programmiersprachen-unabhängigen IDL, um den Stub und das Skeleton für eine bestimmte Programmiersprache zu erstellen. Dies ist oft für verschiedene Programmiersprachen möglich.
- Implementieren des clientseitigen Stellvertreters und den serverseitigen Stellvertreter auf der Grundlage des Stubs und des Skeletts.
Die IDL kann auch innerhalb des Brokers registriert werden, damit der Broker den passenden serverseitigen Stellvertreter finden kann, wenn er vom clientseitigen gefragt wird.
Der Vorteil der Broker-Architektur ist, dass Clients und Server miteinander kommunizieren können, obwohl sie zum Beispiel unterschiedliche Programmiersprachen sprechen.
Bisher habe ich die statische Struktur des Broker-Musters beschrieben. Nun werde ich das Zusammenspiel zwischen dem Client und dem Server betrachten.
Der Client hat eine Anfrage
Wenn ein Client einen Service nutzen möchte, fragt er bei dem Broker danach. Letzterer liefert den clientseitigen Stellvertreter zurück, der die Schnittstelle des Services implementiert. Der clientseitige Stellvertreter verwaltet die Zwischenspeicherung von Daten, die Kommunikation zwischen den Prozessen oder die Vorbereitung der Daten (Marshalling/Serialisierung). Er stellt eine Verbindung zum serverseitigen Stellvertreter her, der den Server aufruft. Der serverseitige Stellvertreter hat eine ähnliche Aufgabe wie der clientseitige Stellvertreter: Er bereitet die Daten auf und spricht die Sprache des Servers. Wenn der Server das Ergebnis des Funktionsaufrufs zurücksendet, ruft er seinen serverseitigen Stellvertreter auf, der mit dem clientseitigen kommuniziert.
Der Server meldet sich an
Während der Initialisierung des Systems startet der Broker sich selbst und tritt in seine Ereignisschleife ein. Der Server initialisiert und registriert sich beim Broker. Der Server erhält die Registrierungsbestätigung vom Broker und tritt in seine Ereignisschleife ein.
Zusätzliche Broker
Manchmal gibt es mehr als einen Broker. Ein Broker kann daher die Dienstanforderung an einen anderen Broker delegieren. In dieser fortschrittlichen Architektur muss jeder Broker zwei Protokolle unterstĂĽtzen. Ein internes Protokoll fĂĽr seinen clientseitigen Stellvertreter und serverseitigen Stellvertreter und ein externes Protokoll fĂĽr den anderen Broker.
Es gibt viele Beispiele fĂĽr Broker-Architekturen.
Beispiele
Das Programm rpcgen
erzeugt aus einer Schnittstellenbeschreibung Stubs, Skeletons und eine XDR-Datei zur Datenkonvertierung. rpcgen
bietet eine API fĂĽr Remote-Funktionsaufrufe in C an.
Remote Method Invocation (RMI):
Der rmic
-Compiler generiert die Stubs und Skeletons aus einer Serverschnittstelle in Java. Im Gegensatz zu den Funktionsreferenzen in SunRPC sind dies Objektreferenzen. Seit Java 5 werden die Stubs und Skeletons implizit von der Java Virtual Machine erzeugt.
Common Object Request Broker Architecture (CORBA):
CORBA verwendet die IDL für die Schnittstellenbeschreibung. Die Syntax der IDL ist C++-orientiert. CORBA verwendet ähnlich wie RMI Objekte. Standardisierte Implementierungen des IDL2Language
Compilers gibt es fĂĽr Ada, C, C++, Lisp, Smalltalk, Java, COBOL, PL/I und Python.
- C++ Implementierung: Die ADAPTIVE Kommunikationsumgebung (ACE)
Simple Object Access Protocol (SOAP):
Als Schnittstellenbeschreibungssprache wird Web Service Definition Language (WSDL) verwendet. WSDL ist ein textbasiertes Protokoll (XML). Dies Protokoll ist nicht nur deklarativ, sondern spezifiziert auch die Art der DatenĂĽbertragung und eines Services.
Einen wsdl2Compiler Codegenerator gibt es in Java, C++, Python, Perl, ...
- C++ Implementierung: gSOAP
Vor- und Nachteile
Vorteile
- Standortunabhängigkeit von Client und Server durch den Intermediär.
- Der Client ist unabhängig von Implementierungsänderungen des Servers.
- Änderungen der IDL können leicht implementiert werden, sodass nur geringe Anpassungen auf dem Client und Server notwendig sind.
- Es ist einfach, den Broker auf ein anderes System zu portieren, da der Client und der Server keine systemspezifischen Funktionen verwenden.
- Clients oder Server, die andere Programmiersprachen sprechen, sind recht einfach hinzuzufĂĽgen, wenn eine IDL fĂĽr den Compiler der Programmiersprache verfĂĽgbar ist.
- Neue Dienste können einfach hinzugefügt werden, da sie die bestehende Broker-Architektur nutzen können.
- SOAP ist ein textbasiertes Protokoll; das macht es ziemlich einfach, die Kommunikation mit UNIX-basierten Kommandozeilen-Tools zu analysieren oder ein einfaches Programm zu implementieren, das Text sendet.
Nachteile
- Aufgrund der vielen Indirektion (Client -> clientseitiger Stellvertreter -> Broker -> serverseitiger Stellvertreter -> Server), der Datenbereitstellung und der Kommunikation zwischen den Prozessen ist die Performanz oft nicht ausreichend; nachdem die erste Kommunikation zwischen dem Stellvertreter auf der Client-Seite und dem Stellvertreter auf der Server-Seite erfolgt ist, sprechen beide Komponenten oft direkt miteinander, ohne den zwischengeschalteten Broker.
- Die Kommunikation der Parteien hängt von vielen Komponenten ab und ist daher im Fehlerfall schwer zu debuggen; im Gegensatz zu SOAP sind die anderen Protokolle binär
Wie geht's weiter?
Das Model-View-Controller (MVC) ist eines der klassischen Architekturmuster. Es unterteilt die Programmlogik einer Benutzeroberfläche in die einzelnen Komponenten Model, View und Controller. Das Model verwaltet die Daten und Regeln der Anwendung. Die View stellt die Daten dar, und der Controller interagiert mit dem Benutzer. Ich werde MVC in meinem nächsten Artikel vorstellen. (rme)