Im Zeitalter immer komplexerer Computersysteme und immer tieferer Vernetzung spielt auch immer stärker die Möglichkeit, Anwendungen verteilt auf mehreren Systemen zu betreiben und untereinander zu nutzen, eine große Rolle. Remote Procedure Calls (RPC) sind hierbei auf allen gängigen Betriebssystemen Quasi-Standards.
Verteilte Anwendungen
Traditionell begann die Computertechnik mit einer sehr klaren Architektur: Programme wurden fest für eine bestimmte Computerarchitektur geschrieben und liefen in der Regel auch nur auf den betreffenden Systemen. Jegliche Änderungswünsche hinsichtlich des Programms erforderten mehr oder weniger umfangreiche Umprogrammierungen. Charakteristisch für diese Architektur war auch, dass praktisch alle Gerätschaften homogen zur eingesetzten Plattform sein mussten, also in der Regel vom gleichen Hersteller oder von Lizenznehmern eingekauft werden mussten. Dies alles resultierte darin, dass Hard- und Software mangels Konkurrenz bzw. Plattformzugänglichkeit äußerst kostspielig waren.
Die Idee der verteilten Anwendungen wurzelt in der Idee, Anwendungen in einzelne Komponenten zu gliedern, die untereinander über definierte Schnittstellen kommunizieren können. Mit dieser Aufgliederung werden Anwendungen nicht unbedingt einfacher zu programmieren (oftmals ist genau das Gegenteil der Fall), allerdings können sie flexibler aufgebaut werden und auch die Möglichkeit bieten, andere Komponenten anzugliedern. Dies ist oftmals größeren EDV-Strukturen erwünscht sind, um Erweiterungen in bestehende Strukturen möglichst einfach - und damit auch kostengünstiger gegenüber einer kompletten Neuinvestition - integrieren zu können. Das Schlüsselwort hierfür ist die so genannte Middleware.
Exkurs: Was ist Middleware?
Von so genannter Middleware wird gesprochen, wenn eine Anwendung verteilt aufgebaut ist und aus mehreren Schichten besteht. Dies kann zum Beispiel bei Anwendungen notwendig sein, die hochverfügbar sein sollen. Oder auch bei Anwendungen, die in der Verarbeitung andere Softwarekomponenten integrieren sollen. Ein Beispiel einer verteilten Anwendung könnte folgendermaßen aufgebaut sein:
- Der Benutzer bedient die Anwendung über ein so genanntes Front End. Dieses Front End übernimmt die eingegebenen Daten des Benutzers und zeigt die von der Anwendung gelieferten Ergebnisse. Das Front End selbst ist über eine einheitliche Adresse erreichbar, so dass der Benutzer eine fixe Zieladresse hat.
- Das Front End selbst kommuniziert mit einer auf Middleware basierenden Plattform mit seiner Anwendung, die das Back End darstellt. Diese Anwendung kann, um zum Beispiel Hochverfügbarkeit zu gewährleisten, auf mehreren Systemen verteilt laufen. Für den Benutzer ist dies im Idealfall transparent, da er niemals direkt mit dem Back End kommuniziert, sondern dies nur über das Front End passiert.
Diese Abstraktion einer Anwendung in verschiedene Schichten kann, je nach Anwendung, beliebig tief gestaltet werden, wobei immer bedacht werden muss, dass der Aufwand bei Programmierung und Betrieb immer größer wird, je verteilter eine Anwendung ist.
Heutzutage sind verteilte Anwendungen in der modernen Datenverarbeitung gang und gäbe. Beispielsweise ersparen moderne Betriebssysteme Programmierern viel Arbeit hinsichtlich der Programmierung von Benutzerführungen oder Funktionen, die den so genannten Kernel, den Kern des Systems, betreffen. Noch eine Stufe weiter gehen Anwendungen, die unter systemunabhängigen Programmiersprachen wie beispielsweise Java geschrieben wurden. Einfacher Java-Programmcode läuft praktisch auf allen Plattformen, für das ein Java-Interpreter verfügbar ist.
Der Gedanke an verteilten Anwendungen geht jedoch noch weiter und wird nicht zuletzt durch die Vernetzungsmöglichkeiten des Internet weiter beflügelt. Verteilte Anwendungen können hier nicht nur aus verschiedenen Komponenten bestehen, sie können auch räumlich völlig woanders stationiert sein, von verschiedensten Anbietern gepflegt werden und der Hauptapplikation scheinbar nebensächliche Dienstleistungen hinzufügen. Hier spricht man von so genannten Web Services.
Exkurs: Was sind Web Services?
Web Services sind Dienste, die Diensteanbieter kostenlos oder kostenpflichtig zur Verfügung stellen und die zur Nutzung in eigenständigen Diensten genutzt werden können. Ein häufig angewendetes Beispiel sind Web Services von Suchmaschinenbetreibern, die von Entwicklern über definierte Programmierschnittstellen, den so genannten API (Application Programming Interface), in eigene Web-Anwendungen integriert werden können. Auf diese Weise können durch Web Services fremde Dienste mitunter sehr einfach und oftmals sogar kostenlos nahtlos integriert werden.
Hersteller von Werkzeugen zur Softwareerstellung haben schon frühzeitig auf die fortlaufende Entwicklung reagiert und verschiedene Lösungen entwickelt, die es Programmierern von Hause aus ermöglicht, verteilte Anwendungen zu entwickeln. Diese so genannten Frameworks sind zwar in der Regel recht komplex zu programmieren, erleichtern aber gerade die Nutzung von verteilten Anwendungen und, im Bezug auf Web-Anwendungen, die Integration von Web Services.
Remote Procedure Calls (RPC)
Das Konzept von RPC wurde ursprünglich vom US-Unternehmen Sun Microsystems für das so genannte Network File System (NFS) entwickelt. Dieses Dateisystem sollte, wie der Name schon besagt, Speicher über ein Netzwerk zur Verfügung stellen können, und dabei so zuverlässig wie ein stationäres Dateisystem sein. Zu diesem Zweck wurde mit RPC eine Sammlung von Befehlen entwickelt, die nach dem Schema eines Client-Server-Modells (siehe hierzu auch Host-Architekturen) diese Speichervorgänge erledigen konnten.
Grundsätzlich funktioniert die RPC-Kommunikation anhand einer einfachen Architektur:
- Die Client-Anwendung sendet eine RPC-Nachricht zunächst an den Server. Hierzu ist auf dem Server ein Dienst (der so genannte Portmapper oder Endpointmapper) installiert, der die RPC-Anfragen zentral empfängt, die in der RPC-Nachricht hinterlegten Informationen über die gewünschte Anwendung ausliest und an die entsprechende Server-Anwendung leitet.
- Die Server-Anwendung erhält die RPC-Nachricht vom RPC-Dienst, verarbeitet entsprechend die Information und sendet seine Antwort an den Client zurück.
Äußerst wichtig ist bei einer solchen Kommunikation über ein Netzwerk die so genannte Fehlersemantik, also die Reaktion auf Kommunikationsfehler. Dies muss der Programmierer einer Anwendung unbedingt berücksichtigen, um beispielsweise bei einer fehlenden Server-Antwort auf eine RPC-Nachricht diesen "hängenden" Zustand abzufangen. Gleichzeitig muss unbedingt vermieden werden, dass wiederholt gesendete RPC-Nachrichten beim Server auch als solche erkennbar sind, damit dieser Vorgänge nicht doppelt ausführt. Es gibt deshalb in RPC verschiedene Möglichkeiten, solche Zustände und wiederholende Nachrichten zu definieren, die zur Gewährleistung der Datenintegrität von Programmierern auch zwingend genutzt werden.
Unterschieden wird bei der RPC-Verarbeitung zwischen synchronem RPC und asynchronem RPC. Bei synchronem RPC muss die Verarbeitung genau Schritt für Schritt erfolgen. Das bedeutet, dass der Client eine RPC-Nachricht an den Server sendet und zwingend auf die Antwort warten muss, bevor er weiter fortsetzen kann. Bei Anwendungen, die mit asynchronem RPC kommunizieren, kann der Client nach dem Senden einer RPC-Nachricht weitere Operationen vornehmen, da auch eine späterer Empfang der Server-Antwort einkalkuliert ist. Diese Funktionsweise hat durchaus seine zentrale Bedeutung, denn Anwendungen, die mit synchronem RPC kommunizieren, ist es sehr wichtig, dass die Anwendung eine höhere Laufzeit der Server-Antwort berücksichtigt, da sonst unter Umständen bei höheren Wartezeiten die Anwendung schlicht stehen bleibt und für den Benutzer unangenehme Wartezeiten und der Eindruck eines "hängenden Programms" entsteht (was an sich dann auch tatsächlich der Fall ist). Andererseits erfordern Anwendungen mit asynchronem RPC in der Regel einen höheren Programmieraufwand.
Ärgerlicherweise gibt es mehrere RPC-Implementierungen, so dass nicht von "einem" RPC-Standard gesprochen werden kann:
- Implementierungen nach Sun RPC
Die ursprüngliche Implementierung wurde von Sun Microsystems entwickelt und liegt inzwischen in zwei eigenständigen Modellen vor, die beide von Sun RPC abgeleitet sind. Beide Modelle nutzen standardmäßig den TCP- und UDP-Port 111.- Transport Independent Remote Procedure Call
(TI RPC)
TI RPC wird hauptsächlich mit dem Unix-Betriebssystem Solaris genutzt und ist eine deutliche Weiterentwicklung, die nicht nur mit TCP und UDP funktioniert, sondern auch mit anderen Transportprotokollen. - Open Network Computing Remote Procedure Call
(ONC RPC)
Die ONC-RPC-Implementierung ist eine, wie der Name schon sagt, offene Implementierung, die sich beispielsweise im offenen Betriebssystem Linux findet.
- Transport Independent Remote Procedure Call
(TI RPC)
- Distributed Computing Environment Remote
Procedure Call (DCE RPC)
Diese RPC-Implementierung basiert auf eine frühe RPC-Version, die später von der Open Software Foundation (OSF) als Basis für diese Implementierung genutzt wird. Auf DCE RPC basiert auch die RPC-Implementierung von Microsoft, die sich MSRPC nennt. Im Gegensatz zu den obigen RPC-Implementierungen nutzen DCE-RPC-Implementierungen den TCP- bzw. UDP-Port 135 zur IP-Kommunikation. - ISO Remote Procedure Call (ISO RPC)
ISO RPC stellt einen Versuch dar, einen einheitlichen RPC-Standard zu etablieren. Mangels Implementierungen und auch wegen einigen fehlenden Features ist ISO RPC jedoch kaum verbreitet und spielt derzeit keine signifikante Rolle.
RPC via XML
Als universelles Datenaustauschformat ist auch XML, die Extensible Markup Language (siehe hierzu auch XML - Extensible Markup Language), prädestiniert für die Übertragung von Funktionsaufrufen. Eine solche einheitliche Übertragung ist zum Beispiel in Web-Anwendungen sinnvoll, die über so genannte Webservices mit anderen Systemen kommunizieren können. So können beispielsweise fremde Anwendungen über Programmschnittstellen, so genannten API (Application Programming Interface) verhältnismäßig einfach in andere Web-Anwendungen integriert werden. Die Abbildung dieser Anfragen in XML-Abfragen erleichtert die Programmierung und Kommunikation solcher Anwendungen gewaltig. Einleuchtend dabei ist auch, dass RPC und XML eine nahezu perfekte Ehe eingehen könnten, um Remote-Befehle und deren Ergebnisse via XML zu übertragen.
Ein erster Schritt in diese Richtung wurde 1998 mit dem Protokoll XML-RPC gelegt, das maßgeblich von Dave Winer in Zusammenarbeit mit Microsoft entwickelt wurde. XML besaß einen kleinen, kompakten Aufbau und diente dazu, Funktionsaufrufe per XML an einen Diensteanbieter zu senden. Dieser verarbeitete die Anfrage und schickt diese an die anfragende Applikation zurück. Im Gegensatz zum klassischen RPC verarbeitet diese Anfrage auf der Server-Seite nicht mehr ein Portmapper-Dämon erforderlich, sondern ein entsprechender XML-Prozessor.
Ein Beispiel einer XML-RPC-Anfrage könnte in etwa so aussehen. An einen Diensteanbieter wird eine XML-RPC-formatierte Anfrage geschickt:
<?xml version="1.0"?>
<methodCall>
<methodName>beispiel.statusabfrage</methodName>
<params>
<param>
<value><i4>40</i4></value>
</param>
</params>
</methodCall>
In dieser Anfrage wird in einem Container namens methodCall eine Funktion namens "beispiel.statusabfrage" aufgerufen (definiert im Container methodName), die als Parameter die Zahl 40 überträgt. Das zurückgesendete Ergebnis vom Server könnte folgendermaßen aussehen:
<?xml version="1.0"?>
<methodResponse>
<params>
<param>
<value><string>Testantwort</string></value>
</param>
</params>
</methodResponse>
In diesem Fall wäre die Antwort also der Text "Testantwort".
Obwohl das zugegebenermaßen ein sehr einfacher Dialog ist, wird doch sehr schön deutlich, dass XML-RPC grundsätzlich einen recht einfachen und strukturierten Aufbau hat und vor allem keinerlei Programmcode oder ähnliches übertragen wird; ganz nach der Tradition von RPC werden lediglich Funktionen auf entfernten Systemen aufgerufen, Parameter übertragen und die Antworten entsprechend empfangen.
SOAP
Als Weiterentwicklung von XML-RPC gilt das Protokoll SOAP, dessen Abkürzung ursprünglich für Simple Object Access Protocol steht, in der Zwischenzeit aus rechtlichen Gründen (in den USA können Abkürzungen nicht als Marke eingetragen werden) nicht mehr als Abkürzung gilt, sondern als eigenständiges Kunstwort.
An der Entwicklung von SOAP waren ebenfalls die Protagonisten der XML-RPC-Entwicklung, Dave Winer und das Unternehmen Microsoft beteiligt, die SOAP im Jahre 1999 in ersten Versionen veröffentlichten. An der Entwicklung von SOAP beteiligten sich jedoch nach und nach immer mehr Unternehmen, so dass SOAP sich nach und nach immer stärker etablierte und die Spezifikation der Version 1.1 später beim World Wide Web Consortium (W3C) eingereicht wurde. Daraus bildete sich eine offizielle Arbeitsgruppe, die im Jahr 2003 die SOAP-Version 1.2 veröffentlichte, die als offizielle Empfehlung gilt.
Im Gegensatz zu XML-RPC ist SOAP universeller bei der Auswahl des Übertragungsprotokolls. Neben XML über HTTP kann SOAP Nachrichten beispielsweise auch per FTP oder SMTP übertragen. Zudem bietet SOAP durch seinen flexiblen Aufbau Möglichkeiten, umfangreiche Abfragen innerhalb einer Transaktion zu kombinieren, um den Übertragungs- und Verarbeitungsaufwand zu verringern. In Kauf genommen wird dies jedoch alles durch einen teilweise erheblich komplexeren Aufbau von SOAP-Nachrichten als bei XML-RPC.
Dennoch ist SOAP inzwischen auf dem besten Wege, in der Programmierwelt zu einer der wichtigsten Datenaustauschprotokolle zu werden - nicht zuletzt durch die Entwicklungen im Bereich Web 2.0 (siehe hierzu auch Web 2.0 - Die nächste Web-Generation).