Interoperabilität zwischen Windows und Linux ist bei den häufig anzutreffenden Infrastrukturen mit Windows-Clients und Linux-Servern sehr wichtig. Mit dem Mono-Projekt ist mittlerweile eine interessante Möglichkeit zur Ausführung von .NET-Applikationen auf heterogenen Plattformen entstanden. Mit der Version 1.0 entsteht im Augenblick das erste produktreife Release des OpenSource-Projektes. Bevor man aber ein Linux-Mono-System ernsthaft als Alternative zu einem Windows-Server in Betracht zieht, sind Performanz- und Interoperabilitätsbetrachtungen unerlässlich. Um festzustellen ob Mono bei verteilten Applikationen ein vollwertiger Ersatz für das kommerzielle .NET Framework ist, haben wir Mono unter Linux sowohl clientseitig als auch serverseitig getestet. Weiterhin haben wir die Interoperabilität von Mono mit dem kommerziellen .NET Framework von Microsoft getestet.
Die .NET-Remoting-Technologie
Die .NET-Remoting-Technologie (im Folgenden kurz Remoting) dient dazu, die Kommunikation zwischen verteilten Anwendungen zu realisieren. Dabei spielt es keine Rolle, ob sich um eine räumliche oder eine logische Verteilung handelt. Um Verteilung mit Remoting realisieren zu können, benötigt man Remotable Objects. Diese können im Gegensatz zu Nonremotable Objects auch außerhalb ihres Adressraums wahrgenommen werden. Möchte man auf Remotable Objects zugreifen und diese dabei explizit im Adressraum des Servers belassen, so verwendet man das Marshal-By-Reference (MBR)-Verfahren. Hierbei wird auf der Clientseite ein Proxy erzeugt. Dieser steht mit dem entsprechenden Remotable Object auf der Serverseite in Verbindung. Jeder Aufruf am Proxy-Objekt führt zu einer entsprechenden Weiterleitung der Aktion an das Server-Objekt. Die Freigabe von Objekten zur Garbage Collection durch das Zählen von Referenzen auf Objekte ist bei einer Verteilung über Rechnergrenzen hinweg ineffektiv. Daher erfolgt die Freigabe der Serverobjekte beim Remoting automatisch nach einer dynamisch änderbaren Zeitspanne (lease time).Möchte man ein Objekt nicht im Adressraum des Servers nutzen, sondern im Adressraum des Clients, so verwendet man das Marshal-By-Value (MBV)-Verfahren. Dabei wird auf der Serverseite eine vollständige Kopie des Objektes erstellt und an den Client übermittelt. Um dies zu ermöglichen, muss das entsprechende Objekt vollständig serialisierbar sein. Zu jedem Remotable-Objekt muss der Zeitpunkt der Aktivierung definiert werden. Sollen Objekte schon bei der ersten Referenzierung instanziiert werden, benutzt man die Client-activated Objects (CAOs). Dabei wird für jeden Proxy, der auf der Clientseite erstellt wird, ein korrespondierendes Objekt auf der Serverseite erzeugt. Die zweite Möglichkeit ist, Objekte beim ersten Zugriff, z.B. dem Aufruf einer Methode, zu erzeugen. Diese Art von Objekt heißt Server-activated Object (SAO). Bei diesem Typ kann man weiterhin zwischen Singleton-Objekten und SingleCall-Objekten unterscheiden. Singleton-Objekte existieren genau einmal auf dem Server, jeder Aufruf wird an der gleichen Instanz ausgeführt. Wählt man hingegen SingleCall als Aktivierungsart, so wird für jeden Aufruf ein neues Objekt erzeugt und danach wieder zur Garbage Collection freigegeben.
Die Kommunikation zwischen Client und Server erfolgt über Kanäle (channels). Die Remoting-Klassenbibliotheken stellen TCP- und HTTP-Kanäle zur Verfügung. In der Standardkonfiguration wird der TCP-Kanal mit dem Binary Formatter, der HTTP-Kanal mit dem SOAP-Formatter genutzt. Diese Formatter regeln die Kodierung der zu übertragenden Daten auf dem ausgewählten Kanal. Die Implementierung der beschriebenen Techniken werden dem Entwickler durch die jeweilige Common Language Runtime und Klassenbibliotheken transparent zur Verfügung gestellt. Dazu gehört das Erstellen von Proxy-Objekten, die Verwaltung von Remotable Objects und das Management von Kanälen.
Das Testsystem
Unsere Testumgebung bestand aus zwei Rechnern (800MHz, 128 MB RAM), jeweils mit Windows XP und Debian 3.0 ausgestattet. Auf dem Windows-System wurde das Microsoft .NET Framework 1.1, auf dem Debiansystem das Mono 1.0 Beta 3 Package installiert. Nach Rücksprache mit Mono-Entwicklern sind keine relevanten Unterschiede zwischen der Remoting-Implementierung der Mono 1.0 Beta 3 und der 1.0 Release-Version zu erwarten.
Wie man in Abpictureung 1 erkennt, nutzen sowohl Client als auch Server jeweils eine CLR-Implementierung, welche die Abwicklung der Testprogramme realisiert. Die Serveranwendung registriert die für den Testlauf zu verwendenden Kanäle und die angebotenen Objekttypen bei der CLR. In unserem Fall handelt es sich um ein serialisierbares sowie ein nichtserialisierbares Objekt. Beide besitzen eine Methode mit einem Parameter vom Typ object. An diese Methode werden im Testverlauf vom Client unterschiedlich große Objekte übergeben. Um vergleichbare Messungen zu den verschiedenen Aufrufarten zu erhalten, wird nun das Serverobjekt einmal als Client-activated Object, einmal als Singleton- und einmal als SingleCall-Objekt registriert.
Durch Verwendung des .NET Frameworks 1.1 (im Gegensatz zur Version 1.0) ergibt sich eine wichtige Änderung bei der Registrierung der Objekttypen auf dem Server. Es muss bei der Kanalregistierung auf der Serverseite bekannt geben werden, welche Objekte automatisch deserialisiert werden dürfen. Man kann dies auf bestimmte Objekttypen beschränken oder generell alle Objekte zur Deserialisierung freigeben. Da Mono diese Eigenschaft (TypeFilterLevel) in der getesteten Version nicht korrekt implementiert, ist an dieser Stelle die Verwendung identischer Assemblies unter Mono und .NET nicht möglich. Es war erforderlich, gezielt für jede der Plattformen eine eigene Serverapplikation zu entwickeln.
Die von uns entwickelte Clientanwendung besteht aus mehren Akteuren (Abb. 1). Eine Komponente realisiert das Einlesen der Testparameter, eine weitere das Speichern der Mess-Ergebnisse in einer XML-Datei. Darüber hinaus enthält die Clientanwendung eine Timerkomponente (Intel-Prozessor-Register-basierend), mit der genaue Messungen der Aufrufzeiten möglich sind. Die Einzelmessungen werden nacheinander durchgeführt und die Aufrufzeiten gemessen. Die CLR übernimmt dabei die Verwaltung von Proxies, das Erstellen von MBV-Objekten und die Kommunikation mit der Serveranwendung. Nach jeder Messung wird sowohl client- als auch serverseitig eine Garbage Collection erzwungen. Darauf erfolgt eine ausreichend lange Pause, um einen Einfluss der laufenden Garbage Collection auf die Messungen zu vermeiden. Die Mess-Ergebnisse werden nach jeder Einzelmessung in der bereits angesprochenen XML-Datei gesichert.
Die Messungen
Unsere Messungen erfolgten in Abhängigkeit von verschiedenen Parametern. Diese waren Kanalart (TCP, HTTP), Objektaktivierungsart (Singleton, SingleCall, CAO) sowie Übergabeart (MBV, MBR) und Datenmenge. Um einen umfassenden Überblick zu erhalten, wurden Messungen für sämtliche Kombinationen von Messparametern durchgeführt. Die den folgenden Betrachtungen zugrunde liegende Datenbasis entstand durch 200fache Wiederholung der Messungen. Um eine Korrelation zwischen der gesendeten Datenmenge und dem Zeitaufwand zu ermitteln, führten wir die Messungen mit ansteigender Datenmenge durch. Erwartungsgemäß lies sich ein linearer Zusammenhang erkennen. Vergleicht man die Performanz der unterschiedlichen Übertragungsarten, so erkennt man, dass die Datenübertragung über den TCP-Kanal schneller erfolgt als über den HTTP-Kanal. Die nahe liegende Erklärung dafür ist der geringere Overhead, der durch den Binary Formatter erzeugt wird. Man sollte sich deshalb nur für einen HTTP-Kanal (mit SOAP-Formatter) entscheiden, wenn die Netzwerkstruktur dies erzwingt (z.B. durch Firewalls).Als weiteres Ergebnis stellte sich heraus, dass die Ausführungszeiten der Remotingmethoden bei den MBR-Aufrufen erheblich größer sind als bei den MBV-Aufrufen. Beim Zugriff auf Marshal-By-Value-Objekte werden diese vom Server auf den Client transportiert und dann dort bearbeitet. Demzufolge werden Aufrufe nur im Adressraum des Clients ausgeführt, d.h., sie müssen keine logischen oder physikalischen Grenzen überwinden. Ruft man hingegen Marshal-By-Reference-Objekte auf, werden beim Client nur Referenzen auf die Objekte angelegt. Die Aufrufzeit für eine Methode ist dann hauptsächlich von der Größe der an die Methode übergebenen Parameter abhängig. Betrachtet man die Singleton-Messungen, kann man sehr gut erkennen, dass der erste Aufruf erheblich länger dauert als alle folgenden. Dies lässt sich dadurch begründen, dass das Objekt zunächst beim ersten Aufruf erzeugt wird und bei den folgenden Aufrufen, wie zuvor erklärt, bereits existiert. Vergleicht man einzelne Singleton-Messungen mit einzelnen SingleCall-Messungen, lässt sich die Zeit zur Objekterstellung dementsprechend ableiten.
Nach unseren Experimenten besteht grundsätzlich die Möglichkeit der Interoperabilität zwischen Mono und .NET. Jedoch ist erkennbar, dass die Kommunikation von .NET nach Mono über den HTTP-Kanal unter Verwendung des SOAP-Formatters zum Zeitpunkt unserer Messung scheiterte. Die Kommunikation in entgegengesetzter Richtung sowie innerhalb der Frameworks funktionierte hingegen problemlos. Neben der Tatsache, dass nicht alle Kommunikationsvarianten erfolgreich kombinierbar waren, ergaben sich auch massive Zeitunterschiede zwischen den einzelnen Messreihen. Die Matrix in Abpictureung 2 vergleicht die Mittelwerte der Mess-Ergebnisse zwischen den Systemen, bei jeweils identischen Parametern, mit den zugehörigen .NET-zu-.NET-Resultaten. In allen betrachteten Fällen wurden die besten Resultate bei der Kommunikation vom kommerziellen Framework mit sich selbst gemessen. Erwähnenswert ist auch, dass die Kommunikation mit einem Linux-Mono-Server über den TCP-Kanal überraschend langsam abläuft.
Lohnt sich Remoting mit Mono?
Aus den Messergebnissen ist ableitbar, dass der Einsatz eines Linux/Mono-Systems als Applikationserver für .NET-Clients eine derzeit nur eingeschränkt nutzbare Variante ist. Hingegen ist der Einsatz von Linux-Mono-Systemen als Client an einer Microsoft .NET-Serverapplikation eine durchaus erwägenswerte Alternative zur alleinigen Nutzung des .NET Frameworks. Auch der Einsatz einer reinen Mono-Infrastruktur sowohl client- als auch serverseitig ist ein gangbarer Weg. Generell ist besonders hervorzuheben, das der Einsatz eine Linux-Mono- oder .NET-Monokultur der jeweils gemischten Infrastruktur vorzuziehen ist. In diesem Zusammenhang ist auch ein sinnvoller Parallelbetrieb der Frameworks auf Klientenseite denkbar und möglich. Da Mono sich in einer erstaunlich hohen Geschwindigkeit weiterentwickelt, ist damit zu rechnen, dass die hier festgestellten Defizite des Frameworks durch die Entwickler von Mono zügig beseitigt werden. Eine Verbesserung der Performanz bzw. ein Debugging des HTTP-Formatters sind zu erwarten. Insgesamt ist festzustellen, das Mono in vielen Fällen schon als Alternative zum .NET Framework eingesetzt werden kann und diese Position sicherlich in der nächsten Zeit weiter ausbauen wird. Wenn es auch in einigen Fällen noch zu früh für den Einsatz von Mono zu sein scheint, so lohnt es sich sicherlich, Mono in regelmäßigen Abständen auf den Zahn zu fühlen und die Einsatzmöglichkeiten des Frameworks zu überdenken.Tobias Queck, Robert Schuppenies und Sebastian Steinhauer sind Studenten der Softwaresystemtechnik am Hasso-Plattner-Insitut für Softwaresystemtechnik der Universität Potsdam. Dieser Artikel entstand infolge einer wissenschaftlichen Arbeit am Lehrstuhl Betriebssysteme und Middleware.
Links und Literatur
- [1] www.go-mono.org/
- [2] Ingo Rammer: Advanced .NET-Remoting, Apres, 2002
- [3] msdn.microsoft.com/library/default.asp?
url=/library/en-us/cpguide/html/cpconnetremotingoverview.asp - [4] Fundamental Modeling Concepts (FMC) Notation Reference: fmc.hpi.uni-potsdam.de/


