R-20-01.doc

(250 KB) Pobierz
PLP - Rozdział 20

 

20. CORBA

CORBA jest skrótem nazwy Common Object Request Broker Architecture (co oznacza ogólną architekturę pośrednika wywoływania obiektów). Jest to unormowany schemat budowy rozproszonych aplikacji obiektowych, którego elementy mają możliwość komunikowania się ze sobą niezależnie od platformy i użytego języka programowania.

Ogólny schemat architektury systemu wykorzystującego CORBA podany jest na poniższym rysunku. Klient i serwer aplikacji są programami, które można napisać samemu:

rysunek ze str. 723

W architekturze CORBA wyróżnia się elementy i warstwy.

Język definicji interfejsu (IDL)

Jest to język używany w deklaracjach interfejsów obiektów. Bardzo mocno przypomina on deklaracje klas w języku C++.

IDL jest stosowany do deklarowania struktur danych i metod wykorzystywanych przez CORBA w aplikacjach. Dla danego zestawienia ORB (patrz niżej) i języka programowania IDL jest zwykle kompilowany do postaci „zrębów” (interfejsy statyczne) i „szkieletów” (interfejsy dynamiczne). Zręby można następnie dołączać do klienta, zaś szkielety do serwera, zaś kod generowany przez kompilator IDL jest wykorzystywany do zarządzania komunikacją między kodem użytym w kliencie lub serwerze, a pośrednikiem wywoływania obiektów (ORB). IDL przekazuje do ORB informacje o rodzaju używanego systemu, wskazując rodzaj wymienianych danych oraz rodzaje wywołań wymaganych przez te dane.

Pośrednik wywołań obiektów (ORB)

Jest to warstwa podstawowa, wykorzystywana przez wszystkie pozostałe.

ORB cechuje się właściwością zdalnego wywoływania i na swoim najbardziej elementarnym poziomie pośredniczy między klientami żądającymi jakichś działań oraz przekazuje parametry między klientem i serwerem. Może on kierować żądania do innego pośrednika ORB, jeżeli on właśnie zarządza żądaną usługą.

Najważniejszą cechą zapewniającą takie działanie jest możliwość komunikacji między pośrednikami ORB niezależnie od ich implementacji. CORBA definiuje ogólne zasady tej komunikacji w postaci protokołu komunikacyjnego (oznaczanego skrótem GIOP od słów General Inter-ORB Protocol). GIOP określa wspólną reprezentację danych (CDR, czyli Common Data Representation), wspólne formaty komunikatów i wspólne założenia odnośnie do dowolnej sieciowej warstwy transportowej, która może być użyta do przekazywania komunikatów GIOP. Nazwy, które tutaj wymieniliśmy stanowią zaledwie niewielki ułamek terminologii i skrótów, z którymi powinni zapoznać się zainteresowani czytelnicy!

Obecnie, przy względnej dominacji sieci wykorzystujących TCP/IP, prawie cała komunikacja między pośrednikami ORB i obsługiwanymi przez nie procesami korzysta z TCP/IP. Dlatego właśnie dodano specyfikację transportową do GIOP, definiując internetowy protokół komunikacji między pośrednikami ORB. Jest on oznaczamy skrótem IIOP pochodzącym od nazwy Internet Inter-ORB Protocol. Same protokoły w architekturze CORBA są zdefiniowane za pomocą IDL i właśnie dzięki temu uzyskano duże możliwości współdziałania różnych implementacji ORB. Jeżeli np. aplikacja ORBit (czyli aplikacja ORB należąca do GNOME) może mieć dostęp do obiektu ORBit za pomocą protokołu IIOP, to staje się wielce prawdopodobne, że może ona mieć dostęp także do obiektów zdefiniowanych za pomocą innych pośredników ORB, np. omniORB, niezależnie od tego, czy są one umieszczone na tym samym serwerze, czy na innym.

Protokół IIOP został znormalizowany, a więc można się spodziewać, że program-klient napisany dla pośrednika ORBit będzie pomyślnie korzystał z usług zdefiniowanych za pomocą omniORB. Nie wymaga to od programisty zbytniego wysiłku, a więc jeżeli została zdefiniowana odpowiednia specyfikacja takiego obiektu (IOR, patrz niżej), to odwołanie może być skierowane do oddalonego pośrednika ORB i tam przetworzone.

