Dokument_38.pdf (5583 KB) - OPUS - Hochschule Konstanz
Dokument_38.pdf (5583 KB) - OPUS - Hochschule Konstanz
Dokument_38.pdf (5583 KB) - OPUS - Hochschule Konstanz
Sie wollen auch ein ePaper? Erhöhen Sie die Reichweite Ihrer Titel.
YUMPU macht aus Druck-PDFs automatisch weboptimierte ePaper, die Google liebt.
Verteilte Systeme mit der <strong>Konstanz</strong>er Komponentensprache CompJava<br />
Hans Albrecht Schmid und Marco Pfeifer<br />
Prof. Dr.<br />
Hans Albrecht Schmid<br />
war nach seinem<br />
Studium an der Universität<br />
Stuttgart, am Institut National<br />
Polytechnique de Grenoble und nach<br />
seiner Promotion mit einem Doktorandenstipendium<br />
der Studienstiftung des<br />
deutschen Volkes als Assistent an der<br />
Universität Karlsruhe, als Gastprofessor<br />
an der University of Toronto und als Forschungsgruppenleiter<br />
an der Universität<br />
Stuttgart tätig. Darauf war er zehn Jahre<br />
im IBM Entwicklungslabor Böblingen<br />
in verschiedenen leitenden technischen<br />
und Management-Positionen tätig,<br />
bevor er als Professor an die HTWG<br />
<strong>Konstanz</strong> kam. Seine Forschungsschwerpunkte<br />
sind fortgeschrittene Softwaretechnologien<br />
in technischen und<br />
kommerziellen Anwendungsgebieten. Er<br />
hat eine größere Anzahl von Forschungsprojekten,<br />
darunter ein DFG-Projekt,<br />
durchgeführt und eine beträchtliche<br />
Anzahl international anerkannter<br />
Veröffentlichungen auf diesen Gebieten<br />
publiziert.<br />
Dipl.-Inf. (FH)<br />
Marco Pfeifer<br />
Software-Engineering-<br />
Studium an der HTWG<br />
<strong>Konstanz</strong>. Seit Oktober 2005 Projektmitarbeiter<br />
der <strong>Hochschule</strong> <strong>Konstanz</strong>.<br />
Mit der Komponentensprache CompJava<br />
lassen sich verteilte Systeme von Komponenten<br />
wesentlich einfacher erstellen als<br />
das bei kommerzieller Middleware der Fall<br />
ist. Außerdem ist die Komposition von lokalen<br />
Komponenten sehr viel effi zienter als<br />
bei kommerzieller Middleware, so dass große,<br />
skalierbare Systeme durch Komposition<br />
von Komponenten erstellt werden können.<br />
Ausgangspunkt<br />
Die Keimzelle von verteilten Systemen bildeten<br />
Anfang der 70er-Jahre Programme,<br />
die auf zwei über eine Telekommunikationsleitung<br />
miteinander verbundenen<br />
Computern abliefen und mittels eines<br />
Protokolls kommunizierten. Die Erstellung<br />
und Wartung solcher Systeme war<br />
extrem zeitaufwändig, weil sich der Entwickler<br />
– und damit ist selbstverständlich<br />
auch die Entwicklerin gemeint – dabei<br />
mit vielen, eigentlich einfachen, aber doch<br />
sehr fehleranfälligen Details beschäftigen<br />
musste (selbst wenn er sich auf ein schon<br />
vorhandenes Protokoll wie LSV2 aus dem<br />
Fertigungsbereich oder TCP aus dem Internet<br />
abstützen konnte). Das führte zu sehr<br />
großen Softwareentwicklungskosten im<br />
Vergleich zu den Kosten der Entwicklung<br />
lokaler Systeme.<br />
Ein weiteres Problem war dabei, dass hinter<br />
einer derartigen Art von Rechnerkommunikation<br />
eine ganz andere Denkweise steckt<br />
als bei der lokalen Programmierung. Bei<br />
dieser ruft man Prozeduren, auch Funktionen<br />
genannt, auf oder Dienste und Methoden,<br />
die von Komponenten bzw. Objekten<br />
zur Verfügung gestellt werden. Deshalb<br />
wurden Anfang der 80er-Jahre entfernte<br />
Prozeduraufrufe in Form des RPC (Remote<br />
Procedure Call) eingeführt. Damit konnte<br />
die Zusammenarbeit von zwei „entfernten“<br />
Programmen (d.h. Modulen auf entfernten<br />
Rechnern) in ähnlicher Weise wie die von<br />
zwei lokalen Modulen durchgeführt werden<br />
und all die einfachen, aber fehleranfäl-<br />
ligen Details der Kommunikationsabwicklung<br />
der RPC-Systemsoftware überlassen<br />
werden.<br />
Verteilte Objekte<br />
Die Objektorientierung gewann seit Anfang<br />
der 90er-Jahre eine immer größere Bedeutung,<br />
ähnlich wie die Arbeit mit verteilten<br />
Dateisystemen, Drucksystemen oder,<br />
allgemeiner, Client-Server-Systemen. Somit<br />
kam die Idee von „verteilten Objekten“ auf,<br />
dass man nämlich Objekte auf verschiedene<br />
Rechner eines Rechnernetzes verteilen<br />
kann und die Methoden eines entfernten<br />
Objektes auf ähnliche oder möglichst gleiche<br />
Art und Weise wie die eines lokalen Objekts<br />
aufrufen kann. Die Zielsetzung [Black<br />
et al. 1987] war dabei folgende:<br />
1. Die Programmierung mit „verteilten<br />
Objekten“, also Erstellung, Deklaration,<br />
Kreation und Aufruf von Methoden, sollte<br />
möglichst auf gleiche Art und Weise wie<br />
bei einem lokalen Objekt durchgeführt<br />
werden.<br />
2. Man sollte die Zuordnung („Allokation“)<br />
von verteilten Objekten auf die Knoten<br />
eines Rechnernetzwerks ändern können,<br />
ohne dass eine Umprogrammierung<br />
erforderlich wird. In anderen Worten, die<br />
Software für die verteilten Objekte sollte<br />
unabhängig von der späteren Allokation<br />
der Objekte entwickelt werden, was man<br />
Allokations-Unabhängigkeit nennt.<br />
3. Der lokale Aufruf der Methode eines<br />
verteilten Objektes, das auf dem gleichen<br />
Rechnerknoten allokiert ist, sollte die gleiche<br />
Effi zienz haben wie der lokale Aufruf<br />
der Methode eines nicht-verteilten Objektes.<br />
Middleware<br />
Obwohl es in der Forschung erfolgreiche<br />
Ansätze gab, verteilte Objekte direkt mit<br />
einer Programmiersprache zur Verfügung<br />
zu stellen [Black et al. 1987], setzten sich<br />
in der Praxis Middleware-Systeme wie z.B.<br />
CORBA, Java RMI, DCOM und DotNet zur<br />
Verteilung von Objekten und später von<br />
Komponenten durch. Leider gelang es diesen<br />
nun schon klassischen Middlewaresystemen<br />
nur teilweise, die oben angeführten<br />
Ziele zu erreichen.<br />
Zum Beispiel ist bei Java RMI die Programmierung<br />
von verteilten Objekten im Prinzip<br />
gleich wie die von lokalen Objekten.<br />
Aber im Detail gibt es doch Unterschiede,<br />
so dass die Programmierung von verteilten<br />
Objekten um einiges komplexer ist und einige<br />
Einarbeitung erforderlich macht. Auch<br />
kann man den Quellcode für ein lokales<br />
Objekt oder einen lokalen Methodenaufruf<br />
nicht einfach übernehmen und evtl. an<br />
ein oder zwei Stellen abändern, um daraus<br />
ein verteiltes Objekt oder einen entfernten<br />
Methodenaufruf zu machen, sondern man<br />
muss mehr oder weniger mechanisch im<br />
ganzen Quellcode kleine Details ändern.<br />
Bei den anderen Middlewaresystemen wie<br />
z.B. CORBA, DCOM und DotNet sind die Unterschiede<br />
noch viel größer und es ist noch<br />
viel mehr Einarbeitung erforderlich. Somit<br />
ist Ziel 1 nur teilweise erfüllt.<br />
Die Middlewaresysteme stellen für entfernte<br />
Objekte oder Komponenten entfernte<br />
Schnittstellen zum Methodenaufruf<br />
zur Verfügung, die sich von den lokalen<br />
Schnittstellen unterscheiden, wie Abbildung<br />
1 zeigt. Man kann über eine entfernte<br />
Schnittstelle auch einen „kollozierten“<br />
Aufruf durchführen, wenn Aufrufer und<br />
aufgerufenes Objekt auf dem gleichen<br />
Rechnerknoten allokiert sind, so dass Ziel 2<br />
erfüllt ist.<br />
Aber leider sind die Kosten eines kollozierten<br />
Aufrufs über eine entfernte Schnittstelle<br />
fast so groß wie die bei einem entfernten<br />
Aufruf und somit wesentlich schlechter als<br />
die beim lokalen Aufruf über eine lokale<br />
Schnittstelle, wie Tabelle 1 zeigt. Ein kollozierter<br />
Aufruf über eine entfernte Schnittstelle<br />
verursacht also große Zusatzkosten,<br />
auf „neudeutsch“ Overhead genannt, so<br />
dass Ziel 3 nicht erfüllt ist.<br />
HTWG Forum<br />
Technik Informatik<br />
50 51<br />
Aufrufkosten in ns<br />
<br />
<br />
<br />
<br />
1.000.000<br />
100.000<br />
10.000<br />
1.000<br />
100<br />
10<br />
1<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
lokaler Aufruf kollozierter<br />
Aufruf<br />
<br />
Abb. 1: Klassische Realisierung von verteilten<br />
Objekten/Komponenten mit Middleware<br />
entfernter<br />
Aufruf<br />
Tabelle 1: Kosten für lokalen, kollozierten und<br />
entfernten Aufruf der Methode int increment(int i)<br />
auf einem 3 GHz Pentium IV mit Windows XP<br />
Dieser Overhead ist in vielen Fällen nicht<br />
tragbar, weil er die Effi zienz des Gesamtsystems,<br />
d.h. die Antwortzeit oder den<br />
maximalen Durchsatz, zu stark verschlechtert.<br />
Deshalb gab es bei der zweiten Version<br />
des Enterprise JavaBeans Standard<br />
(EJB 2.0) großen Druck der Anwender, eine<br />
Lösung für dieses „collocated invocation<br />
overhead“-Problem zu fi nden [SUN 2001<br />
b]. Daraufhin wurden sehr spät, in der letzten<br />
vorgeschlagenen Fassung der zweiten<br />
Version des Standards (proposed fi nal<br />
draft 2 of the EJB 2.0 specifi cations as of<br />
4/24/2001) [SUN 2001 a] lokale Schnittstellen<br />
zusätzlich zu den entfernten Schnittstellen<br />
für EJB-Komponenten eingeführt.<br />
Mit den lokalen Schnittstellen erfüllen EJB-<br />
Komponenten die Ziele 1 und 3, aber nicht<br />
mehr das Ziel 2 (vergleiche [Schmid 2002]).<br />
Verteilung von Komponenten mit<br />
CompJava<br />
Unser Ziel für die Verteilung von Komponenten<br />
mit CompJava [Schmid, Pfeifer,<br />
Schneider 2005] war, alle drei oben genannten<br />
Ziele zu erreichen. Ein verteiltes<br />
System von Komponenten wird durch die<br />
Komposition einer Komponente aus möglicherweise<br />
entfernt allokierten Subkomponenten<br />
erstellt, die wiederum aus Subkomponenten<br />
bestehen können, usw.<br />
Bei der Erstellung eines verteilten Systems<br />
von Komponenten mit CompJava ändert<br />
sich nichts gegenüber der im letzten Jahr<br />
skizzierten Vorgehensweise bei der Erstellung<br />
eines lokalen Systems [Schmid,<br />
Maucher, Pfeifer, Schneider, Ederleh, Hager<br />
2005], außer dass zwei neue Schlüsselworte<br />
hinzukommen.<br />
Ein verteilter Komponententyp, genauer<br />
gesagt, ein verteilbarer Komponententyp,<br />
wird durch das Schlüsselwort „remotable“<br />
gekennzeichnet. Auf Komponenten eines<br />
verteilbaren Komponententyps kann man<br />
von entfernten Rechnerknoten aus zugreifen.<br />
Die Defi nition eines verteilbaren Komponententyps<br />
erfolgt genau gleich wie die<br />
eines lokalen Komponententyps, nur dass<br />
für die Port-Schnittstellen eine zusätzliche<br />
Restriktion gilt, damit überhaupt ein<br />
entfernter Zugriff auf die Schnittstellen<br />
möglich ist: die Java Interfaces dürfen keine<br />
Operationen mit Parametern und Resultaten<br />
mit (lokaler) Referenzsemantik<br />
defi nieren, sondern mit Kopiersemantik;<br />
das heißt, referenzierte Objekte müssen<br />
serialisierbar sein. Abbildung 2 zeigt den<br />
verteilten Komponententyp KundenTyp.<br />
remotable component type KundenTyp {<br />
port verwaltung provides Kundendaten;<br />
}<br />
Abb. 2: Verteilbarer Komponententyp KundenTyp<br />
Eine verteilte Komponente wird durch das<br />
Schlüsselwort „distributed“ gekennzeichnet.<br />
Die Subkomponenten einer verteilten<br />
Komponente, welche einen verteilbaren