Zdalna procedura (RPC) - fundament rozproszonego programowania

Rozproszone przetwarzanie (distributed processing/computing) polega na wykonywaniu aplikacji (programu lub grupy programów) na wielu komputerach jednocześnie. Wynika to z faktu, że aplikacja jest podzielona na dwie lub więcej części zainstalowane na różnych komputerach.

Rozproszone przetwarzanie (distributed processing/computing) polega na wykonywaniu aplikacji (programu lub grupy programów) na wielu komputerach jednocześnie. Wynika to z faktu, że aplikacja jest podzielona na dwie lub więcej części zainstalowane na różnych komputerach.

Komputery są połączone siecią i mogą mieć różne charakterystyki sprzętowe (MIPS R4000, Intel-486, SPARC) i software'owe (różne systemy operacyjne, inna reprezentacja danych np. 16-bitowa lub 32-bitowa). Jedną z głównych zalet rozproszonego przetwarzania jest wspólne korzystanie z zasobów sieci - takich jak aplikacje, pliki, drukarki, bazy danych, a także moc obliczeniowa komputerów - przez wiele programów lub użytkowników.

Różne komputery mogą współpracować ze sobą na różnym poziomie integracji. Im bardziej zaawansowana integracja, tym bliżej do idei rozproszonego systemu operacyjnego, gdzie SIEĆ jest traktowana jako uogólniony komputer.

Cechy rozproszonego systemu operacyjnego mają sieciowe systemy operacyjne NetWare Novell'a czy VINES Banyan'a. Usługi sieciowe (network services) w tych systemach są odpowiednikami rozproszonych aplikacji/programów. Podobne cechy mają - rozproszone środowisko komputerowe DCE (Distributed Computing Environment) i rozproszone środowisko zarządzania DME (Distributed Management Environment), ale o nich innym razem.

Trwająca od paru lat, migracja od scentralizowanych systemów komputerowych do tańszych stacji roboczych i PC-tów połączonych siecią zmieniła w sposób zasadniczy podejście do aplikacji software'owych i ich programowania. Wciąż jednak zbyt mało jest dobrych przykładów realizacji rozproszonych aplikacji. Rozproszone programowanie - to jeszcze nadal trudna i niewdzięczna praca. Od projektantów i programistów wymaga ona nowych umiejętności i konieczności rozwiązania takich nowych problemów inżynierskich jak wybór i dostęp do zasobów w sieci oraz ich zabezpieczenie, komunikacja, itp. Do tego dochodzą nowe narzędzia programowe lub brak takowych - kompilator sieciowy, "debugging" w rozproszonym niejednorodnym środowisku, tradycyjne kompilatory dla różnych systemów operacyjnych, na których aplikacja ma być używana, itp.

Co trzeba wziąć pod uwagę w rozproszonym programowaniu?

Dwie najważniejsze decyzje to wybór modelu rozproszenia i modelu komunikacji. Najczęściej stosowane modele rozproszenia to "klient/serwer" i "każdy z każdym" (peer-to-peer). Poszczególne części rozproszonej aplikacji są wykonywane w oddzielnych procesach i na innych (choć niekoniecznie) komputerach. Istnieje wiele sposobów komunikacji między procesami w systemach operacyjnych (IPC - interprocess communication). Mogą to być rozwiązania właściwe dla danego systemu operacyjnego, potoki (pipes), kolejkowanie poleceń (message queues), zdalne procedury, obiektowe przekazywanie poleceń (object-oriented message-passing).

Nie wdając się w porównywania tych modeli zaję się zdalnymi procedurami, które są podstawą rozproszonego programowania w modelu klient/serwer.

Co to jest zdalna procedura?

Pojęcie zdalnej procedury (RPC - Remote Procedure Call) najłatwiej chyba przedstawić na zasadzie analogii do procedury lokalnej. Każdy programista wie, że dobrze napisany program ma konstrukcję modułową, tzn. składa się z części głównej i procedur (lokalnych), którym przypisane są konkretne zadania (np. program KONTO z procedurami: wpłata na konto bankowe, wypłata, stan konta). Procedury te są wywoływane z programu głównego lub z innych procedur. Taki program (aplikacja) wykonuje się na jednym komputerze w jednorodnej przestrzeni adresowej procesu, który system operacyjny dla tego programu utworzył (rys. 1).

