Wykład 7: RPC, RMI, CORBA

Transkrypt

Wykład 7: RPC, RMI, CORBA
Narzędzia do tworzenia
programów rozproszonych
•
•
•
•
Wprowadzenie: idee i pojęcia
Remote Procedure Call
Java Remote Method Invocation
Common Object Request Broker
Architecture
1
Aspekty programowania
rozproszonego
• Współdziałanie (interoperability) modułów
programowych na różnych maszynach.
• Wielokrotne wykorzystanie (reusability)
modułów programowych.
• Standaryzacja de facto (przemysłowa) lub de
iure (niezależna).
2
Struktura oprogramowania
rozproszonego
klient
serwer
kod programisty
namiastka
namiastka
implementacja
programisty
implementacja
programisty
szkielet serwera
mechanizm zdalnych wywołań
mechanizm zdalnych wywołań
systemowa biblioteka
funkcji komunikacyjnych
systemowa biblioteka
funkcji komunikacyjnych
kod
programisty
kod
generowany
automatycznie
funkcje
komunikacji
biblioteki
narzędzia
3
Struktura oprogramowania
rozproszonego
• Aplikacje działające w środowisku rozproszonym
mogą byd napisane w różnych językach
programowania.
• Interfejs do operacji zdalnych jest wtedy
definiowany w specyficznym języku narzędzia
programowania rozproszonego.
• Interfejs służy do wygenerowania zestawu procedur
w konkretnym języku programowania.
4
Model klient - serwer
• Częśd wspomnianych procedur będzie
wykonywana przez serwer tj. program
świadczący usługę wykonania operacji.
• Częśd wspomnianych procedur będzie
wykonywana przez klienta tj. program na
komputerze zdalnym:
– są to tzw. namiastki (stubs) operacji
wykonywanych przez serwer.
5
Namiastki
• Procedury stub mają prawie dokładnie taką samą
liczbę i typy parametrów jak w deklaracji interfejsu,
ale służą wyłącznie do przekazania argumentów
wywołania do serwera, a następnie odebranie
wyników zdalnej procedury tam wykonanej.
• Kod odpowiedzialny za organizację i konwersję
przekazywanych danych (marshalling code) jest
generowany automatycznie.
6
Serwer
• Procedury wygenerowane automatycznie dla
serwera to także marshalling code
• w trakcie obsługi zlecenia następuje wywołanie
implementacji tj. procedury, która faktycznie wykona
operacje zdefiniowane w interfejsie.
• Stworzenie implementacji jest zadaniem
programisty.
• Szkielet serwera jest tworzony automatycznie.
7
Ograniczenia rodzaju parametrów
• Przesyłanie danych wymaga każdorazowo
podania ich rozmiaru (tablice).
• Przesyłanie wskaźników i referencji nie ma
sensu, bo przestrzenie adresowe serwera i
klienta są różne.
• Przesyłanie deskryptorów plików, uchwytów
okien nie ma sensu, bo obiekty te mają
charakter lokalny.
8
Opakowywanie procedur
• Wrapping – przystosowywanie istniejących procedur
do pracy w środowisku rozproszonym.
właściwa
implementacja
właściwa
implementacja
procedura
opakowująca
procedura
opakowująca
szkielet serwera
9
Komunikacja:
repozytorium serwerów
• Klient musi odnaleźd odpowiedni serwer.
• Zapewnia to specjalny proces serwerowy zarządzający
katalogiem (repository) serwerów działających
w danym systemie.
• Udostępnia on klientom identyfikatory operacji
wykonywanych przez poszczególne zarejestrowane
serwery.
• Inne niezbędne usługi (services):
– zawiadujące przesyłaniem komunikatów, prawami dostępu
do obiektów, bezpieczeostwem, transakcjami.
10
Serwisy
klient A
klient B
Strzałki wskazują kierunek
przepływu danych
serwis
komunikatów
katalog
serwerów
serwer 1
- serwis obowiązkowy
- wykonanie operacji na serwerze
serwer 2
serwer 3
- serwis fakultatywny
- zlecenie usługi rozgłaszania komunikatów
- komunikacja z serwisem (jednorazowa)
• Serwery rejestrują się w katalogu serwerów; klienci pobierają identyfikatory serwerów.
• Serwery i klienci zgłaszają akces do wspólnego kanału komunikatów.
11
Przykład: zadanie obliczeniowe
• Rozwiązanie układu równao:
A·x = b
• Algorytm iteracyjny – konieczna dominacja
diagonali macierzy A, tzn. i i j|aij|<|aii|:
xn+1 = xn – D(Axn – b)
gdzie: {x1,x2,...} – kolejne przybliżenia
rozwiązania x; dij=0 dla i j oraz dii=1/aii.
12
Rozproszona implementacja
• Wektor x dzielony na N podwektorów (tyle, ile jest
jednostek obliczeniowych).
• Każda jednostka przechowuje lokalnie własne
przybliżenie rozwiązania i modyfikuje lokalny
podwektor.
• Uzyskane wyniki są przekazywane do jednostki
nadrzędnej, która modyfikuje aktualne przybliżenie
rozwiązania globalnego.
13
Remote Procedure Call
• Mechanizm RPC został opracowany przez firmę
Sun; obecnie znormalizowany przez ISO/IEC.
• Nie jest przystosowany do programowania
obiektowego.
• Powszechnie stosowany w systemach Unix.
• Wspólny sposób reprezentacji podstawowych
typów danych – eXternal Data Representation.
14
External Data Representation
• XDR – ma za zadanie zniwelowad różnice
w reprezentacji typów danych w różnych
maszynach.
• RPC zawiera funkcje służące do kodowania
i dekodowania typów prostych, łaocuchów
znaków, tablic, unii i wskaźników języka C
w standardzie XDR.
• Dane są zapisywane/odczytywane z potoku XDR
tj. strumienia bajtów.
15
Potok XDR
• Dane są zapisywane w kwantach 4-bajtowych.
• Dane w potoku znajdują się w kolejności wywołao
funkcji je kodujących.
• Nie ma możliwości testowania typów danych
w potoku – kolejnośd dekodowania musi odpowiadad
kolejności kodowania.
• Funkcje kodujące/dekodujące – filtry XDR.
16
Filtry XDR
• Operacje kodowania i dekodowania są wykonywane
przez te same funkcje.
• Pierwszym argumentem filtru XDR jest zawsze
wskaźnik na strukturę reprezentującą potok XDR.
• Liczba i typy pozostałych argumentów zależą od typu
kodowanych danych.
17
Źródła danych potoków XDR
• Deskryptor pliku:
– kodowanie – zapis do wskazanego pliku,
– dekodowanie – odczyt z pliku,
– tworzenie potoku – funkcja xdrstdio_create.
• Obszar pamięci operacyjnej:
– kodowanie – zapis do pamięci od wskazanego adresu,
– dekodowanie – odczyt z pamięci,
– tworzenie potoku – funkcja xdrmem_create.
• Dowolne źródło danych – poprzez dostarczone
z zewnątrz funkcje zapisu i odczytu:
– kodowanie – wywołanie funkcji zapisującej dane,
– dekodowanie – wywołanie funkcji dostarczającej dane,
– tworzenie potoku – funkcja xdrrec_create.
18
Tryb działania potoku
• Obowiązkowym parametrem funkcji tworzenia
potoku jest tryb, w jakim będzie pracował
potok XDR:
– XDR_ENCODE – do kodowania danych,
– XDR_DECODE – do dekodowania danych,
– XDR_FREE – do zwalniania pamięci przydzielonej
podczas dekodowania.
19
Nagłówki filtrów XDR
• Nagłówki filtrów dla typów prostych języka C:
bool_t xdr_type(XDR *pStream, type *pObject);
gdzie type jest jednym z typów: char, int, long, float, double,
void lub enum.
• Argument pObject wskazuje na kodowaną bądź dekodowaną
zmienną.
• Podobnie wyglądają nagłówki filtrów dla łaocuchów znaków,
tablic, unii i wskaźników (mogą one mied większą liczbę
argumentów, w zależności od danego typu).
20
Kodowanie struktur
• Dla wszystkich pól struktury, w kolejności definiowania
wywoływane są odpowiednie filtry.
• Brak uniwersalnego filtru dla struktur.
• Definicji struktur dokonuje się w języku RPC.
• rpcgen – program automatycznie generujący
odpowiednie filtry dla struktur:
– tworzy plik nagłówkowy z definicjami struktur w języku C,
– oraz plik z kodem źródłowym stosownych filtrów.
21
Kodowanie argumentów
• Przy korzystaniu z RPC przekazywane argumenty
należy umieścid w strukturze.
• Opis struktury w języku RPC
MyIterationArguments.x :
22
Uwagi:
• Linia 3 – tablica float o nieokreślonej liczbie elementów – przybliżenie
rozwiązania x*.
• Linia 4 – indeks początkowy obliczanego podwektora.
• Linia 5 – indeks koocowy obliczanego podwektora.
Wykonanie polecenia:
$ rpcgen MyIterationArguments.x
• Powoduje utworzenie plików w języku C:
– MyIterationArguments.h – definicja struktury,
– MyIterationArguments_ xdr.c – kod źródłowy filtru XDR.
23
MyIterationArguments.h
(fragment)
24
Plik 'MyIterationArguments_ xdr.c'
• Zawiera kod filtru dla struktury
MyIterationArguments:
– sekwencja wywołao xdr_array (przetwarzanie tablicy
float),
– dwukrotne wywołanie xdr_int (przetwarzanie
indeksów),
– jeśli przetwarzanie zakooczy się pomyślnie to zwracane
jest 1 (TRUE), w przeciwnym razie 0 (FALSE).
25
example1encoder.c
• Program kodujący argumenty i zapisujący je do pliku:
26
Uruchomienie:
• Po skompilowaniu i uruchomieniu programu powstaje
plik binarny "example1.arg":
$ gcc -o encoder example1encoder.c
MyIterationArguments_xdr.c
• Zawartośd pliku w postaci 16-wej:
$ od -x example1.arg
rozmiar tablicy
0000000 0000 0500 803f 0000 0040 0000 4040 0000
0000020 8040 0000 a040 0000 0000 0000 0000 0400
0000040
indeks początkowy
indeks końcowy
27
example1decoder.c
• Program dekodujący dane i
wykonujący obliczenia:
28
Uruchomienie:
• Po skompilowaniu i uruchomieniu programu
następuje wypisanie kolejnego przybliżenia:
$ gcc -o decoder example1decoder.c My*.c
$./decoder
1.000000 2.000000 3.000000 4.000000 5.000000
-0.666667 1.255556 -0.343704 1.402740 0.654657
29
Automatyczne kodowanie wskazao
• W razie zdefiniowania w XDR struktury
zawierającej wskaźniki na inne struktury podczas
kodowania sprawdzane jest, czy dany wskaźnik
jest równy NULL, a jeśli nie, to wywoływany jest
odpowiedni filtr, kodujący wskazywaną strukturę.
• W przypadku struktur cyklicznych ze względu na
rekurencyjne wywoływanie kolejnych filtrów
występuje przepełnienie stosu.
30
Dekodowanie struktur z wskaźnikami
• Podczas dekodowania struktury, jeśli wskaźnik nie
był NULL, to przydzielana jest pamięd dla
wskazywanej struktury
i wywoływany jest filtr ją dekodujący.
• Tę niejawnie przydzieloną pamięd należy zwalniad
wywołując funkcję:
void xdr_free(xdrproc_t proc, char *objp)
– proc – filtr, który dekodował dane,
– objp – wskaźnik na dekodowaną strukturę.
31
Wymiana danych w RPC
• Wszystkie filtry są skojarzone (via
xdrrec_create) z funkcjami transmisji danych
via gniazdka IP.
• Mechanizm jest ukryty przed programistą w
funkcjach bibliotecznych.
• Rozproszona natura aplikacji narzuca
ograniczenia na języki definicji RPC.
32
Identyfikatory procedur w RPC
• Identyfikowanie procedury przez nazwę jest
niewystarczające.
• Potrzebny jest np.
– Numer programu, wykonującego zdalną procedurę:
• wg firmy Sun numery 0x20 000 000 – 0x3F FFF FFF są zalecane do
wykorzystania.
– Numer wersji w obrębie programu.
– Numer procedury w ramach wersji:
• Numer 0 jest zastrzeżony (rpcgen dodaje taką procedurę standardowo
do testowania działania serwera).
33
Ograniczenia RPC
• Zdalna procedura przyjmuje tylko jeden argument
(może on byd strukturą).
• Wszelkie zmiany dokonane przez procedurę w
obrębie jej argumentu pozostają lokalne
i nie są przekazywane z powrotem do klienta.
• Do klienta jest przekazywany jest wynik procedury
jako dowolny typ XDR – np. także struktura.
34
Schemat tworzenia aplikacji rozproszonej
interfejs.x
kod źródłowy
programisty
kod generowany
automatycznie
interfejs.h
interfejs_clnt.c
interfejs_xdr.c
interfejs_svc.c
klient.c
serwer.c
skompilowany
moduł
skonsolidowany
program
generacja (rpcgen)
kompilacja (cc -c)
klient
serwer
konsolidacja (cc)
35
Generowanie szkieletu aplikacji
• W pliku *.x należy umieścid definicje struktur (tylko
tych niezbędnych do komunikacji klienta
z serwerem) i deklaracji zdalnych procedur, jakie ma
wykonywad serwer.
• Program rpcgen tworzy jeden plik nagłówkowy
i trzy pliki ze źródłami w C:
– *_clnt.c – z namiastkami zadeklarowanych procedur,
– *_xdr.c – z filtrami XDR,
– *_svc.c – ze szkieletem serwera.
• Namiastki mają zawsze dwa argumenty:
– wskaźnik na strukturę wysyłaną do serwera,
– jednoznaczny identyfikator serwera.
36
Identyfikowanie serwerów
• Katalog serwerów – obowiązkowy serwis
odwzorowujący parę {identyfikator_programu,
identyfikator_wersji} w konkretny numer portu
(gniazdka IP).
• Program, uruchamiany przy starcie systemu
i nasłuchujący na porcie 111, przechowuje katalog
serwerów i odpowiadających im portów:
– Linux: portmap, Solaris: rpcbind.
37
Serwisy RPC
• Lista zarejestrowanych serwerów:
$ /usr/bin/rpcinfo –p
• W oparciu o RPC opracowano wiele usług
sieciowych np. NFS – Network File System.
38
Inne schematy komunikacji
• Rozgłaszanie (broadcast) komunikatów bez
możliwości otrzymania odpowiedzi:
– funkcja rpc_broadcast.
• Wywołanie zdalnej procedury bez czekania na
odpowiedź:
– ustawienie czasu oczekiwania na 0 funkcją clnt_control.
• Wywołanie zwrotne (callback):
– klient wywołuje zdalną procedurę i nie czekając na
wynik sam staje się na pewien czas serwerem;
– serwer wywołuje zdalną procedurę udostępnioną przez
klienta.
39
Przykład
• Rozproszona realizacja rozwiązania układu równao
A·x = b.
• Częśd obliczeniową będzie realizowad wiele
procesów serwerów RPC.
• Zarządzad przydziałem zadao będzie
wielowątkowy program nadrzędny:
– każdy wątek będzie klientem RPC,
– synchronizacja obliczeo poprzez synchronizację
wątków.
40
inicjacja
Schemat
zarządca
pobranie
argumentów
obliczenia
zapisywanie
wyników
klienci 1 ... N
...
serwer 1
serwer 2
synchronizacja
41
Schemat iteracji
• Wątek główny uruchamia N wątków – klientów
RPC.
• Klienci pracują w pętli nieskooczonej:
– pobranie aktualnego rozwiązania x* (globalnego –
zastosowanie zamka),
– wykonanie procedury RPC, znajdującej fragment
nowego rozwiązania,
– uaktualnienie fragmentu globalnego rozwiązania
(zamek),
– bariera (wersja synchroniczna) – czekanie, aż pozostałe
wątki dotrą do bariery
42
Plik 'MyIterationProg.x'
• Deklaracja interfejsu w języku RPC:
43
Generacja szkieletu
• Program rpcgen tworzy pliki:
MyIterationProg.h, MyIterationProg_clnt.c,
MyIterationProg_svc.c, MyIterationProg_xdr.c.
• W pierwszym z nich (MyIterationProg.h) pojawiły się wiersze:
• Ostatni deklaruje procedurę my_iteration_proc_1_svc, którą należy
zaimplementowad po stronie serwera (ciało funkcji main serwera już
powstało).
• Po stronie klienta ciało procedury my_iteration_proc_1 już powstało,
należy napisad funkcję main klienta.
44
Implementacja serwera
45
Uruchomienie serwera:
• Po skompilowaniu uruchomiony serwer rejestruje
się w katalogu serwerów i oczekuje na zgłoszenia
klientów:
$ /usr/bin/rpcinfo -p
program vers proto port
536871032 1
udp 32769
536871032 1
tcp
32770
– Numer programu wyrażony dziesiętnie jest identyczny z
numerem nadanym w pliku definicji interfejsu RPC.
Można wywoład procedurę testową:
$ /usr/bin/rpcinfo -t localhost 536871032 1
program 536871032 version 1 ready and waiting
46
Implementacja klienta
• Kod źródłowy podzielony na dwie części:
– funkcja main, definicje struktur pomocniczych i
deklaracje globalne,
– kod wątku klienta: wywołania RPC
i synchronizacja wątków POSIX z użyciem
zamków (chroniących sekcje krytyczne)
i barier.
- kod odpowiedzialny
za sekcję krytyczną
- kod odpowiedzialny
za barierę
- pozostały kod
związany z wątkami
47
example2client.c (cz. I)
48
example2client.c (cz. II)
49
example2client.c (cz. III)
50
example2client.c (cz. IV)
51
Uruchomienie klienta:
• Po skompilowaniu klient należy uruchomid podając
jako parametry nazwy dwóch komputerów, na
których pracują serwery:
$ ./example2client komputer1 komputer2
Thread 8194: -0.666667 1.255556 3.000000 4.000000 5.000000
Thread 16387: 1.000000 2.000000 -0.355556 1.412222 0.647704
Thread 8194: 0.665877 -0.087411 -0.355556 1.412222 0.647704
Thread 16387: -0.666667 1.255556 0.416988 0.104114 0.156218
– Program działa w nieskooczonośd, aż do jego przerwania przez
operatora (Ctrl-C).
– W wersji asynchronicznej mogą się kolejno pojawid dwa wiersze
wygenerowane przez ten sam wątek.
52
Plik 'example2server.c'
53
Plik 'example2client.c'
54
Plik 'MyIterationProg.x'
55
RPC - uzupełnienie
• Możliwe jest uruchamianie serwera przez demon
inetd:
– działanie serwera regulują opcje użycia rpcgen.
• Standardowy klient RPC (utworzony przez funkcję
clnt_create) nie jest uwierzytelniany przez serwer.
• Uwierzytelnianie w RPC (zależne od implementacji):
– prosta autoryzacja (login, itp.),
– szyfrowanie DES (rpc-secure),
– autoryzacja Kerberos.
56
Java Remote Method Invocation
• Mechanizm RMI jest częścią języka Java
opracowanego przez firmę Sun (Java Development
Kit).
• Umożliwia wywoływanie metod obiektów
istniejących w maszynie wirtualnej Javy przez
obiekty znajdujące się w innej maszynie wirtualnej
– komunikacja via protokół TCP.
• Obiekty zdalne jak i lokalne są identyfikowane
standardowo, przez referencje.
57
Java RMI
58
Java RMI
59
Interfejsy i klasy RMI
60
Ograniczenia RMI
• Problemy rozproszonego bezpieczeostwa danych,
synchronizacji, odśmiecania pamięci.
• Możliwe jest tylko wykonywanie metod zdalnego
obiektu, a nie dostęp do jego pól (zmiennych).
• Metody RMI muszą byd zadeklarowane
w interfejsie rozszerzającym interfejs (extends)
java.rmi.Remote:
– wygenerowane zostaną odpowiednie procedury
(marshalling code).
61
Serwer
• Serwer musi implementowad interfejs deklarujący metody
udostępniane zdalnym klientom:
– musi on rozszerzad (dziedziczyd) klasę java.rmi.Remote,
– wszystkie zadeklarowane metody muszą jawnie obsługiwad wyjątki
klasy RemoteException,
– serwer musi rozszerzad klasę
java.rmi.Server.UnicastRemoteObject.
– konstruktor serwera musi również jawnie obsługiwad wyjątki klasy
RemoteException.
• Aby umożliwid klientom odnalezienie serwera musi on się
zarejestrowad w serwisie RMI-Registry:
java.rmi.Naming.rebind("rmi://host/Name", ServerObject)
– stosuje się rebind, ponieważ bind() zostało użyte automatycznie przez
konstruktor klasy macierzystej UnicastRemoteObject.
62
Klient
• Uzyskuje referencję do zdalnego obiektu (serwera) poprzez
użycie znanej mu nazwy usługi serwisu Naming:
java.rmi.Naming.lookup(name)
– zwraca referencję do lokalnego obiektu-namiastki,
– metoda lookup() zwraca referencję uniwersalnego typu Object, a
więc jest konieczne rzutowanie (cast) na typ docelowy.
• Wykorzystuje zdalny serwer wywołując metody uzyskanego
lokalnego obiektu-namiastki.
63
Interfejs RMI
• Metody zadeklarowane w interfejsie muszą byd
zaimplementowane w klasie zawierającej metody
organizujące transport danych (są one dostarczane
przez RMI):
– różne tryby pracy serwera metod.
• Kod serwera RMI powinien implementowad public
static void main(String) lub jej odpowiednik dla
apletów.
64
Inicjacja serwera RMI
• Funkcja main może (ale nie musi) byd jedną
z metod klasy implementującej metody wywoływane
zdalnie.
• Minimalna procedura inicjująca serwer RMI:
– tworzy przynajmniej jeden obiekt klasy implementującej
zdalne wywołania,
– rejestruje ten obiekt w katalogu serwerów.
65
Komunikacja RMI
• Obiekt RMI jest gotowy do działania natychmiast po utworzeniu.
• Serwis katalogowy przechowuje i udostępnia klientom nazwy
zarejestrowanych obiektów- serwerów w postaci URL:
rmi://nazwa_komputera/nazwa_interfejsu
• Klient może uzyskad referencję do lokalnej namiastki obiektu
zdalnego wywołując statyczną metodę lookup klasy
java.rmi.Naming i podając jako argument nazwę, pod jaką
obiekt jest zarejestrowany:
– rezultatem jest referencja do interfejsu java.rmi.Remote,
– powinna ona byd rzutowana na referencję do interfejsu
implementowanego przez zdalny obiekt.
66
Przykład
• Serwer RMI realizujący pojedynczą
bezargumentową metodę, która nie zwraca
żadnego rezultatu.
• Po uruchomieniu serwer ma się zarejestrowad w
katalogu obiektów.
• Klient, po nawiązaniu kontaktu z serwerem zleci
wywołanie zdalnej metody, która wyprowadzi
określony napis na standardowe wyjście serwera.
67
Plik 'MyIterationInterface.java'
• Plik z definicją interfejsu:
68
Plik 'MyIterationImplementation.java'
• Kod klasy implementującej interfejs i inicjującej pracę serwera:
69
Szkielet serwera
• Kompilacja:
$ javac MyIterationInterface.java
MyIterationImplementation.java
• Generowanie klasy ze szkieletem serwera
i namiastkami:
$ rmic MyIterationImplementation
– powoduje utworzenie plików
MyIterationImplementation_Skel.class,
MyIterationImplementation_Stub.class zawierających
odpowiednie klasy.
70
JDK 1.5
• Od wersji JDK 1.5 nie jest konieczne generowanie
szkieletu i namiastek za pomocą kompilatora rmic.
• W razie braku obecności pregenerowanych klas maszyna
wirtualna wygeneruje je dynamicznie
w oparciu o wykryte interfejsy zdalnych metod klasy
implementacji – spowoduje to jej załadowanie.
• W celu zachowania kompatybilności z klientami
utworzonymi w środowisku JDK <1.5 należy jawnie
tworzyd namiastki kompilatorem rmic.
71
Uruchomienie serwera:
• Uruchomienie katalogu serwerów (z innego katalogu niż
zawierający pliki klas namiastek):
$ rmiregistry port -Djava.rmi.server.codebase=file:///path/
– port – numer portu, na którym nasłuchuje katalog (standardowo 1099),
– path – ścieżka do katalogu z namiastkami.
• Uruchomienie serwera:
$ java -Djava.security.policy=/path1/java.policy
-Djava.rmi.server.codebase=file:///path2/
MyIterationImplementation
– path1 – ścieżka do katalogu z plikiem konfiguracji zabezpieczeo.
– path2 – ścieżka do katalogu z klasami serwera.
72
Plik 'java.policy'
• Konfiguracja podstawowa konfiguracji zabezpieczeo (pełny
dostęp):
73
• Plik java.policy:
Przykład
– punktem odniesienia przydzielanych uprawnieo jest katalog wskazany przez
właściwośd program.codebase,
– zezwala na odczyt właściwości client.name,
– zezwala na otwarcie połączeo sieciowych powyżej portu 1024,
– zezwala na odczyt i zapis pliku wskazanego przez examples.file,
– zezwala na nasłuch na dynamicznie przydzielonym porcie.
74
example3client.java
• Implementacja klienta RMI:
75
Uruchomienie klienta:
• Po skompilowaniu, zakładając, że serwer pracuje na
komputerze komputer1, uruchomienie klienta:
$ java example3client komputer1
spowoduje wypisanie przez serwer na swoim
terminalu napisu: "Hello, world!"
76
Menedżer obiektów
• Obiekt zarządzający dostępem do puli serwerów:
– pozwala na działanie wielu serwerów tej samej klasy na
tym samym komputerze.
• Zwraca klientom referencje do serwerów za pomocą
mechanizmu RMI:
– definiuje nowy interfejs z metodą zwracającą klientowi
referencję do jednego z zarządzanych obiektów.
77
Schemat działania menedżera obiektów (1)
1
katalog
menedżer
Na komputerze działa katalog
(rmiregistry)
Uruchomienie JVM i w niej
menedżera obiektów
maszyna wirtualna
komputer 2
komputer 1
78
Schemat działania menedżera obiektów (2)
2
katalog
Menedżer obiektów rejestruje się
w katalogu (rebind)
menedżer
maszyna wirtualna
komputer 2
komputer 1
79
Schemat działania menedżera obiektów (3)
3
katalog
menedżer
maszyna wirtualna
komputer 2
Klient uruchomiony na innym
komputerze uzyskuje z katalogu
referencję do menedżera na
serwerze.
maszyna wirtualna
komputer 1
80
Schemat działania menedżera obiektów (4)
4
katalog
menedżer
maszyna wirtualna
komputer 2
Klient wywołuje zdalną metodę w
menedżerze.
Menedżer może wykorzystać
istniejący obiekt lub utworzyć
nowy
maszyna wirtualna
komputer 1
81
Schemat działania menedżera obiektów (5)
5
katalog
Klient otrzymuje referencję do
namiastki, kanał komunikacyjny
jest utrzymywany przez RMI
menedżer
maszyna wirtualna
komputer 2
maszyna wirtualna
komputer 1
82
Schemat działania menedżera obiektów (6)
6
katalog
Klient wywołuje zdalne metody za
pośrednictwem namiastki.
menedżer
maszyna wirtualna
komputer 2
maszyna wirtualna
komputer 1
83
Własności interfejsu Remote
• Mechanizm przekazywania referencji do obiektów
implementujących interfejs Remote jako
argumentów wywołania metod lub rezultatów ich
działania.
• Rozproszone odśmiecanie pamięci (distributed
garbage collection):
– obiekt implementujący Remote może byd usunięty
gdy nie odnoszą się do niego referencje
w maszynach lokalnej i zdalnych.
84
Mechanizm serializacji
• Obiekty nie implementujące Remote i typy proste
przekazywane poprzez wartośd (na odległej maszynie
tworzone są ich kopie).
• Wszystkie klasy będące argumentami lub wynikami
metod RMI muszą implementowad interfejs
java.io.Serializable:
– jego metoda writeObject zapisuje zawartośd obiektu do
strumienia bajtów, a readObject rekonstruuje zawartośd
obiektu ze strumienia bajtów,
– możliwa jest serializacja typów prostych, tablic obiektów
dających się serializowad i obiektów klasy String.
85
Przykład
• Rozproszona realizacja rozwiązania układu równao
A·x = b.
• Zarządzad przydziałem zadao będzie
wielowątkowy program nadrzędny.
• Częśd obliczeniową będzie realizowad wiele
procesów serwerów RMI:
– zdalna procedura przyjmuje jeden argument – obiekt
zawierający m. in. bieżące rozwiązanie,
– wynikiem będzie obiekt tej samej klasy.
86
MyIterationParameters.java
• Klasa argumentu (i wyniku) zdalnej procedury:
87
MyIterationInteface.java
• Interfejs zdalnej procedury:
88
Java Native Interface
• Umożliwia wykorzystanie modułu napisanego w C i
opakowanie go w celu wykorzystania
w aplikacji Java.
• JNI pozwala m. in. deklarowad metody
w Javie, a implementowad je w języku C.
• Taka metoda jest deklarowana jako native.
• Program javah generuje na podstawie deklaracji
plik nagłówkowy z deklaracją w C.
• JNI umożliwia uzyskiwanie referencji do obiektów
maszyny wirtualnej, wywoływanie ich metod i
sygnalizowanie wyjątków.
89
Korzystanie z JNI
• Dla programu w Javie:
– implementacje wszystkich procedur native muszą byd
umieszczone w bibliotece dołączanej dynamicznie,
– funkcje ładujące bibliotekę należy wykonad jawnie.
• Dla procedury w języku C:
– obiekty maszyny wirtualnej mogą byd przez nią
przemieszczane pod inny adres,
– w czasie odwołao do nich należy je czasowo unieruchomid
za pomocą odpowiednich funkcji.
90
kompilacja
(cc –c lub javac)
generacja szkieletu
i namiastki (rmic)
kod źródłowy
programisty
Schemat tworzenia aplikacji
moduły
wspólne
generacja
nagłówka (javah -jni)
MyIterationParameters.java
kod generowany
automatycznie
skompilowany
moduł
MyIterationInterface.java
biblioteka
dynamiczna
konsolidacja
biblioteki (ld -shared -o)
example4client.java
MyIterationImplementation.java
moduły
serwera
MyIterationImplementation.h
moduły
klienta
MyIterationImplementation.c
MyIteration.c
libmyIterationWrapper.so
91
Zastosowanie JNI
• Klasa implementująca metodę zdalną zawierad
będzie deklarację funkcji native.
• Implementacja metody zdalnej będzie
przystosowywała parametry, aby móc wywoład
w/w funkcję.
• Funkcja wywoła pozostałe konwersje parametrów
i wywoła funkcję obliczeniową MyIteration.
• Wyniki odwrotną drogą wrócą do klienta.
92
MyIterationImplementation.java
• Kod klasy implementującej
zdalną procedurę.
93
Generacja szkieletu RMI
i nagłówków JNI
• Po skompilowaniu kodu serwera należy wygenerowad
szkielet serwera i namiastkę dla klienta programem
rmic:
$ rmic MyIterationImplementation
– powstają pliki: MyIterationImplementation_Skel.class,
MyIterationImplementation_Stub.class
• Następnie należy wygenerowad plik nagłówkowy JNI
programem javah:
$ javah -jni MyIterationImplementation
– powstaje plik: MyIterationImplementation.h
94
Plik 'MyIterationImplementation.h'
(fragment)
• W pliku nagłówkowym znajduje się deklaracja funkcji
opakowującej, którą należy zaimplementowad.
95
MyIterationImplementation.c
96
Uruchomienie serwera:
• Moduły języka C należy skompilowad do postaci
biblioteki ładowanej dynamicznie:
$ gcc -c *.c
$ ld -shared -o libmyIterationWrapper.so *.o
• Aby uruchamiany serwer odnalazł i załadował
bibliotekę dynamiczną należy wcześniej ustawid
zmienne środowiskowe (por. opcję -cp):
$ export LD_LIBRARY_PATH=/path
$ java -cp . -Djava.security.policy=/path/java.policy
-Djava.rmi.server.codebase=file:///path/
MyIterationImplementation
97
Kod klienta
• Realizacja wielowątkowa.
- kod odpowiedzialny
za sekcję krytyczną
- kod odpowiedzialny
za barierę
- pozostały kod
związany z wątkami
98
example4client.java
(cz. I)
99
example4client.java
(cz. II)
100
example4client.java
(cz. III)
101
example4client.java
(cz. IV)
102
Uruchomienie klienta:
• Po uruchomieniu serwerów na odpowiednich
komputerach można uruchomid klienta:
$ java example4client komputer1 komputer2
Thread komputer1: -0.6666667 1.2555557 3.0 4.0 5.0
Thread komputer2: -0.6666667 1.2555557 -0.3437039 1.4027405 0.6546566
Thread komputer1: 0.6586601 -0.080675356 -0.3437039 1.4027405 0.6546566
Thread komputer2: -0.6666667 1.2555557 0.4121416 0.10546201 0.15754676
Thread komputer1: 0.14908929 0.21676 0.4121416 0.10546201 0.15754676
•
Zatrzymanie programu jest możliwe przez przesłanie odpowiedniego sygnału (np.
via Ctrl-C z konsoli).
103
Superserwer RMI
• Możliwe jest uruchamianie serwera RMI na
żądanie:
– w celu wykonania danego zlecenia (wykonania zdalnej
metody),
– ewentualnie z oczekiwaniem przez określony czas na
kolejne zgłoszenia,
– wymaga to działania demona zdalnego aktywowania
obiektów rmid (od JDK 1.2),
– uruchamia on maszynę wirtualną, a w niej serwer
obsługujący żądanie.
104
Przykład - c.d.
• Klient wczytuje klucz publiczny (publicKey) z pliku;
– przy wywołaniu metody zdalnej „opakowuje” parametry
i dołącza podpis cyfrowy:
• Serwer wczytuje klucz prywatny (privateKey) z pliku;
– przed wykonaniem metody zdalnej weryfikuje tożsamośd
klienta, który nadesłał podpisany obiekt (sObj):
– zmienna isFriend będzie miała wartośd true, jeśli podpis został
wykonany za pomocą prawidłowego klucza.
105
CORBA
• CORBA – Common ORB Architecture
• ORB – Object Request Broker
Wikipedia: W
najbardziej generalnym ujęciu brokerem jest podmiot
świadczący określone usługi, z reguły pośrednictwa,
działający na cudzy rachunek…
• Standard komunikacji aplikacji w środowisku
rozproszonym realizowanej za pośrednictwem
wspólnego brokera ORB.
• Opracowany przez Object Management Group:
http://www.omg.org/
106
Interfejs Corby
• Moduły programowe komunikują się z innymi za
pośrednictwem własnych brokerów.
• Wszyscy brokerzy komunikują się ze sobą
w jednakowy sposób (common).
• Moduł poznaje charakterystykę interfejsu innego
modułu:
– poprzez dynamiczne pobranie definicji interfejsu ze
standardowego serwisu: katalogu interfejsów (interface
repository),
– poprzez statyczne wkompilowanie do własnego kodu
definicji wymaganych interfejsów.
107
CORBA
108
Interface Definition Language
• IDL – uniwersalny język opisu interfejsu.
• Definicje interfejsów są niezależne od
języków programowania używanych do
stworzenia modułów.
• Odpowiednie narzędzia przekształcają
definicje sformułowane w języku IDL na ich
odpowiedniki w danym języku:
– m. in. C,C++, Smalltalk, Ada, Cobol, Java.
109
Własności IDL
• Język IDL umożliwia definiowanie:
– modułów zawierających deklaracje typów,
stałych, wyjątków, interfejsów oraz definicje
innych modułów.
• Deklaracje interfejsów mogą zawierad:
– deklaracje typów, stałych i wyjątków,
– deklaracje atrybutów i operacji.
• Możliwe jest wielobazowe dziedziczenie
między interfejsami.
110
• Typy proste:
Typy IDL
– całkowite: short (-215 215-1), long (-231 231-1), long long (263 263-1) oraz ich odpowiedniki bez znaku(unsigned) o
zakresach odpowiednio 0 216-1,
0 232-1, 0 263-1;
– zmiennoprzecinkowe: float, double i long double
(wg standardu ANSI/IEEE 754-1985);
– znakowe: char – jednobajtowy dla znaków ISO 8859-1,
wchar – (wide) dla znaków w innych standardach, octet –
jednobajtowy, nie podlegający konwersjom;
– logiczny: boolean (wartości TRUE lub FALSE);
– dla danych dowolnego typu: any.
111
Typy IDL
• C.d. :
– sekwencje (a la wektory) (sequence) w/w;
– łaocuchy znaków: string, wstring;
– typ fixed – reprezentujący 31-znakową liczbę
stałoprzecinkową.
• Typy pochodne:
– struktury (struct), unie (union), wyliczeniowe (enum);
– wyjątki (exception) – CORBA definiuje standardowy
zestaw wyjątków zgłaszanych przez operacje.
• Rekurencja w definicjach struktur nie jest dozwolona
112
Przykład
Definicja błędna
(niedozwolona rekurencja)
struct Node
{
long nodeValue;
Node nextNode;
}
Definicja poprawna
(użycie sequence dozwolone)
struct Node
{
long
nodeValue;
sequence<Node> nextNode;
}
113
Definicje operacji
• Przypominają deklaracje funkcji w języku C.
• Każdy z parametrów jest poprzedzony
obowiązkowym atrybutem, określającym kierunek
przepływu danych:
– in – parametr wejściowy (dane przesyłane od
klienta do serwera),
– out – parametr wyjściowy(od serwera do klienta),
– inout – parametr wejściowy i wyjściowy (dane
przesyłane w obu kierunkach).
• Listę zgłaszanych wyjątków, poprzedzoną dyrektywą
raises, umieszcza się w nawiasach okrągłych za listą
argumentów.
114
Operacje asynchroniczne
• Standardowo CORBA wykonuje operacje
synchronicznie tj. blokuje klienta do czasu
otrzymania wyników.
• Definicja operacji, która ma byd wykonywana
asynchronicznie, musi byd poprzedzona
dyrektywą oneway:
– nie może ona mied parametrów z atrybutami out, inout
ani zgłaszad wyjątków,
– deklaracja zwracanego typu musi byd void.
115
Ograniczenia IDL
• Implementacja zadeklarowanych w IDL operacji
jest dokonywana w językach docelowych.
• Odwzorowanie niektórych konstrukcji IDL
w językach docelowych może byd bardzo
rozbudowane.
• CORBA dopuszcza tworzenie alternatywnych wersji
odwzorowao np. pod kątem określonych
kompilatorów.
116
Operacje wykonywane przez referencje
• Obiekty, implementujące operacje zdefiniowane w
interfejsie, są identyfikowane przez referencje.
• Umożliwiają one wykonanie pewnych prostych,
niezależnych od języka operacji:
– tworzenie swoich duplikatów (Object duplicate())
i usuwanie się (void release()) – należy używad tych operacji
do powielania i usuwania referencji,
– sprawdzanie, czy referencja odnosi się do jakiegokolwiek
obiektu (boolean is_nil()) i czy odnosi się do tego samego
obiektu, co inna referencja (boolean is_equivalent(in Object
other_object)).
117
Operacje wykonywane przez referencje (2)
• Corba umieszcza w/w operacje w module CORBA, w
interfejsie Object (CORBA::Object).
• Wszystkie wymienione operacje są wykonywane w
lokalnej maszynie:
– za pomocą operacji is_equivalent można tylko potwierdzid
identyfikowanie przez dwie referencje tego samego
zdalnego obiektu,
– Jednoznaczne zaprzeczenie tożsamości, bez komunikacji ze
zdalną maszyną, nie jest możliwe.
118
Object Adapter
• Warstwa pośrednicząca między brokerem,
a obiektami implementującymi interfejsy.
• Standardowa wersja (CORBA 2.3) – Portable OA (POA);
– generuje referencje do obiektów implementujących
interfejsy, odpowiada za prawidłową interpretację referencji;
– Udostępnia obiektom informację o kliencie, która może byd
wykorzystana do uwierzytelniania,
– realizuje określoną politykę wykonywania operacji na
obiektach.
119
Model referencyjny Corby
120
Portable Object Adapter
121
Cykl realizacji żądania w POA
122
Sposoby obsługi żądania
• Zależne od producenta implementacji Corby – ogólny
podział serwerów:
– jednowątkowe – mogą byd (lub nie) jednocześnie klientami
oraz mogą szeregowad inne zlecenia
w trakcie obsługi bieżącego; zawsze obsługują tylko jedno
zlecenie w danej chwili,
– wielowątkowe – tworzą nowy wątek dla każdego nowego
żądania; pozwala to jednemu klientowi na jednoczesne
wywołanie kilku metod serwera.
123
Przykład
• Rozproszona realizacja rozwiązania układu
równao A·x = b.
• Wersja jednowątkowa:
– w pełni funkcjonalny serwer,
– klient zdolny do komunikacji tylko z jednym
serwerem,
– język docelowy: C++.
124
Plik 'MyIterationInterface.idl'
• Operacja myIteration zdefiniowana w interfejsie
MyIterationInterface (w języku IDL):
125
Implementacje Corby
• Dalsze tworzenie aplikacji Corby wymaga
wyboru konkretnego produktu ją
implementującego.
• Poniżej zastosowano pakiet ORBacus 4.1:
– implementacja CORBA 2.3,
– stworzony przez Object-Oriented Concepts,
– dawniej projekt typu open source, teraz Iona,
– implementacja dla języków C++ i Java.
126
Odwzorowanie interfejsu IDL
• Narzędzie idl odwzorowuje interfejs IDL do języka
C++:
$ idl MyIterationInterface.idl
• Generowane są pliki:
– zawierające namiastkę serwera oraz jego szkielet:
MyIterationInterface.h, MyIterationInterface.cpp,
MyIterationInterface_skel.h, MyIterationInterface_skel.cpp.
127
Pliki interfejsu (1)
• MyIterationInterface.h
– myVector jest synonimem sekwencji danych typu
CORBA::Float (sekwencja jest realizowana przez szablon
(template) ORBacusa);
– interfejs MyIterationInterface został odwzorowany w klasę
o tej samej nazwie, dziedziczącą po CORBA::Object;
– zadeklarowano w niej jako virtual metodę myIteration.
128
MyIterationInterface.h
(fragmenty)
129
Pliki interfejsu (2)
• MyIterationInterface.cpp
– implementacja metody myIteration;
jest to implementacja klienta:
– kod pakujący argumenty,
– wywołanie funkcji request,
– kod rozpakowujący wyniki.
130
MyIterationInterface.cpp
(fragmenty)
131
Pliki interfejsu (3)
• MyIterationInterface_skel.h
– deklaracja klasy szkieletu serwera,
POA_MyIterationInterface, dziedziczącej po
PortableServer::ServantBase;
– ponowna deklaracja metody myIteration, tym razem jako
czystej – wirtualnej.
132
MyIterationInterface_skel.h
(fragmenty)
133
Pliki interfejsu (4)
• MyIterationInterface_skel.cpp
– implementacja szkieletu;
– nie ma tu implementacji metody zadeklarowanej
w pliku nagłówkowym jako czysta – wirtualna.
• Programista powinien zaimplementowad myIteration
w klasie dziedziczącej po POA_MyIterationInterface
i PortableServer::RefCountServantBase.
134
MyIterationInterface_skel.cpp
(fragment)
135
Plik 'MyIterationImplementation.h'
• Plik nagłówkowy klasy-implementacji:
136
Plik 'MyIterationImplementation.cpp'
• Implementacja metody myIteration (z wykorzystaniem MyIteration.c):
137
example5server.cpp
138
Dygresja:
• CORBA nie narzuca dostawcy sposobu implementacji
referencji do obiektu.
• Wywołanie operacji, zdefiniowanej w IDL jako op
w interfejsie A, wyglądało: ref->op() :
– identyfikator ref oznacza tu referencję i może byd typu A_var lub
A_ptr,
– referencja A_var usuwa wskazywany przez nią obiekt (lub
namiastkę) w chwili gdy sama jest usuwana lub nadawana jest inna
wartośd (zarządzanie pamięcią),
– np. w ORBacusie referencja A_ptr jest zdefiniowana jako zwyczajny
wskaźnik na obiekt klasy A, referencja A_var jest obiektemkontenerem z przedefiniowanym operatorem „->”.
139
Uruchomienie serwera:
• Kompilacja serwera z użyciem bibliotek ORBacusa :
$ c++ -I. -I$(ORBACUS_DIR)/include -L$(ORBACUS_DIR)/lib
-o
server example5server.cpp
MyIterationImplementation.cpp MyIterationInterface.cpp
MyIterationInterface_skel.cpp MyIteration.c
-lOB -lJTC -ldl -lpthread
(należy podstawid ścieżki do katalogów pakietu ORBacus 4.1.x)
• Po uruchomieniu serwer tworzy w bieżącym katalogu plik
„MyIteration.ref”, w którym zapisuje swoją referencję
i rozpoczyna oczekiwanie na zlecenia od klienta.
140
example5client.cpp
141
Uruchomienie klienta:
• Kompilacja:
$ c++ -I. -I$(ORBACUS_DIR)/include
-L$(ORBACUS_DIR)/lib -o
client example5client.cpp
MyIterationInterface.cpp lOB -lJTC -ldl -lpthread
(należy podstawid ścieżki do katalogów pakietu ORBacus 4.1.x)
• Przed uruchomieniem należy dostarczyd plik z referencją.
$ ./client
1.000000 2.000000 3.000000 4.000000 5.000000
-0.666667 1.255556 -0.343704 1.402740 0.654657
0.658660 -0.080675 0.145622 0.318677 0.001189
142
Odwzorowanie IDL do Javy
• Język Java posiada pakiet implementujący Corbę:
org.omg.CORBA.
• Przykład – implementacja klienta w Javie.
• Wygenerowanie interfejsu:
$ $(JDK)/bin/idlj MyIterationInterface.idl
(należy podstawid ścieżkę do katalogu pakietu JDK)
• Powstają pliki:
MyIterationInterface.java, myVectorHolder.java, myVectorHelper.java,
MyIterationInterfaceOperations.java, MyIterationInterfaceHolder.java,
MyIterationInterfaceHelper.java, _MyIterationInterfaceStub.java.
143
Interfejs Corba – Java (1)
• Interfejs (w sensie Cobry) został odwzorowany w
interfejs Javy:
– plik MyIterationInterfaceOperations.java deklaruje
metodę myIteration:
o typach argumentów będących odpowiednikami typów
prostych IDL, za wyjątkiem snapshot, typu
myVectorHolder (ponieważ snapshot jest deklarowany
jako inout).
144
Interfejs Corba – Java (2)
• Corba wymaga, aby wszystkie parametry
transmitowane w Javie do klienta były osadzone w
obiektach – uchwytach (przyrostek Holder).
• Również obiekty implementujące
MyIterationInterface, jako potencjalne parametry
innych operacji, są wyposażone w taką klasę –
uchwyt.
145
Interfejs Corba – Java (3)
• Dla wszystkich klas, których obiekty mogą byd
transmitowane między maszynami, muszą zostad
wygenerowane definicje klas
z kodem serializującym i deserializującym;
– mają one przyrostek Helper.
• W pliku _MyIterationInterfaceStub.java jest
tworzona namiastka operacji, która zleca
serwerowi wykonanie zadania, przekazuje
parametry i odbiera wyniki.
146
example5client.java
147
Uruchomienie klienta (Java):
• Kompilacja:
$ $(JDK)/bin/javac example5client.java My*.java my*.java
_My*.java
(należy podstawid ścieżkę do katalogu pakietu JDK)
• Przed uruchomieniem należy dostarczyd plik z referencją.
$ $(JDK)/bin/java example5client
1.0 2.0 3.0 4.0 5.0
-0.6666667 1.2555557 -0.3437039 1.4027405 0.6546566
0.6586601 -0.080675356 0.14562233 0.3186774 0.001188775
148

Podobne dokumenty