Spec-Zone .ru
спецификации, руководства, описания, API
|
inetd
На Операционной системе Соляриса (Солярис ОС), демон Интернет сервисов inetd
обеспечивает альтернативу запуску служб во время начальной загрузки системы. Этот демон, серверный процесс для интернет-служб стандарта, может быть сконфигурирован, чтобы запустить службы по требованию. Для получения дополнительной информации на демоне Интернет сервисов, см. Солярис ОС inetd(1M)
страница справочника.
Теперь, inetd
может быть сконфигурирован, чтобы запустить JavaTM Удаленный Вызов метода (Java RMI) службы по требованию. Приложение, однако, должно использовать определенный метод, чтобы позволить тому приложению и его составляющим службам быть запущенным с inetd
. Во-первых, служебная программа должна создать локальный реестр, экспортируемый, чтобы использовать сокет ввода-вывода, наследованный от inetd
. Служебная программа должна тогда связать прокси службы в этом особенно экспортируемом реестре так, чтобы клиенты могли искать службу. Как только служебная программа полна, inetd
может быть сконфигурирован, чтобы запустить эту программу, когда клиент пытается соединиться с локальным реестром службы, чтобы искать службу по имени.
Это учебное руководство сначала описывает, как структурировать служебную программу (использующий особенно экспортируемый локальный реестр) так, чтобы служба могла быть запущена с inetd
когда клиенты соединяются с локальным реестром службы.
Затем, учебное руководство описывает, как сконфигурировать inetd
запустить служебную программу. Вы должны будете добавить запись в каждый из двух конфигурационных файлов это inetd
использование, /etc/inetd.conf
и /etc/services
. Редактирование этих файлов требует корневого доступа к машине, на которой будет работать служба.
После inetd
был реконфигурирован, следует протестировать свою конфигурацию, чтобы удостовериться, что она работает должным образом.
У этого учебного руководства есть следующие шаги:
/etc/inetd.conf
/etc/services
inetd
считать его новую конфигурациюСерверная реализация использует следующие исходные файлы:
ServiceInterface.java
: отдалите интерфейс для службыInitializeRegistry.java
: утилита, чтобы создать/экспортировать реестр, используя наследованный каналServer.java
: служебная программаServiceInterface
определяет удаленный интерфейс с помощью единственного метода sendMessage
определенный, чтобы взять единственный параметр, message
, и возвратите подтверждение, что сообщение было получено. class InitializeRegistry
определяет статический служебный метод initializeWithInheritedChannel
это создает и экспортирует реестр (использующий наследованный канал, если любой), и обязывает прокси удаленной службы в том реестре для клиентов искать.
Служебная программа Server
реализует интерфейс ServiceInterface
и определяет помехи main
метод для того, чтобы выполнить службу. Помехи main
метод делает следующее:
System.err
вывод к файлу, чтобы препятствовать тому, чтобы вывод ошибок был потерян в случае, с которого запускается служебная программа inetd
.InitializeRegistry.initializeWithInheritedChannel
служебный метод с прокси службы, именем для службы в реестре, и дополнительным номером порта, чтобы использовать, если программа выполняется из командной строки вместо того, чтобы быть запущенной с inetd
.ready
.Самая интересная часть реализации находится в 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
это задерживает запросы принятия, пока служба не связывается в реестре, см. частный вложенный class DelayedAcceptServerSocket
определенный в InitializeRegistry
class.
Скомпилируйте служебную программу следующим образом:
% javac -d classDir ServiceInterface.java InitializeRegistry.java Server.javaгде classDir является путем class для этого примера.
Отметьте, что, если служба должна быть доступной для клиентов, работающих на выпусках ранее чем 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, и путь к классу является путем class для примера.
Если программа должна быть выполнена как пользователь кроме 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); } }
Полный источник (включая комментарии) для клиента:
ServiceInterface.java
: отдалите интерфейс для службыClient.java
: клиентская программаСкомпилируйте и выполните эту программу следующим образом:
% javac -d classDir ServiceInterface.java Client.java % java -classpath classDir example.inetd.Client host port "message"то, где classDir является путем class для этого примера, узел является узлом, на котором служба конфигурируется, чтобы работать, портировать, является портом, сконфигурированным для службы в
/etc/services
файл, и сообщение являются строкой, чтобы передаться к службе. Если клиентская программа распечатывает это, она отправила сообщение и получила сообщение от службы, то служебная программа была успешно запущена inetd
.
Если клиентская программа или подвешивает или печатает трассировку исключения, проверьте вывод, произведенный служебной программой. Служебная программа перенаправляет любой вывод, записанный System.err
к файлу, расположенному в каталоге, определяется свойством java.io.tmpdir
, обычно /var/tmp
на Солярисе ОС. Выходной файл снабжается префиксом "сервер в качестве примера, допускают ошибку", и имеет суффикс ".tmp". Имя файла также содержит другие символы (обычно числа) промежуточный, чтобы сохранить имя файла уникальным.
Если служебная программа запускает успешно от inetd
, выходной файл должен содержать текст"ready
"без предупреждающих сообщений или сообщений об ошибках.
Если файл не существует,"ready
"сообщение не находится в файле, или дополнительный вывод ошибок находится в файле, затем перепроверьте конфигурацию. После изменения inetd
конфигурация, не забудьте передаваться inetd
сигнал зависания так, чтобы это перечитало свою измененную конфигурацию, и не забыло завершать любой процесс, запущенный с предыдущей попытки перед продолжением.