Jak będzie to wyglądać w rozproszonej aplikacji? Składa się ona nie z jednego programu jak poprzednio, lecz jest podzielona na część klienta i część serwera, czyli na dwa programy (rys. 2). Po stronie klienta wywoływanie procedur w programie wygląda podobnie lub identycznie jak poprzednio. Zdalna procedura zachowuje semantykę procedury lokalnej, a więc identyczne wywołanie, przekazywanie informacji przez podobne argumenty wejściowe i wyjściowe (rezultaty).

Jest to jednak podobieństwo pozorne. Po pierwsze, kod każdej procedury - aczkolwiek niezmieniony - nie znajduje się w części klienta (front end) lecz w części serwera (back end). W części klienta pozostała resztówka czyli tak zwany "stub", który umożliwia wywołanie procedur przy użyciu sieci. Procedury wykonują się na komputerze, na którym zainstalowana jest część serwera aplikacji. Lokalne procedury zostały zastąpione zdalnymi procedurami!

Zdalna procedura "chowa" szczegóły dotyczące sieci przed programistą. Nie musi on wiedzieć jak dokonywać połączeń sieciowych, jak je obsługiwać i jak poprawnie się rozłączać. Zdalna procedura zapewni mu również obsługę błędów sieciowych. RPC należy umiejscowić w warstwie sesji w 7-poziomowym modelu sieci.

Bardzo ważną cechą zdalnych procedur jest umiejętność tłumaczenia jednego typu reprezentacji danych na inny w procesie zwanym marshalling. W ten sposób można - bez problemu - porozumiewać się między systemami komputerowymi o różnych architekturach. Nowsze pakiety RPC zapewniają identyfikację użytkownika i bezpieczny dostęp do zasobów sieci, potrafią znaleźć część serwera danej aplikacji lub usługę sieciową niezależnie od jej fizycznej lokalizacji oraz są niezależne od używanej warstwy transportu.

Czy są jakieś minusy tej "cudownej" technologii? Coś tam zawsze się znajdzie. RPC świetnie nadaje się do zarządzania rozproszonego środowiska komputerowego jeśli przez nie rozumiemy komunikujące się ze sobą systemy operacyjne różnych stacji roboczych lub dużych komputerów, ale nie da się łatwo zastosować do zarządzania siecią, gdy w grę wchodzą koncentratory, mostki, routery czy multiplexery.

Inna wada to taka, że zdalna procedura jest z natury swej synchroniczna. A co to znaczy w aplikacjach sieciowych, gdzie wszystko odbywa się asynchronicznie, nie trzeba nikomu tłumaczyć. Co prawda są na to sposoby, jak niezależne wątki aplikacji w ramach jednego procesu (threads), ale nie są one dzisiaj dostępne we wszystkich systemach operacyjnych.

Zdalna procedura - jak to działa?

Narzędzia programowe dla pakietów RPC automatycznie generują tzw. resztówki lub "stubs" (stub code) dla obu części (klient i serwer) rozproszonej aplikacji.

Każda z gotowych części rozproszonej aplikacji KONTO (klient i serwer) zawiera taką resztówkę i bibliotekę RPC. W programie KONTO/klient główna ścieżka programu wywołuje zdalną procedurę sądząc, że jest to procedura lokalna. W istocie wywołana zostaje resztówka, czy też "stub". Zadaniem tej części kodu jest określić rodzaj transportu, który będzie używany; znaleźć - za pomocą usług sieciowych globalnego katalogu (directory service) - sieciowy adres komputera, na którym program KONTO/serwer został uruchomiony, wreszcie ustanowić sieciowe połączenie, dokonać tłumaczenia danych przeznaczonych do transmisji (marshalling) i przesłać polecenie żądające wykonanie danej procedury do programu KONTO/serwer.

Tu istotne przypomnienie: program KONTO/serwer musi być uruchomiony (na stałe) i oczekiwać na polecenia licznych

kopii programu KONTO/klient, uruchamianych z różnych komputerów włączonych do sieci.

Kiedy serwer otrzyma z sieci polecenie, przekazuje je do biblioteki RPC do rozpoznania, gdyż np. może nie być procedury odpowiadającej danemu poleceniu. "Stub" przygotowuje dane dla procedury poprzez odpowiednie ich sformatowanie (unmarshalling). W końcu procedura wykonuje się przekazując rezultaty z powrotem do "stubu", a stąd - po sformatowaniu (tym razem "marshalling") - przez sieć do programu KONTO/klient.

Klient, poprzez warstwy biblioteki RPC i resztówkę, a zarazem kolejne formatowanie danych - "unmarshalling", otrzymuje rezultaty wykonanej zdalnie procedury. Następuje powrót z wywołanej procedury do ścieżki głównej programu KONTO/klient.

