Grundlagen verteilter Systeme - Institut für Informatik

Werbung
Universität Augsburg
Institut für Informatik
Prof. Dr. Bernhard Bauer
Stephan Roser
Viviane Schöbel
Wintersemester 07/08
Übungsblatt 2
20.11.07
Grundlagen verteilter Systeme
Lösungsvorschlag
Aufgabe 1:
Das vorliegende System besteht aus einem Client und einem Server. Es soll eine
Prozedur vom Client mittels RPC auf dem Server ausgeführt werden. Gehen
Sie davon aus, dass die jeweiligen Maschinen unterschiedliche Architekturen
aufweisen (SPARC, Intel) und die Prozedur ein Ergebnis beinhaltet.
a) Erläutern Sie den Aufbau und die Funktionsweise von RPC.
b) Welche Probleme können bei der Parameterübergabe auftreten?
c) Beschreiben Sie eine mögliche Lösung für die Probleme aus b).
d) Sind Prozeduraufrufe mittels RPC transparent? Begründen Sie ihre Antwort.
zu a)
Abbildung 1: Aufbau RPC
Funktionsweise:
1. Die Client-Prozess ruft die Client-Stub-Prozedur wie eine normale Prozedur auf.
2. Der Stub erzeugt eine Nachricht (Marshalling), die neben den Eingabeparametern zusätzlich noch den Name bzw. eine ID der Server-Prozedur
enthält. Anschließend übergibt der Stub die Nachricht an das Betriebssystem (BS).
3. Das Client BS sendet die Nachricht über die Kommunikationsmodule an
das entfernte Betriebssystem.
4. Das Server BS gibt die Nachricht an den Dispatcher weiter.
5. Dieser entpackt den Header der Nachricht und kann durch die mitgelieferte
Identifizierung die jeweilige Stubprozedur aufrufen.
6. Der Stub entpackt die Nachricht (Unmarshalling) und ruft die eigentliche
Prozedur auf.
1
7. Der Server führt die Prozedur aus und gibt das Ergebnis an den Stub
zurück.
8. Der Stub verpackt die Nachricht und gibt sie an das BS weiter.
9. Dadurch wird die Nachricht erneut über die Kommunikationsmodule übertragen und an das Client BS weiter gegeben.
10. Das Client BS reicht die Nachricht an den Stub weiter.
11. Der Stub packt das Ergebnis aus und gibt es zurück.
zu b)
• Call-by-Value: Darstellungsformate können unterschiedlich sein. Beispielsweise verwenden Intel basierte Systeme das LittleEndian Format und
SPARC Maschinen das BigEndian Format. Daher kann es bei der Parameterübergabe zu falschen Werten kommen.
• Call-by-Reference: Referenzen sind Zeiger auf Adressen im lokalen Adressraum und daher auch nur da sinnvoll. Zwar kann man für kleinere Konstrukte die Pointer belassen und die Struktur mit übergeben. Dies ist
allerdings nur sehr begrenzt möglich.
zu c)
Durch Interface Definition Language (IDL) können Schnittstellen in einer maschinenunabhängigen Sprache formuliert und in entsprechende Stubs für Client
und Server kompiliert werden. Anschließend werden Header, Stubs und die eigentlichen Implementierungen verbunden (Linker).
zu d)
Ja, da durch die angesprochene Lösung ein Programm eine entfernet Prozedur
als lokale‘ aufrufen kann und dabei keine Unterschiede bei einem fehlerfreien
’
Ablauf beachten muss. Allerdings muss bei der Fehlerbehandlung auf Transparenz geachtet werden.
Aufgabe 2:
Analog zu Aufgabe 1 liegt Ihnen eine Client/Server Architektur vor.
a) Erläutern Sie den Aufbau und die Funktionsweise von RMI.
b) Kann die Transparenz im Fall eines Fehlers in der Übertragung von Nachrichten mittels RMI gewahrt bleiben? Begründen Sie ihre Antwort und
gehen Sie dabei auf die verschiedenen Aufruf-Semantiken ein.
zu a)
2
Abbildung 2: Aufbau RMI
Funktionsweise:
Analog zu RPC werden die Kommunikationsmodule benutzt um ein Anfrage/Antwort Protokoll zu implementieren.
Wird ein entferntes Objekt bzw. dessen Referenz zum ersten mal verwendet, so
wird ein Eintrag zwischen einem lokale und entfernten Objekt in die Tabelle
des Remote Reference Module eingetragen. Liegt noch kein Proxy oder dessen
Referenz vor, so werden die benötigten Informationen heruntergeladen und der
Proxy erzeugt. Dies geschieht in Java mittels der RMIRegistry automatisch. Mit
dem RMI Compiler rmic können Skeleton-Klassen und damit auch Proxy- und
Dispatcher-Klassen automatisch erzeugt werden.
Liegt jetzt somit für jedes verwendete entfernte Objekt ein Proxy vor, so können
Methoden auf dem eigentlichen Objekt ausgeführt werden. Der Proxy verhält
sich wie ein lokales Objekt. Beim Aufruf einer Methode des Proxy werden die Argumente (können wiederum entfernte Referenzen sein) mit dem Verweis auf das
Zielobjekts und einer methodId verpackt und über die Kommunikationsmodule
übertragen. Der Dispatcher verwendet die methodId, um die passende Methode
im Skeleton auszuwählen und leitet die Request Nachricht entsprechend weiter.
Der Skeleton entpackt die Nachricht und führt den eigentlichen Methodenaufruf
auf dem Objekt aus und nimmt eine eventuelle Antwort entgegen, verpackt und
sendet sie zum Client. Dort wird die Nachricht vom Proxy entgegengenommen,
entpackt und an die Applikation weitergegeben.
zu b)
• maybe Semantik: Nein, da die Nachricht verloren gehen kann und nach
einem Timeout ein Fehler zurückgeliefert wird.
• at-least-once Semantik: Nein. Zwar wird die Nachricht mit dieser Semantik auf jeden Fall übertragen. Allerdings kann sie auch öfters übertragen
werden, wobei dies bei nicht indepotenten Methoden zu Problemen führen
kann.
• at-most-once Semantik: Ja, die Nachricht wird genau einmal übertragen
und gleicht somit der Semantik eines lokalen Aufrufs. Allerdings besteht
weiterhin ein Unterschied im Verhalten bestimmter Situationen (Ausfall
der Verbindung für längere Zeit).
3
Die Transparenz kann nie gänzlich erfüllt werden, da durch Fehlen der Verbindung ein Fehler nicht mehr maskiert werden kann, egal welche Semantik
verwendet wird.
Aufgabe 3:
Erläutern Sie die verteilte Garbage Collection (vGC) anhand des folgenden Systems. Gehen Sie dabei auf die Verweise ein und stellen Sie diese zusätzlich grafisch dar.
Initialzustand:
- Server A: Objekt a, Verweis auf entferntes Objekt b,c,d.
- Server B: Objekt b,c, Verweis auf entferntes Objekt a,d.
- Server C: Objekt d.
a) Welche Operationen haben zu dem Initialzustand des Systems geführt?
Die Reihenfolge können Sie außer acht lassen.
b) Ein Server X ruft eine Methode auf und bekommt eine entfernte Referenz
auf das Objekt c zurückgeliefert. Beim Eintrag in die Liste der Verweise
von c wird ein Fehler an Server X zurück gegeben. Welche Auswirkungen
hat das auf die vGC?
c) Ein Server Y hält bereits eine Referenz des Objektes c und ist auch in der
Liste der Verweise korrekt eingetragen. Y wird das Objekt c nicht weiter
benötigen und benachrichtigt Server C. Dabei wird ein Fehler zurückgeliefert. Welche Auswirkungen hat das auf die vGC?
d) Der Server Z verwendet die entfernten Objekte a,c,d und wurde auch korrekt in die entsprechenden Verweis-Listen eingetragen. Im Weiteren ist
davon auszugehen, dass keine weiteren Verweise auf die Objekte a,c,d bestehen. Z verwendet diese Objekte anschließend auch nicht mehr, benachrichtigt aber nicht die entsprechenden Server. Mit welchem Mittel kann
die vGC trotzdem funktionsfähig bleiben? Welche Auswirkungen hat dies
letztendlich für die lokale GC der Server A,B und C?
zu a)
A: addRef(b); an Server B
addRef(c); an Server B
addRef(d); an Server C
B: addRef(a); an Server A
addRef(d); an Server C
4
Abbildung 3: Initialzustand
zu b)
X: addRef(c); an Server B Exception;
removeRef(c); an Server B
addRef(c); an Server B
Abbildung 4: Zustand nach b)
zu c)
Y: addRef(c) (bereits erfolgt); an Server B
removeRef(c); an Server B ; Exception;
removeRef(c) oder Server B löscht den Verweis nach Ablauf der LeaseDauer.
5
Abbildung 5: Zustand nach c)
zu d)
Für den Fall, dass Objekte nicht mehr benutzt werden, dies den entsprechenden
Servern nicht mitgeteilt, können Referenzen über Leases entfernt werden. Server müssen innerhalb einer bestimmten Zeit ihren Lease erneuern, damit ihre
Referenz nicht entzogen wird.
Falls nach der vGC keine entfernten Referenzen mehr bestehen, kann die lokale
GC auf diesen Objekten ausgeführt werden und falls auch lokal keine Verwendung besteht, können Sie gelöscht werden.
Aufgabe 4:
a) Welche Eigenschaften müssen Objekte haben, damit sie mittels Java RMI
verwendet werden können?
b) Schreiben Sie ein Programm mit Java RMI, welches die folgenden Anforderungen erfüllt:
– News sollen mit einer Methode addNews(String news) an den Server
geschickt werden können.
– Beim Aufruf der Methode auf dem Server soll die neue Nachricht
gespeichert werden.
– Zusätzlich sollen mit getNews() alle News zurückgeliefert werden.
– Verwenden Sie Callbacks, um Clients über neue Nachrichten zu informieren.
zu a)
Objekte können prinzipiell als Werte und als Referenzen übertragen werden.
Objekte werden dabei gegen Interfaces als Typ programmiert. Daher muss für
jedes entfernte Objekt ein entsprechendes Interface erstellt werden, dessen Methoden RemoteExceptions (throws RemoteException) werfen.
6
Wenn Objekte als Wert übertragen werden, müssen sie das Interface Serializable
implementieren und IOExceptions werfen können.
Damit Objekte als Referenzen übergeben werden können, müssen sie von RemoteObject abgeleitet sein. Damit implementieren sie automatisch die Schnittstellen Remote und Serializable. Server Objekte werden entweder von RemoteServer, von Activatable oder von UnicastRemoteObject abgeleitet und müssen
RemoteExceptions werfen können.
zu b)
Alle Klassen müssen kompiliert werden. Anschließend müssen die Stubs für die
Klassen NewsImpl und NewsClient mit dem RMI Compiler rmic erzeugt werden.
Bsp.: rmic NewsClient (ohne Endung)
Liegen Somit alle Klassen vor, muss die RMI-Registry mit rmiregistry erzeugt
werden.
Beim Aufruf der Klassen NewsClient und NewsServer muss zusätzlich eine Policy File mit eingebunden werden.
Bsp.: java -Djava.security.policy=policy NewsServer
Die Zugriffsrechte wurden hierbei nicht eingeschränkt.
/**
* @author Michael Rambold
* Dieses Interface dient als Remote Schnittstelle eines NewsServer.
* Die Methoden sollten durch die Namen klar sein.
*/
import java.rmi.RemoteException;
import java.util.ArrayList;
public
public
public
public
public
}
interface INews extends java.rmi.Remote {
void addNews(String news) throws RemoteException;
ArrayList<String> getNews() throws RemoteException;
void register (ICallback client) throws RemoteException;
void unregister (ICallback client) throws RemoteException;
import java.rmi.RemoteException;
/**
*
* @author Michael Rambold
* Dieses Interface stellt eine Methode notifyForNews bereit,
* die als Callback Schnittstelle für einen Client verwendet wird.
* Ein Server kann die Methode aufrufen und dadurch den Client
* informiert halten.
*/
7
public interface ICallback extends java.rmi.Remote {
public void notifyForNews() throws RemoteException;
}
import java.rmi.RemoteException;
import java.util.*;
public class NewsImpl extends java.rmi.server.UnicastRemoteObject implements INews {
public NewsImpl() throws java.rmi.RemoteException {
super();
}
private ArrayList<String> news = new ArrayList<String>();
private ArrayList<ICallback> registeregClients = new ArrayList<ICallback>();
public void addNews(String n) throws java.rmi.RemoteException
news.add(n);
if(this.registeregClients.size()!=0){
this.notifyClients();
}
}
{
public ArrayList<String> getNews() throws java.rmi.RemoteException
return news;
}
public void register(ICallback client) throws RemoteException {
this.registeregClients.add(client);
System.out.println("Client is registered");
}
public void unregister(ICallback client) throws RemoteException {
this.registeregClients.remove(client);
}
/**
* Jeder registrierte Client wird benachrichtigt.
*/
8
{
private void notifyClients(){
System.out.println("NewsServer: notify Client");
Iterator<ICallback> it = this.registeregClients.iterator();
while(it.hasNext()){
ICallback client = it.next();
try {
client.notifyForNews();
} catch (RemoteException e) {
e.printStackTrace();
}catch (Exception ex){
ex.printStackTrace();
}
}
}
}
import java.rmi.*;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
public class NewsServer {
/**
* @param args
*/
public static void main(String[] args) {
/**
* SecurityManager verhindern das automatische herunterladen
* möglicherweise schadhaften Codes(Stubs).
* In diesem Fall liegen alle Stub Klassen im src Verzeichnis
* und damnach müssen keine weiteren Aktionen hinzugefügt werden.
* Falls man einen WebServer zum Austausch einsetzen möchte, muss
* der nachfolgende Kommentar entfernt werden und die Addresse
* angepasst werden. Dort müssen sich die Stub Klassen befinden.
* Beim Aufruf der Klasse: java -Djava.security.policy=policy NewsServer !!
*/
if(System.getSecurityManager()==null){
System.setSecurityManager(new RMISecurityManager());
//System.getProperties().put("java.rmi.server.codebase","Url als String");
}
9
try{
INews news = new NewsImpl();
Registry registry = LocateRegistry.getRegistry();
registry.rebind("NewsServer", news);
System.out.println("Server NewsServer run!");
}catch(RemoteException ex){
System.out.println("NewsServer RemoteException: " + ex.getMessage());
}catch(Exception e){
System.out.println("NewsServer Exception: " + e.getMessage());
}
}
}
import java.net.MalformedURLException;
import java.rmi.*;
import java.util.ArrayList;
public class NewsClient extends java.rmi.server.UnicastRemoteObject implements ICallback {
private ArrayList<String> _lokalNews = null;
private INews _news =null;
/**
*
* @param NewsServer vom Typ INews ist die Schnittstelle eines NewsServer
* @throws java.rmi.RemoteException
*/
public NewsClient(INews NewsServer)throws java.rmi.RemoteException{
super();
this._news = NewsServer;
}
public void notifyForNews() throws RemoteException {
this.set_lokalNews(this._news.getNews());
}
/**
* Nachrichten werden einem NewsServer über die Referenz übergeben
* @param news zu speichernde Nachrichten
* @param NewsServer vom Typ INews ist die Schnittstelle eines NewsServer
10
*/
private void addNews(String news, INews NewsServer){
try {
NewsServer.addNews(news);
} catch (RemoteException e) {
e.printStackTrace();
}
}
private void set_lokalNews(ArrayList<String> news) {
_lokalNews = news;
}
/**
* @param args
* @throws
*/
public static void main(String[] args) {
INews newsServer = null;
/**
* SecurityManager verhindern das automatische herunterladen
* möglicherweise schadhaften Codes(Stubs).
* In diesem Fall liegen alle Stub Klassen im src Verzeichnis
* und damnach müssen keine weiteren Aktionen hinzugefügt werden.
* Falls man einen WebServer zum Austausch einsetzen möchte, muss
* der nachfolgende Kommentar entfernt werden und die Addresse
* angepasst werden. Dort müssen sich die Stub Klassen befinden.
* Beim Aufruf der Klasse: java -Djava.security.policy=policy NewsClient !!
*/
if(System.getSecurityManager()==null){
System.setSecurityManager(new RMISecurityManager());
//System.getProperties().put("java.rmi.server.codebase","Url als String");
}
try{
newsServer = (INews) Naming.lookup("NewsServer");
NewsClient client = new NewsClient(newsServer);
newsServer.register((ICallback)client);
for(int i=0;i<5;i++){
client.addNews("Nachricht: "+i, newsServer);
}
System.out.println(client._lokalNews.toString());
newsServer.unregister((ICallback)client);
11
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (NotBoundException e) {
e.printStackTrace();
} catch (RemoteException e) {
e.printStackTrace();
}
}
}
Abgabe in elektronischer Form und Dreiergruppen bis zum 30.11.07
an: [email protected].
12
Herunterladen