Spec-Zone .ru
спецификации, руководства, описания, API
Содержание документации

Разработка Служб, которые будут Запущены от inetd

На Операционной системе Соляриса (Солярис ОС), демон Интернет сервисов inetd обеспечивает альтернативу запуску служб во время начальной загрузки системы. Этот демон, серверный процесс для интернет-служб стандарта, может быть сконфигурирован, чтобы запустить службы по требованию. Для получения дополнительной информации на демоне Интернет сервисов, см. Солярис ОС inetd(1M) страница справочника.

Теперь, inetd может быть сконфигурирован, чтобы запустить JavaTM Удаленный Вызов метода (Java RMI) службы по требованию. Приложение, однако, должно использовать определенный метод, чтобы позволить тому приложению и его составляющим службам быть запущенным с inetd. Во-первых, служебная программа должна создать локальный реестр, экспортируемый, чтобы использовать сокет ввода-вывода, наследованный от inetd. Служебная программа должна тогда связать прокси службы в этом особенно экспортируемом реестре так, чтобы клиенты могли искать службу. Как только служебная программа полна, inetd может быть сконфигурирован, чтобы запустить эту программу, когда клиент пытается соединиться с локальным реестром службы, чтобы искать службу по имени.

Это учебное руководство сначала описывает, как структурировать служебную программу (использующий особенно экспортируемый локальный реестр) так, чтобы служба могла быть запущена с inetd когда клиенты соединяются с локальным реестром службы.

Затем, учебное руководство описывает, как сконфигурировать inetd запустить служебную программу. Вы должны будете добавить запись в каждый из двух конфигурационных файлов это inetd использование, /etc/inetd.conf и /etc/services. Редактирование этих файлов требует корневого доступа к машине, на которой будет работать служба.

После inetd был реконфигурирован, следует протестировать свою конфигурацию, чтобы удостовериться, что она работает должным образом.

У этого учебного руководства есть следующие шаги:


Реализуйте служебную программу

Реализация серверной стороны использует следующие исходные файлы:

Интерфейс ServiceInterface определяет удаленный интерфейс с помощью единственного метода sendMessage определенный, чтобы взять единственный параметр, message, и возвратите подтверждение, что сообщение было получено.

Класс InitializeRegistry определяет статический служебный метод initializeWithInheritedChannel это создает и экспортирует реестр (использующий наследованный канал, если любой), и обязывает прокси удаленной службы в том реестре для клиентов искать.

Служебная программа Server реализует интерфейс ServiceInterface и определяет помехи main метод для того, чтобы выполнить службу. Помехи main метод делает следующее:

Самая интересная часть реализации находится в initializeWithInheritedChannel служебный метод. Этот метод использует System.inheritedChannel метод, который позволяет приложению получать канал (java.nio.channels.SocketChannel или java.nio.channels.ServerSocketChannel, например) наследованный от процесса, который запустил виртуальную машину. Такой наследованный канал может привыкнуть к любой службе единственное входящее соединение (в случае a SocketChannel), или примите многократные входящие соединения (в случае ServerSocketChannel). Таким образом, приложения, запущенные inetd может получить SocketChannel или ServerSocketChannel наследованный от inetd.

initializeWithInheritedChannel служебный метод сначала вызывает System.inheritedChannel метод, чтобы получить наследованный канал. Наследованный канал должен или быть null или a ServerSocketChannel или метод бросит IOException.

Если наследованный канал null, нет никакого наследованного канала; то есть, программа была выполнена из командной строки. В этом случае, initializeWithInheritedChannel метод просто экспортирует реестр на указанном порту (который должен быть ненулевым), и связывает указанный прокси службы в том реестре.

Если наследованный канал является a ServerSocketChannel экземпляр, тогда программа была запущена от inetd. В этом случае, initializeWithInheritedChannel метод экспортирует реестр с RMIServerSocketFactory чей createServerSocket метод возвращает a ServerSocket это задерживает запросы принятия от наследованного ServerSocketChannel пока указанный прокси не связывается в реестре.

В случае, от которого запускается программа inetd, важно, чтобы реестр не принял любые входящие соединения на наследованном ServerSocket пока прокси службы не связывается в локальном реестре. Если соединение принимается прежде, чем служба связывается в реестре, клиент мог бы получить a java.rmi.NotBoundException от попытки искать прокси службы.

Для получения дополнительной информации на том, как реализовать a ServerSocket это задерживает запросы принятия, пока служба не связывается в реестре, см. частный вложенный класс DelayedAcceptServerSocket определенный в InitializeRegistry класс.

Скомпилируйте служебную программу следующим образом:

% javac -d classDir ServiceInterface.java InitializeRegistry.java Server.java
где classDir является путем к классу для этого примера.

Отметьте, что, если служба должна быть доступной для клиентов, работающих на выпусках ранее чем J2SE 5.0, Вы должны будете использовать rmic генерировать тупик для удаленной службы.

Следующие три раздела описывают, как установить inetd запустить служебную программу.

Сконфигурировать /etc/inetd.conf

/etc/inetd.conf конфигурационный файл содержит записи для служб, которые будут запущены когда inetd получает запрос по сокету. Для получения дополнительной информации на формате этого конфигурационного файла см. Солярис ОС inetd.conf(4) страница справочника.

Сконфигурировать inetd чтобы запустить служебную программу, добавьте следующую запись в /etc/inetd.conf конфигурационный файл (требует корневого доступа к машине):

