Основы многопоточного и распределенного программирования

       

Учебные примеры: язык Java


В разделе 5.4 был представлен язык Java и программы для чтения и записи простой разде­ляемой базы данных. В разделе 7.9 было показано, как создать приложение типа "клиент-сервер", используя передачу сообщений через сокеты и модуль j ava. net. Язык Java также под­держивает RPC для распределенных программ. Поскольку операции с объектами языка Java на­зываются методами, а не процедурами, RPC в языке Java называется удаленным вызовом метода (remote method invocation — RMI). Он поддерживается модулями j ava. rmi и j ava. rmi. server.

Ниже приведен обзор удаленного вызова методов, а его использование иллюстрируется реализацией простой удаленной базы данных. База данных имеет тот же интерфейс, что и в предыдущих примерах на языке Java из главы 5, но в ее реализации использованы клиент и сервер, которые выполняются на разных машинах.

8.5.1. Удаленный вызов методов

Приложение, использующее удаленный вызов методов, состоит из трех компонентов: ин­терфейса, в котором объявлены заголовки удаленных методов, серверного класса, реализую­щего этот интерфейс, и одного или нескольких клиентов, которые вызывают удаленные ме­тоды. Приложение программируется следующим образом.

•    Пишется интерфейс Java, который расширяет интерфейс Remote, определенный в модуле Java. rmi. Для каждого метода интерфейса нужно объявить, что он возбуж­дает удаленные исключительные ситуации.

•    Строится серверный класс, расширяющий класс UniclassRemoteObject и реали­зующий методы интерфейса. (Сервер, конечно же, может содержать также защищен­ные поля и методы.) Пишется код, который создает экземпляр сервера и регистрирует его имя с помощью службы регистрации (см. ниже). Этот код может находиться в глав­ном методе серверного класса или в другом классе.

•    Пишется класс клиента, взаимодействующий с сервером. Клиент должен сначала ус­тановить диспетчер безопасности RMI, чтобы защитить себя от ошибочного кода за­глушки (stub code, см. ниже), который может быть загружен через сеть.
После этого клиент вызывает метод Naming. lookup, чтобы получить объект-сервер от службы регистрации. Теперь клиент может вызывать удаленные методы сервера.

Как компилировать и выполнять эти компоненты, показано ниже. Конкретный пример рас­сматривается в следующем разделе.

Программа-клиент вызывает методы сервера так, как если бы они были локальными (на той же виртуальной Java-машине). Но когда вызываются удаленные методы, взаимодействие

Глава 8 Удаленный вызов процедур и рандеву                                                                      307

между клиентом и сервером в действительности управляется серверной заглушкой и скелетом сервера. Они создаются после компиляции программы при выполнении команды rmic. За­глушка и скелет — это части кода, которые включаются в программу автоматически. Они нахо­дятся между реальным клиентом и кодом сервера в исходной Java-программе. Когда клиент вы­зывает удаленный метод, он в действительности вызывает метод в заглушке. Заглушка упорядо­чивает аргументы удаленного вызова, собирая их в единое сообщение, и отсылает по сети скелету. Скелет получает сообщение с аргументами, генерирует локальный вызов метода серве­ра, ждет результатов и отсылает их назад заглушке. Наконец заглушка возвращает результаты коду клиента. Таким образом, заглушки и скелет скрывают подробности сетевого взаимодействия.

Еще одно следствие использования удаленных методов состоит в том, что клиент и сервер являются отдельными программами, которые выполняются на разных узлах сети. Следова­тельно, им нужен способ именования друг друга, причем имена серверов должны быть уни­кальными, поскольку одновременно могут работать многие серверы. По соглашению удален­ные серверы именуются с помощью схемы URL. Имя имеет вид: rmi://hostname:port/ pathname, где hostname— доменное имя узла, на котором будет выполняться сервер, port — номер порта, a pathname — путевое имя на сервере, выбираемые пользователем.

Служба регистрации — это специализированная программа, которая управляет списком имен серверов, зарегистрированных на узле.




Она запускается на серверной машине в фоно­вом режиме командой "rmiregistry port &". (Программа-сервер может также обеспечи­вать собственную службу регистрации, используя модуль Java. rmi. registry.) Интерфейс для службы регистрации обеспечивается объектом Naming; основные методы этого объекта — bind для регистрации имени и сервера и lookup для поиска сервера, связанного с именем.

Последний шаг в выполнении программы типа "клиент-удаленный сервер" — запуск сервера и клиента (клиентов) с помощью интерпретатора Java. Сначала запускается сер­вер на машине hostname. Клиент запускается на любом узле, подключенном к серверу. Но тут есть два предостережения: пользователь должен иметь разрешение на чтение фай­лов . class языка Java на обеих машинах, а на серверной машине должны быть разрешены удаленные вызовы с клиентских машин.

8.5.2. Пример: удаленная база данных

В листинге 8.15 представлена законченная программа для простого, но интересного при­мера использования удаленного вызова методов. Интерфейс RemoteDatabase определяет методы read и write, реализуемые сервером. Эти методы будут выполняться удаленно по отношению к клиенту, поэтому они объявлены как возбуждающие исключительную ситуа­цию RemoteException.

Листинг 8.15. Интерфейс удаленной базы данных, клиент и сервер

import java.rmi.*;

import j ava.rmi.server.*;

public  interface RemoteDatabase extends Remote  {

public  int  read()   throws  RemoteException;

public void write(int value)   throws RemoteException; }

class Client   {

public static void main(String[]   args)   { try  {

// установить стандартный диспетчер безопасности RMI System.setSecurityManager(new RMISecurityManager()); // получить объект удаленной базы данных



Класс Client определяет клиентскую часть программы. Он состоит из метода main, ко­торый можно запускать на любой машине. Клиент сначала устанавливает диспетчер безопас­ности RMI для защиты от ошибочного кода заглушки сервера. Затем клиент ищет имя серве­ра и получает ссылку на сервер.


В остальной части программы клиента циклически вызыва-

Глава 8. Удаленный вызов процедур и рандеву                                                                       309

ются методы read и write сервера. Число round повторений цикла задается как аргумент в командной строке при запуске клиента.

Серверный класс RemoteDatabaseServer реализует интерфейс сервера. Сама "база дан­ных" представляет собой просто защищенную целочисленную переменную. Метод ma in серве­ра создает экземпляр сервера, регистрирует его имя и, чтобы показать, что сервер работает, выво­дит строку на терминал узла сервера. Сервер работает, пока его процесс не уничтожат. В программе используются такие имя и номер порта сервера: paloverde: 9999 (рабочая станция автора). Обе части программы должны быть записаны в одном файле, который называется Remot-eDatabase. Java, поскольку это имя интерфейса. Чтобы откомпилировать программу, соз­дать заглушки, запустить службу регистрации и сервер, на узле paloverde нужно выполнить следующие команды.

javac RemoteDatabase.Java

rmic RemoteDatabaseServer

rmiregistry 9999 &

Java RemoteDatabaseServer

Клиентская программа запускается на машине paloverde или на другой машине той же се­ти с помощью такой команды.

Java Client rounds

Читателю рекомендуется поэкспериментировать с этой программой, чтобы понять, как она себя ведет. Например, что происходит, если выполняются несколько клиентов или если за­пустить клиентскую программу до запуска сервера?


Содержание раздела