Współdziałające odwołanie do obiektu (IOR)

Żądanie wprowadzenia metody obiektu musi zawierać tzw. współdziałające odwołanie do obiektu (oznaczane skrótem IOR od nazwy Interoperable Object Reference). Jest to odwołanie do obiektu zdefiniowanego w CORBA mające postać napisu. Zawiera ono informację o użytym rodzaju IDL, nazwę węzła przechowującego obiekt, porządek bajtów dla tego węzła oraz w systemach TCP/IP — dane gniazda sieciowego, które może być wykorzystane do dostarczenia żądania do pośrednika ORB działającego w tym węźle.

Czasami warto podczas uruchamiania aplikacji podjąć próbę zdekodowania części IOR, ale w zasadzie powinno ono być traktowane jako przezroczyste, czyli jako coś, co powinien zinterpretować pośrednik ORB.

Zainicjowanie systemu CORBA zazwyczaj wymaga rozesłania jakichś IOR w celu poinformowania klientów o sposobie dostępu do odpowiednich serwerów. Jest to najbardziej dokuczliwy proces podczas uruchamiania aplikacji w architekturze CORBA.

Adapter obiektu

Pomiędzy pośrednikiem ORB a implementacją obiektu występuje tzw. adapter obiektu. Zawiera on funkcje wspomagające tworzenie, identyfikację, uaktywnianie i na końcu zwalnianie obiektu.

Najpierw w architekturze CORBA zdefiniowany został podstawowy adapter obiektu (BOA, od słów Basic Object Adpator), ale jego specyfikacja nie była dokładnie określona. Różne pośredniki korzystały z całkowicie odmiennych wywołań, co wyjątkowo silnie ograniczało możliwość współdziałania aplikacji. Następnie wprowadzono przenośny adapter obiektu (POA, czyli Portable Object Adaptor), który umożliwiał korzystanie z wielu cykli pracy w znacznie bardziej wygodny sposób.

Oznacza to, że gdy jakiś pośrednik odwołań do obiektów okaże się nieprzydatny i jeżeli dostępne jest odwzorowanie użytego języka, to wprowadzając niewielkie zmiany w kodzie programu można będzie przystosować go do innego pośrednika.

Serwery

Serwery zapewniają korzystanie z obiektów, zezwalając klientom na wywołania metod tych obiektów. Usługi CORBA zostały określone za pomocą standardowych definicji języka IDL, dzięki czemu znane są sposoby wykonywania ogólnodostępnych czynności. Dzięki usługom nazewniczym można budować rejestr dostępnych obiektów, a więc aplikacje w architekturze CORBA mogą wyszukiwać wymagane usługi. Obsługa zdarzeń zapewnia umieszczane zdarzeń w kolejkach, dzięki czemu aplikacje korzystające ze zdarzeń przy wywołaniach w architekturze CORBA nie muszą szczegółowo analizować każdej usługi od początku.

Klienty nie muszą znać bezpośrednio danych identyfikacyjnych serwera, z którego usług chcą skorzystać. Komponenty serwera mogą być przechowywane na różnych maszynach rozrzuconych po całej sieci i klient nie musi znać ich dokładnej lokalizacji. Przeważnie wysyłają one żądania wymagające wykonania pewnych operacji na obiekcie, zaś pośrednik ORB kieruje te żądania do właściwego serwera w odpowiedniej lokalizacji. W architekturze CORBA istnieje kilka usług, które pozwalają programom rejestrować ich własne usługi. Oznacza to, że aplikacja CORBA może wyszukiwać dostępne usługi podczas swojej pracy.

Zwróćmy uwagę na to, że CORBA nie jest „czystym” systemem typu klient-serwer, bowiem zezwala również na komunikowanie się węzłów między sobą. Od wielu usług CORBA wymaga się, aby serwery odwracały swoją rolę stając się klientami żądającymi usług od innych serwerów.