example-server stream tcp wait nobody jreHome/bin/java  \
     java -classpath classpath example.inetd.Server
где jreHome является путем к установленному JRE, и путь к классу является путем к классу для примера.

Если программа должна быть выполнена как пользователь кроме nobody, замена nobody выше с идентификатором пользователя, под которым должна работать программа.

Сконфигурировать /etc/services

Затем, имя, выбранное, чтобы обратиться к службе, example-server, потребности, которые будут перечислены как сервис в /etc/services конфигурационный файл. Для получения дополнительной информации на формате этого конфигурационного файла см. Солярис ОС services(4) страница справочника.

Перечислять example-server как сервис добавьте следующую запись в /etc/services конфигурационный файл (требует корневого доступа к машине):

example-server        port/tcp
где порт является номером порта для локального реестра службы.

Сила inetd считать его новую конфигурацию

Теперь, когда конфигурация была изменена, inetd потребности считать новую конфигурацию так, чтобы это могло слушать на соответствующих портах для служб, которые конфигурируются.

Но сначала, важно удостовериться, что служебная программа уже не работает. Чтобы сделать это, выполните следующую команду:

% ps -ef | grep example.inetd.Server
Если вышеупомянутая команда не распечатывает информацию для выполнения java процесс для служебной программы, тогда программа не работает. Если это сделает, то Вы должны будете завершить программу сначала перед продолжением.

Затем, inetd потребности считать его новую конфигурацию. Вызвать inetd перечитывать его конфигурацию, выполнение inetd процесс должен быть отправлен сигнал зависания. Во-первых, найдите ID процесса для выполнения inetd процесс, выполняя следующую команду:

% ps -ef | grep inetd
который распечатает что-то вроде этого:
root   171     1  0   Sep 30 ?        0:02 /usr/sbin/inetd -s
В этом примере, ID процесса для inetd 171. Теперь, inetd процесс может быть отправлен сигнал зависания, выполняя следующую команду, и предоставляя ID процесса (требует корневого доступа):
% kill -HUP 171
Теперь, inetd все устанавливается запустить служебную программу, когда клиент пытается соединиться с портом, сконфигурированным выше.

Протестируйте свою конфигурацию, используя простой клиент

Протестировать это inetd конфигурируется должным образом, можно выполнить простую клиентскую программу, которая ищет службу в реестре на порту, сконфигурированном выше, и затем вызывает метод на службу. Попытка соединиться с локальным реестром службы, поочередно, вызовет inetd запустить служебную программу, если конфигурация корректна.

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

package example.inetd;

import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;

public class Client {

    public static void main(String[] args) throws Exception {

        int port = 0;
        String host = "";
        String message = "";
        
        if (args.length > 2) {
            host = args[0];
            try {
                port = Integer.parseInt(args[1]);
                if (port == 0) {
                    goodbye("nonzero port argument required", null);
                }
            } catch (NumberFormatException e) {
                goodbye("malformed port argument", e);
            }
            message = args[2];
        } else {
            usage();
        }

        Registry registry = LocateRegistry.getRegistry(host, port);
        ServiceInterface proxy =
            (ServiceInterface) registry.lookup("ServiceInterface");
        System.out.println("sending message: " + message);
        System.out.println("received message from proxy: " +
                           proxy.sendMessage(message));
        
        System.out.println("done.");
    }

    private static void goodbye(String message, Exception e) {
        System.err.println("Client: " + message + (e != null ? ": " : ""));
        if (e != null) {
            e.printStackTrace();
        }
        System.exit(1);
    }

    private static void usage() {
        System.err.println("Client <host> <port> <message>");
        System.exit(1);
    }
}

Полный источник (включая комментарии) для клиента:

Скомпилируйте и выполните эту программу следующим образом:

% javac -d classDir ServiceInterface.java Client.java
% java -classpath classDir example.inetd.Client host port "message"
то, где classDir является путем к классу для этого примера, узел является узлом, на котором служба конфигурируется, чтобы работать, портировать, является портом, сконфигурированным для службы в /etc/services файл, и сообщение являются строкой, чтобы передаться к службе.

Если клиентская программа распечатывает это, она отправила сообщение и получила сообщение от службы, то служебная программа была успешно запущена inetd.

Если клиентская программа или подвешивает или печатает трассировку исключения, проверьте вывод, произведенный служебной программой. Служебная программа перенаправляет любой вывод, записанный System.err к файлу, расположенному в каталоге, определяется свойством java.io.tmpdir, обычно /var/tmp на Солярисе ОС. Выходной файл снабжается префиксом "сервер в качестве примера, допускают ошибку", и имеет суффикс ".tmp". Имя файла также содержит другие символы (обычно числа) промежуточный, чтобы сохранить имя файла уникальным.

Если служебная программа запускает успешно от inetd, выходной файл должен содержать текст"ready"без предупреждающих сообщений или сообщений об ошибках.

Если файл не существует,"ready"сообщение не находится в файле, или дополнительный вывод ошибок находится в файле, затем перепроверьте конфигурацию. После изменения inetd конфигурация, не забудьте передаваться inetd сигнал зависания так, чтобы это перечитало свою измененную конфигурацию, и не забыло завершать любой процесс, запущенный с предыдущей попытки перед продолжением.


Oracle и/или его филиалы Авторское право © 1993, 2011, Oracle и/или его филиалы. Все права защищены.
Свяжитесь с Нами