Java-приложение как Windows-сервис
По просьбе камрада Gangsta раскрываю подробности работы NSIS-скрипта, описанного в прошлом топике. В нем было перечислено несколько файлов, входящих в тестовый дистрибутив (install.bat, wrapper.properties) и т.п. Что в них находится и зачем они нужны? С точки зрения изучения возможностей установщика NSIS эта информация избыточна: файлы и файлы, которые могли называться как угодно и содержать что угодно. Главное было — положить их в нужную папку на целевой машине. В отладочных целях в том скрипте не был предусмотрен даже автозапуск самопального install.bat (хотя возможности для этого в NSIS есть).
Однако рассмотренный пример интересен еще и тем, что устанавливает на Windows-компьютер Java-приложение в качестве сервиса, а это весьма ценно. Ведь сервис запускается скрытым для обычного пользователя образом (т.е. на экране не маячит дурацкое черное окно), может выполнять привилегированные операции, его можно перезапускать и останавливать. Как всё это реализовать, если речь идет о Java-приложении (в данном случае — Apache Felix)?
Вообще-то, на затронутую тему я уже писал на Мтааламу. Однако было это в самом начале жизни сайта и материал почти никто не заметил (судя по его рейтингу и количеству комментариев). Да и сам топик был беглый: есть, мол такой проект — Java Service Wrapper, посвященный именно запуску Java приложений в качестве сервисов, причем как под Windows, так и под *NIX. Хорошо, что спустя год появился повод вернуться вернуться к этой теме.
Если вы скачаете дистрибутив Java Service Wrapper, то обнаружите там множество файлов на все случаи жизни: для разных версий Windows и Linux. Из них для запуска сервиса на обычной Windows-XP нужны только три:
* wrapper-windows-x86-32.exe
* wrapper-windows-x86-32.dll
* wrapper.jar
плюс конфигурационный файл, настроив который, вы можете запускать любое консольное Java-приложение, имеющее метод public static void main(String[] args) в виде сервиса. В зависимости от ключей, сервис может быть:
wrapper-windows-x86-32.exe -i
wrapper-windows-x86-32.exe -r
запущен в консольном режиме в целях отладки (без установки в качестве сервиса):
wrapper-windows-x86-32.exe -s
Осталось рассмотреть конфигурационный файл. В случае с Apache Felix он выглядит так:
wrapper.java.command = C:\Program Files\Java\jre6\bin\java wrapper.java.classpath.1 = lib/wrapper.jar wrapper.java.classpath.2 = lib/felix.jar wrapper.java.library.path.1 = lib wrapper.java.mainclass = org.tanukisoftware.wrapper.WrapperSimpleApp wrapper.app.parameter.1 = org.apache.felix.main.Main wrapper.ntservice.name = OSGi wrapper.ntservice.displayname = Служба OSGi (Apache Felix) wrapper.ntservice.description = Служба OSGi (Apache Felix)
По-моему, особые комментарии не требуются. Скажу лишь, что поскольку файл содержит кириллические буквы, желательно сохранить его в кодировке Cp1251, иначе его название в списке сервисов Windows будет крокозябрами. А о том, что всё это работает и сервис действительно появляется в списке, свидетельствует скриншот из старого топика:
Приложение Spring Boot как услуга
В этой статье рассматриваются некоторые варианты запуска приложений Spring Boot в качестве службы.
Во-первых, мы собираемся объяснить варианты упаковки веб-приложений и системные службы. В последующих разделах мы рассмотрим различные альтернативы, которые у нас есть при настройке службы как для Linux, так и для систем на базе Windows.
Наконец, мы закончим некоторыми ссылками на дополнительные источники информации.
2. Инструкции по установке и сборке проекта
2.1. Упаковка
Веб-приложения традиционно упаковываются в архивы веб-приложений (WAR) и развертываются на веб-сервере.
Приложения Spring Boot могут быть упакованы как в файлы WAR, так и в файлы JAR. Последний встраивает веб-сервер в файл JAR, что позволяет запускать приложения без необходимости установки и настройки сервера приложений.
2.2. Конфигурация Maven
Начнем с определения конфигурации нашего файла pom.xml :
packaging>jarpackaging> parent> groupId>org.springframework.bootgroupId> artifactId>spring-boot-starter-parentartifactId> version>1.4.0.RELEASEversion> parent> dependencies> . dependencies> build> plugins> plugin> groupId>org.springframework.bootgroupId> artifactId>spring-boot-maven-pluginartifactId> configuration> executable>trueexecutable> configuration> plugin> plugins> build>
Упаковка должна быть установлена на jar . Мы используем последнюю стабильную версию Spring Boot на момент написания, но будет достаточно любой версии после 1.3. Вы можете найти больше информации о доступных версиях здесь .
Обратите внимание, что мы установили для параметра значение true для артефакта spring-boot-maven-plugin . Это гарантирует, что файл MANIFEST.MF будет добавлен в пакет JAR. Этот манифест содержит запись Main-Class , указывающую, какой класс определяет основной метод для вашего приложения.
2.3. Создание вашего приложения
Запустите следующую команду в корневом каталоге вашего приложения:
$ mvn clean package
Исполняемый файл JAR теперь доступен в целевом каталоге, и мы можем запустить приложение, выполнив следующую команду в командной строке:
$ java -jar your-app.jar
На этом этапе вам все еще нужно вызвать интерпретатор Java с параметром -jar . Есть много причин, по которым было бы предпочтительнее запускать приложение, имея возможность вызывать его как службу.
3. В Linux
Чтобы запустить программу как фоновый процесс, мы могли бы просто использовать команду nohup Unix, но это также не является предпочтительным способом по разным причинам. В этой теме есть хорошее объяснение .
Вместо этого мы собираемся демонизировать наш процесс. В Linux мы можем настроить демон либо с помощью традиционного сценария инициализации System V , либо с помощью файла конфигурации Systemd . Первый традиционно является наиболее известным вариантом, но постепенно вытесняется вторым.
Вы можете найти более подробную информацию об этой разнице здесь .
Для повышения безопасности мы сначала создаем конкретного пользователя для запуска службы и соответствующим образом меняем права доступа к исполняемому JAR-файлу:
$ sudo useradd foreach $ sudo passwd foreach $ sudo chown foreach:foreach your-app.jar $ sudo chmod 500 your-app.jar
3.1. Инициализация системы V
Исполняемый JAR-файл Spring Boot упрощает процесс настройки службы:
$ sudo ln -s /path/to/your-app.jar /etc/init.d/your-app
Приведенная выше команда создает символическую ссылку на ваш исполняемый файл JAR. Вы должны использовать полный путь к исполняемому файлу JAR, иначе символическая ссылка не будет работать должным образом. Эта ссылка позволяет запустить приложение как службу:
$ sudo service your-app start
Скрипт поддерживает стандартные команды запуска , остановки , перезапуска и состояния службы . Более того:
- он запускает службы, работающие под только что созданным пользователем foreach
- он отслеживает идентификатор процесса приложения в /var/run/your-app/your-app.pid
- он записывает журналы консоли в /var/log/your-app.log , которые вы можете проверить на случай, если ваше приложение не запустится должным образом.
3.2. Системд
Настройка службы systemd также очень проста. Во- первых, мы создаем скрипт с именем your-app.service, используя следующий пример, и помещаем его в каталог /etc/systemd/system :
[Unit] Description=A Spring Boot application After=syslog.target [Service] User=foreach ExecStart=/path/to/your-app.jar SuccessExitStatus=143 [Install] WantedBy=multi-user.target
Не забудьте изменить поля Description , User и ExecStart , чтобы они соответствовали вашему приложению. На этом этапе вы также сможете выполнять вышеупомянутые стандартные служебные команды.
В отличие от подхода к инициализации System V , описанного в предыдущем разделе, файл идентификатора процесса и файл журнала консоли должны быть настроены явно с использованием соответствующих полей в сценарии службы. Исчерпывающий список опций можно найти здесь .
3.3. Выскочка
Upstart — это диспетчер служб на основе событий, потенциальная замена System V init , который предлагает больший контроль над поведением различных демонов.
На сайте есть хорошие инструкции по установке , которые подойдут практически для любого дистрибутива Linux. При использовании Ubuntu вы, вероятно, уже установили и настроили его (проверьте, есть ли какие-либо задания с именем, начинающимся с «upstart» в /etc/init ).
Мы создаем задание your-app.conf для запуска нашего приложения Spring Boot:
# Place in /home//.config/upstart description "Some Spring Boot application" respawn # attempt service restart if stops abruptly exec java -jar /path/to/your-app.jar
Теперь запустите «start your-app», и ваш сервис запустится.
Upstart предлагает множество вариантов настройки работы, большинство из них вы можете найти здесь .
4. В Windows
В этом разделе мы представляем несколько вариантов, которые можно использовать для запуска Java JAR в качестве службы Windows.
4.1. Оболочка службы Windows
Из-за трудностей с лицензией GPL Java Service Wrapper (см. следующий подраздел) в сочетании, например, с лицензией MIT Jenkins , был задуман проект Windows Service Wrapper , также известный как winsw .
Winsw предоставляет программные средства для установки/удаления/запуска/остановки службы. Кроме того, его можно использовать для запуска любого исполняемого файла в качестве службы под Windows, тогда как Java Service Wrapper, как следует из его названия, поддерживает только приложения Java.
Во-первых, вы скачиваете бинарники здесь . Затем файл конфигурации, определяющий нашу службу Windows, MyApp.xml , должен выглядеть так:
MyApp MyApp This runs Spring Boot as a Service. java -Xmx256m -jar "%BASE%\MyApp.jar" rotate
Наконец, вы должны переименовать winsw.exe в MyApp.exe , чтобы его имя совпадало с файлом конфигурации MyApp.xml . После этого вы можете установить службу следующим образом:
$ MyApp.exe install
Точно так же вы можете использовать uninstall , start , stop и т. д.
4.2. Оболочка службы Java
Если вы не возражаете против лицензирования GPL проекта Java Service Wrapper , эта альтернатива может одинаково хорошо удовлетворить ваши потребности в настройке файла JAR в качестве службы Windows. По сути, Java Service Wrapper также требует, чтобы вы указали в файле конфигурации, который указывает, как запускать ваш процесс как службу в Windows.
В этой статье очень подробно объясняется, как настроить выполнение JAR-файла в качестве службы в Windows, поэтому нам нет необходимости повторять информацию.
5. Дополнительные ссылки
Приложения Spring Boot также можно запускать как службу Windows с помощью Procrun проекта Apache Commons Daemon . Procrun — это набор приложений, которые позволяют пользователям Windows превращать приложения Java в службы Windows. Такая служба может быть настроена на автоматический запуск при загрузке машины и будет продолжать работать без входа пользователя в систему.
Более подробную информацию о запуске приложений Spring Boot под Unix можно найти здесь . Также есть подробные инструкции по изменению файлов модулей Systemd для систем на основе Redhat. Окончательно
Наконец, это краткое руководство описывает, как включить сценарий Bash в ваш файл JAR, чтобы он сам стал исполняемым файлом!
6. Заключение
Сервисы позволяют вам очень эффективно управлять состоянием вашего приложения, и, как мы видели, настройка сервисов для приложений Spring Boot теперь проще, чем когда-либо.
Просто не забудьте следовать важным и простым мерам безопасности в отношении разрешений пользователей на запуск вашего сервиса.
Делаем java приложение как windows-сервис
В общем, расскажу я вам сказку про Terracota’овский сервер. В одной далёкой галактике На одной из наших виртуалок на конторе, жила-была ВебСфера (прожорливая сволочь), которая голодала от недостатка места на жёстом диске и, как результат, приложения живущие на ней начинали сильно лагать, вследствие чего приходилось часто приходилось ребутать вирталку для нормальной жизни приложений на сфере. Но не одиноки мы во вселенной(возможно), тем не менее на Земле так точно не одни, так и на виртуалке кроме сферы жили и другие монстры, куда менее прожорливые, вроде Terracotta сервера и других приложений. Так вот, вследствие перерождения галактики перезагрузки виртуалки терракотовский сервак постоянно надо было поднимать, так как наши приложения хранящие данные в кластере не могли запуститься, потому ожидали коннекшена от лежачего сервака. Естественно, кому-то из команды постоянно приходилось запускать Терракотту вручную, что, в общем, то было утомительно:). Мною было принято решение создать галактический отряд windows сервис по поднятию сервера после перезагрузки виртуалки, что казалось задачей на 15 минут, и тут я наткнулся на Дарта Вейдера подводные камни. Хренова конечно, что из коробки в терракоте нет создания сервиса после установки.
К делу
- Windows Server 2008 какой-то edition(с установленным Windows Resource Kit Tools).
- Установленная JDK6
- Terracotta
Световые мечи
Пива- srvany.exe – утилита, позволяющая запускать любую программу как службу, позволяя тем самым создавать пользовательские службы(странно но у меня на виртуалке этого файла не было). Скачаваем с инета.
- Знаний использования реестра.(Этот недостатот быстро отпадает)
Для начала скопируем скачанный srvany.exe в папки /bin с терракотой. В моём случае нехватало батника для создания сервиса, т.к. путь к терракоте содержал
пробелы. Если кто знает как в консоли прописывать пути без пробелов, прошу писать в комменты.
Сообственно createService.bat:
sc.exe create Terracotta binPath=“c:\Program Files\terracotta-3.2.1_1\bin\srvany.exe” type=own start=auto DisplayName=“Terracotta Server 3.2.1_1”
Думаю пояснений не требуется. Windows сервис требует данных о приложении в регистре. Создаём tcservice.reg:
REGEDIT4
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Terracotta\Parameters]
«Application»=»\»C:\\Java\\jdk1.6.0_17\\bin\\java.exe\\»
«AppParameters»=»-cp c:\\Program Files\\terracotta-3.2.1_1\\lib\\tc.jar -server -Xms4G –Xmx4G -XX:+HeapDumpOnOutOfMemoryError -Dtc.install-root=c:\\Program files\\terracotta-3.2.1_1 com.tc.server.TCServerMain»
«AppDirectory»=»c:\\Program Files\\terracotta-3.2.1_1\\»
И запускаем его. Не знаю почему, да и в общем то времени на разборку не было, но скрипт у меня не запускался, а данные в регистр не попадали:(. Поэтому делаем всё ручками. Запускаем regedit, заходим по пути HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Terracotta\Parameters и создаём там строковые параметры типа Application с указанием путей типа С:\\Java\\jdk1.6.0_17\\bin\\java.exe Также можно применить дополнительные параметры, если терракота работает не с дефолтовыми настройками:
«AppParameters»=»-cp c:\\ Program Files \\terracotta-3.2.1_1\\lib\\tc.jar -server –Xms512M –Xmx512M -XX:+HeapDumpOnOutOfMemoryError -Dtc.install-root=c:\\terracotta\\terracotta-3.2.1_1 com.tc.server.TCServerMain -f c:\\ Program Files \\my-tc-config.xml -n Server1″
Всё сделали. Тестим заходим в Панель Управления -> Администрирование –> Службы, ищем сервис с названием Terracotta Server 3.2.1_1. Запускаем. Провеяем порты и видим, что приложение стартануло, если нет, проверьте правильность указания путей. Надо бы ещё убедиться что приложение встанет после перезагрузки виртуалки. Значит, что делаем? Выключаем сервер из розетки перезагружаем виртуалку – видим, что сервер поднялся автоматически. Ура. Таким макаром можно любое Java приложение сделать как windows сервис.
Установка приложения Java в качестве службы Windows
Это звучит как то, что вам никогда не понадобится, но иногда, когда вы распространяете программное обеспечение для конечного пользователя, вам может потребоваться установить Java-программу в качестве службы Windows. Мне пришлось это сделать, потому что я разработал инструмент для государственных служащих, который автоматически конвертирует и передает свои файлы Excel на портал opendata своей страны. Инструмент должен периодически запускаться, поэтому он является основным кандидатом на услугу (что сделает загрузку возможной, даже если государственный служащий вообще забудет об этой задаче, и, кроме того, повторная загрузка вручную – пустая трата времени).
Несмотря на многочисленные сообщения и ответы на вопросы stackoverflow по этой теме, мне все равно потребовалось много времени из-за незначительных предостережений и одного важного условия, которое, казалось, имели немногие – наличие JRE в комплекте, так что никто не должен загружать и устанавливать JRE (усложнит процесс установки без необходимости, а целевая аудитория не обязательно будет разбираться в технологиях).
Итак, в проекте maven с jar-упаковкой я сначала подумал об упаковке exe- файла (с launch4j ), а затем о регистрации его в качестве службы. Проблема в том, что Java-программа использует запланированный исполнитель, поэтому она никогда не завершается, что делает невозможным запуск ее как процесса.
Поэтому мне пришлось «демонизировать» его, используя procrun для commons-daemon . Перед этим мне пришлось собрать все необходимые компоненты в одну целевую папку – толстый файл jar (включая все зависимости), JRE, двоичные файлы commons-daemon и файл конфигурации.
Вы можете увидеть полный файл Maven здесь . Соответствующие биты (где $ равен $/target/installer> ):