Jako przykład można podać aplikację obsługującą wypożyczalnię płyt DVD. Serwer tej aplikacji przetwarzający zapytania może być traktowany jako typowy serwer, ale zmienia się on w klienta podczas żądania danych od serwera bazy danych lub żądania potwierdzeń autentyczności od serwera zabezpieczeń.

Usługi nazewnicze i usługi wymiany

Wiele aplikacji używających usług nazewniczych i transakcyjnych w architekturze CORBA może równocześnie korzystać z tego samego „rejestru”, zaś to umożliwia zastosowanie nawet specyficznych programów pomocniczych do zarządzania systemem śledzenia informacji o wszystkich zarejestrowanych obiektach. Bez unormowanych zasad działania, takich jak usługi nazewnicze, nie można byłoby utworzyć aplikacji wykonującej takie zadanie. Usługi nazewnicze umożliwiają także tworzenie powiązań z usługami katalogowymi, np. z LDAP.

Nigdzie nie wspomniano tutaj o użyciu UDP zamiast TCP, o nazwach węzłów sieci lub o stosowaniu określonego języka programowania przy tworzeniu klientów lub serwerów. Podczas korzystania z RPC lub gniazd sieciowych aplikacja musi zwracać uwagę na stany węzłów sieci i sposoby uzyskiwania połączeń z serwerami. W architekturze CORBA zagadnienia te są traktowane jako szczegółowy opis środowiska, który rozwiązuje dana implementacja. Zarządza tym wszystkim pośrednik ORB, przeważnie nie ingerując w aplikację. Gniazda sieciowe zapewniają podstawowy format powiązań z określonymi standardowymi protokołami. Dzięki temu aplikacja musi się troszczyć tylko o protokół oraz o format danych, które mają być przekazywane. W architekturze CORBA ten format opisuje IDL, zaś protokółem zajmuje się pośrednik ORB — a więc została tu wyeliminowana konieczność analizy surowych danych. Ścisłe określanie danych za pomocą IDL umożliwia przekaz tych danych o odpowiedniej strukturze z jednego systemu do innego, niezależnie od używanego systemu operacyjnego, protokołu sieciowego, języka programowania oraz pośrednika ORB.

Ogólna ocena architektury CORBA

Zastosowanie architektury CORBA jest początkowo bardziej kosztowne w porównaniu z bezpośrednim nakładaniem na siebie elementów tworzonego systemu. Zyski widać dopiero przy długoterminowym korzystaniu z tej architektury. Użycie CORBA do wydzielenia klienta i serwera z aplikacji w przypadku naszego programu obsługującego wypożyczalnię płyt DVD nie przyniesie znacznych ulepszeń w porównaniu z zastosowaniem gniazd sieciowych lub RPC. Uzyskujemy tylko to, że łatwiejsze stanie się zarządzanie następnymi modyfikacjami, które mogą obejmować:

q       powiązanie aplikacji obsługującej wypożyczalnię z systemem księgującym;

q       podłączenie czytnika kodu kreskowego umieszczonego w pojemniku na zwroty (zwrot płyty jest obsługiwany w momencie, gdy klient wsunie płytę do pojemnika odbiorczego, przesuwając ją nad czytnikiem kodu);

q       przenoszenie danych do bazy PostgreSQL bez konieczności angażowania interfejsu klienta, jeżeli nie ma takiego powodu;

q       zastosowanie języka Java w programie serwera;

q       rozdzielenie aplikacji w taki sposób, aby baza danych obsługująca klientów wypożyczalni była zarządzana z jednego komputera, zaś tytuły płyt były obsługiwane z innego oraz aby dostęp do pozostałych elementów aplikacji był możliwy z różnych komputerów.

Wszystkie te zmiany środowiskowe można wprowadzić bez konieczności modyfikacji interfejsu klienta. Jeżeli zdarzy się, że zostaną wprowadzone nowe interfejsy, to jedyną zmianą będzie dołączenie nowego oprogramowania do istniejących serwerów wypożyczalni DVD. Nie zaburzy to w najmniejszym stopniu już istniejących programów-klientów.