Programowanie z użyciem zdalnej procedury

Obie części rozproszonej aplikacji, klient i serwer muszą interpretować zdalne procedury w ten sam sposób. Pierwsza faza programowania, to zdefiniowanie składni każdej procedury we wspólnym pliku specyfikacyjnym. W niektórych pakietach RPC nazywa się to plikiem IDL (Interface Definition Language). IDL jest zbliżony do języka

programowania C. Plik specyfikacyjny kompiluje się przy użyciu kompilatora sieciowego (różne angielskie terminy jak "network compiler" lub "protocol compiler"). W rezultacie otrzymuje się plik nagłówkowy RPC dla języka C (header file) - wspólny dla programów klienta i serwera - oraz po jednej resztówce dla każdej części aplikacji.

W drugiej fazie przystępuje się do programowania części klienta i serwera danej aplikacji. To pierwsze zadanie jest łatwiejsze i w zasadzie przypomina tradycyjne programowanie. Programista pisze kod aplikacyjny w języku programowania C pamiętając o tym, aby włączyć plik nagłówkowy RPC do plików zródłowych i aby stosować się do wspólnych definicji, jako że plik nagłówkowy RPC i resztówki wiążą ze sobą kod klienta i serwera. Następnie kompiluje się wszystkie pliki źródłowe (łącznie z resztówką klienta) przy użyciu kompilatora C i program KONTO/klient gotowy!

Z programowaniem serwera jest więcej zachodu. Choć nie jest to trudne, trzeba napisać kod dla zadeklarowanych zdalnych procedur. W wielu wypadkach, gdy tworzy się aplikację rozproszoną z istniejącej lokalnej aplikacji można - niemal w całości - wykorzystać istniejące procedury lokalne. Nieco trudniejszą rzeczą jest napisanie kodu, który prawidłowo uruchomi (zainicjalizuje) program KONTO/serwer. Pozostała praca jest identyczna jak dla klienta. Na ogół jednak kompilacja plików źródłowych będzie odbywać się w innym środowisku komputerowym niż dla programu KONTO/klient.

Dobrze jest wiedzieć, że brutalne życie nie znosi czystych form, wobec tego w praktyce poszczególne programy rozproszonej aplikacji są zarazem klientami, jak i serwerami jednocześnie. Ale dla ścisłości i dla otuchy należy dodać, że w wielu wypadkach pisze się tylko kod klienta do dostarczanych przez firmy software'owe usług sieciowych.

Handlowe pakiety RPC

Jedne z najwcześniejszych realizacji systemów RPC to - ONC RPC (Open Network Computing RPC) firmy Sun oraz NCS RPC (Network Computing System RPC) firmy Apollo/HP. Sun podjął - dobrych kilka lat temu - bardzo mądrą decyzję: udostępnił kod źródłowy swojego pakietu ONC RPC 4.0 plus kompilator sieciowy - RPCGEN - w sieci Internet. Spowodowało to szybki wzrost rozproszonych aplikacji używających zdalnych procedur ONC. Warto wiedzieć, że na ONC RPC opiera się także popularny sieciowy system plików - NFS.

Konkurencyjny kompilator sieciowy firmy Netwise - RPCTOOL - oparty jest na pakiecie zdalnych procedur ONC RPC. Podczas, gdy darmowy RPCGEN stanął w miejscu, RPCTOOL rozwija się umożliwiając kompilacje najnowszych wersji zdalnych procedur ONC z takimi cechami jak niezależność transportowa (TIRPC).

"Gwiazda" NCS RPC (z kompilatorem sieciowym NIDL) nieco przygasła choć głównie na tym standardzie oparte są zdalne procedury DCE (RPC DCE). Jeśli ambitne zamierzenie Open Software Foundation powiedzie się NCS RPC "przeżyje" jako DCE RPC. Warto może, jednym tchem wymienić pakiety takie jak: Courier RPC (Xerox), Vines NetRPC (Banyan), DECrpc (DEC).

Zdalne procedury to z pewnością podstawowy element rozproszonego przetwarzania. W połączeniu z niezależnymi wątkami (threads) ich główną zaletą jest możliwość obsługi wielu równoczesnych poleceń między częściami rozproszonej aplikacji.

W celu komercyjnej reprodukcji treści Computerworld należy zakupić licencję. Skontaktuj się z naszym partnerem, YGS Group, pod adresem [email protected]

TOP 200