Jeżeli zajdą zmiany funkcjonalne w serwerze, to prawdopodobnie trzeba będzie odnowić połączenia klientów w architekturze CORBA. Jest to wymagane do uzyskania informacji o nowych lokalizacjach usług obiektowych. Przy założeniu, że interfejs się nie zmieni, uzyskanie dostępu przez klienta do nowego serwera może polegać tylko na jego wylogowaniu i powtórnym zalogowaniu.

Zupełnie niezauważalnie można dodawać następne usługi. Usługi związane z bezpieczeństwem w architekturze CORBA mogą obejmować np. weryfikację tożsamości przeprowadzaną dzięki specjalnemu wspomaganiu ze strony ORB. Mogłoby to zmniejszyć wymagania odnośnie do zaufania między klientami a serwerami, a alternatywą byłoby dołączanie kodu weryfikującego do każdego z nich. Taka sytuacja dotyczy również niektórych innych usług CORBA: ich działanie można ulepszyć przenosząc niektóre ich cechy funkcjonalne do pośrednika ORB.

Oddzielenie definicji IDL od języka programowania użytego w klientach i serwerach staje się szczególnie przydatne wtedy, gdy zespoły programistów zaczynają pracować w rozproszeniu. Najważniejsze jest wówczas utrzymanie dokładnie i jednoznacznie zdefiniowanych interfejsów, szczególnie zaś wtedy, gdy system ma mieć jakąś postać otwartego standardu, a programiści są zatrudnieni w różnych organizacjach i nawet w różnych krajach.

Interfejs musi być bardzo dokładnie zdefiniowany, ale przy implementacji usługi mamy pozostawioną możliwość wyboru. Ważne jest więc to, że zarówno środowisko, jak i implementacja, mogą się zmieniać bez konieczności modyfikacji interfejsów.

W odróżnieniu od wielu rozwiązań alternatywnych, CORBA pozwala na łączenie wszelkich systemów operacyjnych i wszelkich rodzajów języków programowania. Konsorcjum o nazwie Object Management Group (OMG) zarządzające standardami CORBA, uzgodniło znormalizowane sposoby odwzorowania konstrukcji IDL w kilku językach programowania: Ada, C, C++, COBOL, Common Lisp, Java i Smalltalk. Inne organizacje wprowadziły mniej sformalizowane zapisy dotyczące odwzorowania IDL w innych językach, np. Perl, Python i TCL.

Niektóre języki, jak np. C, nie obsługują bezpośrednio abstrakcji obiektowych, a więc obiekty muszą w nich być symulowane. Prowadzi to do nieco dziwnie wyglądającego kodu, ale jednocześnie możliwe jest uzyskanie wyników niedostępnych w inny sposób.

CORBA i RPC

CORBA najbardziej przypomina RPC (patrz rozdział 18), ponieważ umożliwia zdalne wywoływanie procedur przez klienty. Najważniejszą różnicą jest tu sposób lokalizacji serwerów: w systemach korzystających z CORBA nie są one wybierane na podstawie informacji o węźle i gnieździe utrzymywanej przez klienta, lecz na podstawie tzw. „odwołań obiektowych” używanych przy kierowaniu żądań przez ORB. Dzięki temu to ORB zarządza wymianą informacji między klientami a serwerami, a nie same klienty.

Podstawowym problemem w alternatywach takich jak RPC i gniazda sieciowe nie jest brak skomplikowanych abstrakcji, ale raczej to, że w miarę wzrostu stopnia złożoności aplikacji korzystających z takich mechanizmów, coraz trudniejsze staje się zarządzanie nimi. Widać to szczególnie wyraźnie, gdy aplikacje muszą korzystać z dodatkowych usług, rejestrów i pośredników. Z drugiej strony, CORBA zawiera wzorzec dodawania nowych usług, zaś konsorcjum OMG unormowało wiele użytecznych dodatkowych abstrakcji obiektów oraz pewne właściwości tej architektury wspomagające aplikacje. Zagadnienia te zostaną omówione bardziej szczegółowo w następnych częściach książki.

CORBA rozwiązuje kilka znaczących ograniczeń spotykanych w RPC:

q       RPC wymaga, aby podczas kompilacji funkcje API były deklarowane statycznie.

Zarówno RPC, jak i CORBA zawierają języki definicji interfejsu, określające dozwolone operacje, czyli tzw. „protokół”. CORBA obsługuje dodatkowo tzw. interfejs wezwań dynamicznych (Dynamic Invocation Interface). Mogą z niego korzystać programy, sprawdzając podczas pracy w repozytorium interfejsów dostępność metod, które mogą być następnie użyte w wywołaniach. Stosując RPC nie uzyskuje się żadnej możliwości takiego działania.

q       RPC umożliwia tylko synchroniczną wymianę komunikatów.

W architekturze CORBA komunikacja między klientem a pośrednikiem (ORB), podobnie jak komunikacja między pośrednikiem a serwerem, odbywa się synchronicznie — w tradycyjny sposób. Można tu jednak bardzo prosto dołączyć elementy pośredniczące umożliwiające korzystanie z innych modeli wymiany komunikatów. Połączenia z pośrednikami mogą więc pozostać synchroniczne, zaś serwer CORBA przyjmujący i przechowujący żądania może symulować komunikację asynchroniczną w połączeniach z serwerem faktycznie obsługującym dane żądania.

Istnieje nowy sposób obsługi wykorzystujący tzw. asynchroniczną metodę wezwań (oznaczaną skrótem AMI od Asynchronous Method Invocation), który umożliwia prawdziwie asynchroniczny sposób wymiany komunikatów. Zastosowano go w kilku pośrednikach ORB.

q       RPC obsługuje tylko procedury, zaś współczesne systemy coraz częściej zaczynają korzystać z obiektów.

q       RPC bardzo mocno wiąże się z protokołami TCP/IP.

W architekturze CORBA założono wprawdzie charakterystykę wymiany informacji podobną do stosowanej przez TCP/IP, ale świadomie rozważa się użycie alternatywnych systemów transportu informacji, takich jak IPX, ATM, XNS firmy Xerox, SNA firmy IBM, DECnet, a także współużytkowanej pamięci lokalnej ze względu na jej olbrzymią szybkość działania.

W szczególności użycie współużytkowanej pamięci lokalnej może ogromnie powiększyć wydajność i jest nieomal obowiązkowe, jeżeli rozważa się zastosowanie architektury CORBA w obsłudze abstrakcji graficznych na najniższym poziomie — tak jak to ma miejsce w sterowaniu systemami okienkowymi (projekt Berlin, http://www.berlin-consortium.org/) — albo w systemach okienkowych wykorzystujących architekturę CORBA jako warstwę komunikacyjną między API a kontrolerem grafiki.

Mechanizmy te charakteryzują się całkowicie odmienną semantyką, a w architekturze CORBA świadomie starano się uniknąć ścisłego powiązania z jakimkolwiek mechanizmem. Obecnie „wszyscy” posługują się TCP/IP, co było nie do pomyślenia jeszcze dziesięć lat temu, ale można sobie wyobrazić, że w roku 2010. wszyscy będą korzystać z ATM w swoich osobistych łączach gigabitowych. CORBA może sprostać tym wymaganiom bez problemów. Niewielka liczba osób zajmujących się rozwojem RPC nie zdoła zapewne wprowadzić modyfikacji nadążających za takimi zmianami.

q       Wiele wysiłku poświęcają obecnie architekturze CORBA projektanci i programiści, zaś RPC praktycznie nie jest już rozwijane, ponieważ firmy sponsorujące te prace zajęły się właśnie architekturą CORBA. Jeżeli ktoś próbuje rozwijać RPC firmy ONC, to może okazać się jedynym użytkownikiem wykorzystującym efekty swojej pracy. Istniał wprawdzie projekt bezpłatnego udostępnienia implementacji sponsorowanej przez DCE, ale wydaje się, że wyszedł on już z mody.

CORBA i gniazda sieciowe

W podobny sposób, jak w poprzednim podrozdziale, porównamy teraz architekturę CORBA z gniazdami sieciowymi:

q       Użycie IDL do dokładnego definiowania typów danych umożliwia przekaz danych o odpowiedniej strukturze z jednego systemu do innego, niezależnie od używanego systemu operacyjnego, protokołu sieciowego, języka programowania oraz pośrednika ORB...

Zgłoś jeśli naruszono regulamin