Додаток Spring Boot як послуга


197

Як правильно налаштувати додаток Spring Boot, упакований як виконувану банку, як сервіс у системі Linux? Це рекомендований підхід, або я повинен перетворити цю програму на війну та встановити в Tomcat?

В даний час я можу запускати додаток Spring для завантаження з screenсеансу, що приємно, але вимагає ручного запуску після перезавантаження сервера.

Що я шукаю, це загальна порада / напрям чи зразок init.dсценарію, якщо мій підхід до виконуваної банки належний.


Для початку, чи розповсюджується ваша дистрибуція на початку чи на системній основі?
yglodt

Відповіді:


138

Наступні роботи для Springboot 1.3 і вище:

Як послуга init.d

Виконана банка має звичайні команди запуску, зупинки, перезавантаження та статусу. Він також встановить PID-файл у звичайній / var / run директорії та ввійде у звичайний / var / log каталог за замовчуванням.

Вам просто потрібно позначити баночку в /etc/init.d так

sudo link -s /var/myapp/myapp.jar /etc/init.d/myapp

АБО

sudo ln -s ~/myproject/build/libs/myapp-1.0.jar /etc/init.d/myapp_servicename

Після цього можна зробити звичайне

/etc/init.d/myapp start

Потім встановіть посилання в будь-якому запуску рівня, який ви хочете, щоб програма запускалася / зупинялася під час завантаження, якщо так хочеться.


Як системна послуга

Для запуску програми Spring Boot, встановленої в var / myapp, ви можете додати наступний скрипт у /etc/systemd/system/myapp.service:

[Unit]
Description=myapp
After=syslog.target

[Service]
ExecStart=/var/myapp/myapp.jar

[Install]
WantedBy=multi-user.target

Примітка: якщо ви використовуєте цей метод, не забудьте зробити сам файл jar виконуваним (з chmod + x), інакше він не вийде з помилкою "Дозвіл відмовлено".

Довідково

http://docs.spring.io/spring-boot/docs/current-SNAPSHOT/reference/html/deployment-install.html#deployment-service


1
Як працює "повністю виконаний JAR" підхід? Я використовую CentOS 6.6. Я додав <executable>true</executable>до свого pom.xml, але упакований файл JAR не виконується (.... ./myapp.jar ... cannot execute binary file)
Абдул

5
Ця відповідь працює лише для поточного етапу 1.3, який ще не вийшов. 1.1 та 1.2 гілки потрібно буде перевірити інші відповіді тут.
voor

6
Чи знаєте ви, хлопці, як передавати такі весняні аргументи -Dspring.profiles.active=prodщодо цих служб? Питання - stackoverflow.com/questions/31242291 / ...
nKognito

2
Я не в змозі зупинити додаток Spring-boot. /etc/init.d stopне зупиняє додаток, його намагаються запустити заново.
tintin

2
Якщо ви хочете , щоб процес моніторингу та перезапустити його , якщо він помре без запису системних демонів перевірити patrickgrimard.com/2014/06/06 / ...
Rux

112

Далі йде найпростіший спосіб встановити додаток Java як системну службу в Linux.

Припустимо, ви використовуєте systemd(що робить сьогодні будь-який сучасний дистрибутив):

По-перше, створіть файл служби з /etc/systemd/systemназвою, наприклад, javaservice.serviceіз цим вмістом:

[Unit]
Description=Java Service

[Service]
User=nobody
# The configuration file application.properties should be here:
WorkingDirectory=/data 
ExecStart=/usr/bin/java -Xmx256m -jar application.jar --server.port=8081
SuccessExitStatus=143
TimeoutStopSec=10
Restart=on-failure
RestartSec=5

[Install]
WantedBy=multi-user.target

По-друге, повідомте systemdпро новий файл служби:

systemctl daemon-reload

і увімкніть його, тому він працює на завантаженні:

systemctl enable javaservice.service

Врешті-решт, ви можете використовувати наступні команди для запуску / зупинки нової послуги:

systemctl start javaservice
systemctl stop javaservice
systemctl restart javaservice
systemctl status javaservice

За умови, що ви використовуєте systemd, це самий не нав'язливий і чистий спосіб налаштування програми Java як системного сервісу.

Що мені особливо подобається у цьому рішенні, це те, що вам не потрібно встановлювати та конфігурувати будь-яке інше програмне забезпечення. Поставлений systemdвиконує всю роботу за вас, і ваша служба поводиться як будь-яка інша системна служба. Я використовую його у виробництві вже деякий час, на різних дистрибутивах, і він просто працює так, як ви очікували.

Ще один плюс полягає в тому, що, використовуючи /usr/bin/java, ви можете легко додати jvmпараметри, такі як -Xmx256m.

Прочитайте також systemdчастину офіційної документації Spring Boot: http://docs.spring.io/spring-boot/docs/current/reference/html/deployment-install.html


На жаль, systemd недоступний для Centos 6
MariuszS

як воно знає, як це зупинити? Записує під, а потім його вбиває?
туман

2
Завдяки Spring Boot 1.3+ ви можете генерувати повністю виконуваний файл війни, тому немає необхідності в Java -jar ... біт, просто використовуйте ім'я файлу там.
П’єр Генрі

1
Я вважаю за краще використовувати повний командний рядок Java, тому що ви можете додавати параметри jvm.
yglodt

1
Для правильної послідовності завантаження ви можете додати заяву замовлення в [Unit]розділ, наприклад After=mysql.service, Before=apache2.service.
іржа

57

Ви також можете використовувати нагляд, який є дуже зручним демоном, за допомогою якого можна легко контролювати послуги. Ці сервіси визначаються простими файлами конфігурації, що визначають, що потрібно виконати, з яким користувачем, у якому каталозі тощо, є мільйони варіантів. supervisord має дуже простий синтаксис, тому він робить дуже гарною альтернативою написання сценаріїв SysV init.

Тут простий файл конфігураційного нагляду для програми, яку ви намагаєтеся запустити / керувати. (помістіть це в /etc/supervisor/conf.d/yourapp.conf )

/etc/supervisor/conf.d/yourapp.conf

[program:yourapp]
command=/usr/bin/java -jar /path/to/application.jar
user=usertorun
autostart=true
autorestart=true
startsecs=10
startretries=3
stdout_logfile=/var/log/yourapp-stdout.log
stderr_logfile=/var/log/yourapp-stderr.log

Для управління додатком вам потрібно буде виконати supervisorctl , який подасть вам підказку, звідки ви можете запустити, зупинити, статус yourapp.

CLI

# sudo supervisorctl
yourapp             RUNNING   pid 123123, uptime 1 day, 15:00:00
supervisor> stop yourapp
supervisor> start yourapp

Якщо supervisordдемон вже запущений, і ви додали конфігурацію для своєї серії, не перезавантажуючи демон, ви можете просто зробитиreread і updateкоманду в supervisorctlоболонці.

Це дійсно дає всі гнучкі можливості, які ви мали б використовувати за допомогою сценаріїв SysV Init, але простий у використанні та керуванні. Погляньте на документацію .


Нарешті щось спрацювало для мене прямо з коробки. Велике спасибі за підказку нагляду.
Віталій Сазанович

Це робить ту саму роботу systemd, що і вбудована в більшість поточних дистрибутивів Linux.
іржа

18

Мені просто доводилося це робити самому, тож далі я опинився з точки зору сценарію контролера служб CentOS init.d. Наразі це працює досить непогано, але я не маю хакера Баша, тому я впевнений, що є місце для вдосконалення, тому думки щодо його вдосконалення вітаються.

Перш за все, у мене є короткий скрипт конфігурації /data/svcmgmt/conf/my-spring-boot-api.shдля кожної служби, який встановлює змінні середовища.

#!/bin/bash
export JAVA_HOME=/opt/jdk1.8.0_05/jre
export APP_HOME=/data/apps/my-spring-boot-api
export APP_NAME=my-spring-boot-api
export APP_PORT=40001

Я використовую CentOS, тому для забезпечення запуску моїх послуг після перезавантаження сервера, у мене є сценарій управління сервісом у /etc/init.d/my-spring-boot-api:

#!/bin/bash
# description: my-spring-boot-api start stop restart
# processname: my-spring-boot-api
# chkconfig: 234 20 80

. /data/svcmgmt/conf/my-spring-boot-api.sh

/data/svcmgmt/bin/spring-boot-service.sh $1

exit 0

Як бачите, він викликає початковий скрипт config для настройки змінних середовища, а потім викликає спільний скрипт, який я використовую для перезавантаження всіх моїх служб Spring Boot. Цей спільний сценарій - це місце, де можна знайти все м'ясо:

#!/bin/bash

echo "Service [$APP_NAME] - [$1]"

echo "    JAVA_HOME=$JAVA_HOME"
echo "    APP_HOME=$APP_HOME"
echo "    APP_NAME=$APP_NAME"
echo "    APP_PORT=$APP_PORT"

function start {
    if pkill -0 -f $APP_NAME.jar > /dev/null 2>&1
    then
        echo "Service [$APP_NAME] is already running. Ignoring startup request."
        exit 1
    fi
    echo "Starting application..."
    nohup $JAVA_HOME/bin/java -jar $APP_HOME/$APP_NAME.jar \
        --spring.config.location=file:$APP_HOME/config/   \
        < /dev/null > $APP_HOME/logs/app.log 2>&1 &
}

function stop {
    if ! pkill -0 -f $APP_NAME.jar > /dev/null 2>&1
    then
        echo "Service [$APP_NAME] is not running. Ignoring shutdown request."
        exit 1
    fi

    # First, we will try to trigger a controlled shutdown using 
    # spring-boot-actuator
    curl -X POST http://localhost:$APP_PORT/shutdown < /dev/null > /dev/null 2>&1

    # Wait until the server process has shut down
    attempts=0
    while pkill -0 -f $APP_NAME.jar > /dev/null 2>&1
    do
        attempts=$[$attempts + 1]
        if [ $attempts -gt 5 ]
        then
            # We have waited too long. Kill it.
            pkill -f $APP_NAME.jar > /dev/null 2>&1
        fi
        sleep 1s
    done
}

case $1 in
start)
    start
;;
stop)
    stop
;;
restart)
    stop
    start
;;
esac
exit 0

Під час зупинки він спробує використовувати Spring Boot Actuator для здійснення керованого відключення. Однак у випадку, якщо привід не налаштований або не вимикається протягом розумних часових рамків (я даю йому 5 секунд, що справді трохи не вистачає), процес буде знищений.

Крім того, сценарій робить припущення, що java-процес, який запускає додаток, буде єдиним із текстом деталей процесу "my-spring-boot-api.jar". Це безпечне припущення в моєму середовищі і означає, що мені не потрібно слідкувати за PID.


3
Не потрібно писати власний сценарій запуску / зупинки. Це передбачено станом на Spring Boot 1.3 і вище. Див. Docs.spring.io/spring-boot/docs/current/reference/htmlsingle/… для отримання більш детальної інформації.
gregturn

Добре знати, що це варіант, але все, що потрібно зробити, це усунути необхідність виконання за допомогою java -jar. Решта сценарію все ще потрібна.
Стів

Дуже корисно, коли /etc/init.d або systemd не є варіантом, дякую за обмін.
Бернардн

@Steve: Ні. Ви винаходите колесо. Ох, і ми зараз пропрацювали.
Мартін Шредер

Коли вам потрібно передати параметри JVM (як -javaagent або -D параметри), це унікальний спосіб, tks @Steve!
Діоргіо

14

Якщо ви хочете використовувати Spring Boot 1.2.5 з модулем Spring Boot Maven Plugin 1.3.0.M2, ось таке рішення:

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>1.2.5.RELEASE</version>
</parent>

<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
            <version>1.3.0.M2</version>
            <configuration>
                <executable>true</executable>
            </configuration>
        </plugin>
    </plugins>
</build>

<pluginRepositories>
    <pluginRepository>
        <id>spring-libs-milestones</id>
        <url>http://repo.spring.io/libs-milestone</url>
    </pluginRepository> 
</pluginRepositories>

Потім компілюйте як ususal:, mvn clean packageзробіть symlink ln -s /.../myapp.jar /etc/init.d/myapp, зробіть його виконуваним chmod +x /etc/init.d/myappі запустіть його service myapp start(з Ubuntu Server)


як щодо запущених файлів WAR? він не працює для мене з ВОЙНОМОГО макетом.
Radu Toader

Цікаво, що це працює з випуском 1.3.0.M2, але при спробі я отримав помилку 1.3.0.RC1.
JBCP

Будь-яка ідея про те, як це зробити з градел замість maven?
Гейр

При використанні Gradle ця конфігурація робиться за допомогою springBoot { executable = true }блоку.
Натікс

@RaduToader: Чи вдалося виконати файл WAR як послугу?
naveenkumarbv

9

Я знаю, що це питання старіше, але я хотів представити ще один спосіб, який є додаток appassembler-maven-plugin . Ось відповідна частина мого POM, яка включає безліч додаткових значень параметрів, які ми вважали корисними:

<plugin>
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>appassembler-maven-plugin</artifactId>
    <configuration>
        <generateRepository>true</generateRepository>
        <repositoryLayout>flat</repositoryLayout>
        <useWildcardClassPath>true</useWildcardClassPath>
        <includeConfigurationDirectoryInClasspath>true</includeConfigurationDirectoryInClasspath>
        <configurationDirectory>config</configurationDirectory>
        <target>${project.build.directory}</target>
        <daemons>
            <daemon>
                <id>${installer-target}</id>
                <mainClass>${mainClass}</mainClass>
                <commandLineArguments>
                    <commandLineArgument>--spring.profiles.active=dev</commandLineArgument>
                    <commandLineArgument>--logging.config=${rpmInstallLocation}/config/${installer-target}-logback.xml</commandLineArgument>
                </commandLineArguments>
                <platforms>
                    <platform>jsw</platform>
                </platforms>
                <generatorConfigurations>
                    <generatorConfiguration>
                        <generator>jsw</generator>
                        <includes>
                            <include>linux-x86-64</include>
                        </includes>
                        <configuration>
                            <property>
                                <name>wrapper.logfile</name>
                                <value>logs/${installer-target}-wrapper.log</value>
                            </property>
                            <property>
                                <name>wrapper.logfile.maxsize</name>
                                <value>5m</value>
                            </property>
                            <property>
                                <name>run.as.user.envvar</name>
                                <value>${serviceUser}</value>
                            </property>
                            <property>
                                <name>wrapper.on_exit.default</name>
                                <value>RESTART</value>
                            </property>
                        </configuration>
                    </generatorConfiguration>
                </generatorConfigurations>
                <jvmSettings>
                    <initialMemorySize>256M</initialMemorySize>
                    <maxMemorySize>1024M</maxMemorySize>
                    <extraArguments>
                        <extraArgument>-server</extraArgument>
                    </extraArguments>
                </jvmSettings>
            </daemon>
        </daemons>
    </configuration>
    <executions>
        <execution>
            <id>generate-jsw-scripts</id>
            <phase>package</phase>
            <goals>
                <goal>generate-daemons</goal>
            </goals>
        </execution>
    </executions>
</plugin>

6

ЯК ВІДНОВА СЛУЖБА

Якщо ви хочете, щоб це запустилося в Windows Machine, завантажте програму winw.exe

 http://repo.jenkins-ci.org/releases/com/sun/winsw/winsw/2.1.2/

Після цього перейменуйте його на ім'я файлу jar (наприклад: your-app .jar)

winsw.exe -> your-app.exe

Тепер створіть xml-файл your-app.xml та скопіюйте до нього наступний вміст

<?xml version="1.0" encoding="UTF-8"?>
<service>
     <id>your-app</id>
     <name>your-app</name>
     <description>your-app as a Windows Service</description>
     <executable>java</executable>
     <arguments>-jar "your-app.jar"</arguments>
     <logmode>rotate</logmode>
</service>

Переконайтесь, що exe та xml разом з баночкою в одній папці.

Після цього відкритого командного рядка у привілеї адміністратора та встановіть його до служби Windows.

your-app.exe install
eg -> D:\Springboot\your-app.exe install

Якщо це не вдається

Error: Registry key 'Software\JavaSoft\Java Runtime Environment'\CurrentVersion' has value '1.8', but '1.7' is required.

Потім спробуйте наступне:

Delete java.exe, javaw.exe and javaws.exe from C:\Windows\System32

Це воно :) .

Щоб видалити службу у Windows

your-app.exe uninstall

Для перегляду / запуску / зупинки послуги: win + r та введіть Адміністративні інструменти, а потім виберіть службу з цього. Потім правою кнопкою миші виберіть варіант - запустити / зупинити


Я дотримувався тих же кроків, щоб запустити весняний завантажувальний jar, як і сервіс Windows в інтранет мережі env, але служба не встає. З'являється вікно із помилкою: Помилка: 1067 Процес несподівано завершився. Чи можете ви допомогти чи підказати, що потрібно зробити?
Нікхіл Сінгх Бхадорія

У вас є всі дозволи на це? Якщо ви адміністратор, це не спричинить жодних проблем. Ви можете, будь ласка, перевірити, чи є у вас права адміністратора.
Арундев

stackoverflow.com/questions/18205111/… Ви можете, будь ласка, спробуйте це, можливо, це допоможе вам вирішити проблему.
Арундев

дякую за швидку відповідь, я розпочав свою роботу і виправив проблему з тегом у файлі xml.
Нікхіл Сінгх Бхадорія

4

Мій сценарій SysVInit для Centos 6 / RHEL (ще не ідеально). Цей скрипт вимагає ApplicationPidListener .

Джерело /etc/init.d/app

#!/bin/sh
#
# app Spring Boot Application 
#
# chkconfig:   345 20 80
# description: App Service
#           

### BEGIN INIT INFO
# Provides: App
# Required-Start: $local_fs $network
# Required-Stop: $local_fs $network
# Default-Start: 3 4 5 
# Default-Stop: 0 1 2 6
# Short-Description: Application
# Description:      
### END INIT INFO

# Source function library.
. /etc/rc.d/init.d/functions

# Source networking configuration.
. /etc/sysconfig/network

exec="/usr/bin/java"
prog="app"
app_home=/home/$prog/
user=$prog

[ -e /etc/sysconfig/$prog ] && . /etc/sysconfig/$prog

lockfile=/var/lock/subsys/$prog    
pid=$app_home/$prog.pid

start() {

    [ -x $exec ] || exit 5
    [ -f $config ] || exit 6
    # Check that networking is up.
    [ "$NETWORKING" = "no" ] && exit 1
    echo -n $"Starting $prog: "
    cd $app_home
    daemon --check $prog --pidfile $pid --user $user $exec $app_args &
    retval=$?
    echo
    [ $retval -eq 0 ] && touch $lockfile
    return $retval
}

stop() {
    echo -n $"Stopping $prog: "
    killproc -p $pid $prog
    retval=$?
    [ $retval -eq 0 ] && rm -f $lockfile
    return $retval
}

restart() {
    stop
    start
}

reload() {
    restart
}

force_reload() {
    restart
}

rh_status() {
    status -p $pid $prog
}

rh_status_q() {
    rh_status >/dev/null 2>&1
}

case "$1" in
    start)
        rh_status_q && exit 0
        $1
        ;;
    stop)
        rh_status_q || exit 0
        $1
        ;;
    restart)
        $1
        ;;
    reload)
        rh_status_q || exit 7
        $1
        ;;
    force-reload)
        force_reload
        ;;
    status)
        rh_status
        ;;
    condrestart|try-restart)
        rh_status_q || exit 0
        restart
        ;;
    *)
        echo $"Usage: $0 {start|stop|status|restart|condrestart|try-restart|reload|force-reload}"
        exit 2
esac
exit $?

Зразок конфігураційного файлу /etc/sysconfig/app:

exec=/opt/jdk1.8.0_05/jre/bin/java

user=myuser
app_home=/home/mysuer/

app_args="-jar app.jar"

pid=$app_home/app.pid

4

Ось сценарій, який розгортає виконуваний jar як системну службу.

Він створює користувача для сервісу та файлу .service, а також розміщує файл jar під / var та робить основне блокування привілеїв.

#!/bin/bash

# Argument: The jar file to deploy
APPSRCPATH=$1

# Argument: application name, no spaces please, used as folder name under /var
APPNAME=$2

# Argument: the user to use when running the application, may exist, created if not exists
APPUSER=$3

# Help text
USAGE="
Usage: sudo $0 <jar-file> <app-name> <runtime-user>
If an app with the name <app-name> already exist, it is stopped and deleted.
If the <runtime-user> does not already exist, it is created.
"

# Check that we are root
if [ ! "root" = "$(whoami)" ]; then
    echo "Must be root. Please use e.g. sudo"
    echo "$USAGE"
    exit
fi

# Check arguments
if [ "$#" -ne 3 -o ${#APPSRCPATH} = 0 -o ${#APPNAME} = 0 -o ${#APPUSER} = 0 ]; then
    echo "Incorrect number of parameters."
    echo "$USAGE"
    exit
fi

if [ ! -f $APPSRCPATH ]; then
    echo "Can't find jar file $APPSRCPATH"
    echo "$USAGE"
    exit
fi

# Infered values
APPFILENAME=$(basename $APPSRCPATH)
APPFOLDER=/var/javaapps/$APPNAME
APPDESTPATH=$APPFOLDER/$APPFILENAME

# Stop the service if it already exist and is running
systemctl stop $APPNAME >/dev/null 2>&1

# Create the app folder, deleting any previous content
rm -fr $APPFOLDER
mkdir -p $APPFOLDER

# Create the user if it does not exist
if id "$APPUSER" >/dev/null 2>&1; then
    echo "Using existing user $APPUSER"
else
    adduser --disabled-password --gecos "" $APPUSER
    echo "Created user $APPUSER"
fi

# Place app in app folder, setting owner and rights
cp $APPSRCPATH $APPDESTPATH
chown $APPUSER $APPDESTPATH
chmod 500 $APPDESTPATH
echo "Added or updated the $APPDESTPATH file"

# Create the .service file used by systemd
echo "
[Unit]
Description=$APPNAME
After=syslog.target
[Service]
User=$APPUSER
ExecStart=/usr/bin/java -jar $APPDESTPATH
SuccessExitStatus=143
[Install]
WantedBy=multi-user.target
" > /etc/systemd/system/$APPNAME.service
echo "Created the /etc/systemd/system/$APPNAME.service file"

# Reload the daemon
systemctl daemon-reload

# Start the deployed app
systemctl start $APPNAME
systemctl status $APPNAME

Приклад: введіть тут опис зображення


4

Я намагаюсь робити програми для Springboot, які представлені у вигляді сценарію оболонки стилю "init.d" із стиснутим додатком Java, який поставлений в кінці

Синхронізуючи ці сценарії від /etc/init.d/spring-app до /opt/spring-app.jar і chmod'ing jar для виконання, можна зробити "/etc/init.d/spring-app start "" /etc/init.d/spring-app stop "та інші можливості, наприклад, робота зі статусом

Імовірно, як сценарії стилю init.d з Springboot виглядають, що вони мають необхідні магічні рядки (наприклад, # Default-Start: 2 3 4 5 ) chkconfig змогли б додати його як "послугу"

Але я хотів змусити його працювати з systemd

Щоб зробити цю роботу, я спробував багато відповідей в інших відповідях вище, але жодна з них не працювала на мене на Centos 7.2 з Springboot 1.3. Вони здебільшого запускали послугу, але не могли відслідковувати pid

Врешті-решт я виявив, що таке спрацювало для мене, коли також існувала посилання /etc/init.d. Файл, подібний до наведеного нижче, повинен бути встановлений як/usr/lib/systemd/system/spring-app.service

[Unit]
Description=My loverly application
After=syslog.target 

[Service]
Type=forking
PIDFile=/var/run/spring-app/spring-app.pid
ExecStart=/etc/init.d/spring-app start
SuccessExitStatus=143

[Install]
WantedBy=multi-user.target

4

Я закінчив робити системну службу для макета WAR / JAR

Я називаю java -jar, оскільки вона більш гнучка. Спробував також поставити ExecStart = spring-mvc.war, але, хоча він є виконуваним, я отримав "Помилка формату Exec"

У будь-якому випадку, systemd присутній на всіх дистрибутивах і пропонує гарне рішення для перенаправлення журналів (syserr важливо, коли ви навіть не запускаєте файл log4j. Місце розташування файлів буде порожнім :)).

cat /etc/systemd/system/spring-mvc.service 
[Unit]
Description=Spring MVC Java Service

[Service]
User=spring-mvc
# The configuration file application.properties should be here:
WorkingDirectory=/usr/local/spring-mvc


# Run ExecStartPre with root-permissions
PermissionsStartOnly=true

ExecStartPre=-/bin/mkdir -p /var/log/spring-mvc


ExecStartPre=/bin/chown -R spring-mvc:syslog /var/log/spring-mvc
ExecStartPre=/bin/chmod -R 775 /var/log/spring-mvc



#https://www.freedesktop.org/software/systemd/man/systemd.service.html#ExecStart=
ExecStart=/usr/bin/java \
        -Dlog4j.configurationFile=log4j2-spring.xml \
        -DLog4jContextSelector=org.apache.logging.log4j.core.async.AsyncLoggerContextSelector \
        -Dspring.profiles.active=dev \
        -Denvironment-type=dev \
        -XX:+UseConcMarkSweepGC \
        -XX:CMSInitiatingOccupancyFraction=80 \
        -XX:NewSize=756m \
        -XX:MetaspaceSize=256m \
        -Dsun.net.inetaddr.ttl=5 \
        -Xloggc:/var/log/spring-mvc/gc.log \
        -verbose:gc \
        -verbosegc \
        -XX:+DisableExplicitGC \
        -XX:+PrintGCDetails \
        -XX:+PrintGCDateStamps \
        -XX:+PreserveFramePointer \
        -XX:+StartAttachListener \
        -Xms1024m \
        -Xmx1024m \
        -XX:+HeapDumpOnOutOfMemoryError \
        -jar spring-mvc.war

SuccessExitStatus=143
StandardOutput=journal
StandardError=journal


KillSignal=SIGINT
TimeoutStopSec=20
Restart=always
RestartSec=5
StartLimitInterval=0
StartLimitBurst=10

LimitNOFILE=500000
LimitNPROC=500000

#https://www.freedesktop.org/software/systemd/man/systemd.exec.html#LimitCPU=
#LimitCPU=, LimitFSIZE=, LimitDATA=, LimitSTACK=, LimitCORE=, LimitRSS=, LimitNOFILE=, LimitAS=, LimitNPROC=, LimitMEMLOCK=, LimitLOCKS=, LimitSIGPENDING=, LimitMSGQUEUE=, LimitNICE=, LimitRTPRIO=, LimitRTTIME=¶

SyslogIdentifier=spring-mvc

[Install]
WantedBy=multi-user.target


# https://www.freedesktop.org/software/systemd/man/journalctl.html
#check logs --- journalctl -u spring-mvc -f -o cat

rsyslog - переадресація вводу syslog з програми в конкретну папку / файл

cat /etc/rsyslog.d/30-spring-mvc.conf 
if $programname == 'spring-mvc' then /var/log/spring-mvc/spring-mvc.log
& stop

логротат

cat /etc/logrotate.d/spring-mvc.conf 
/var/log/spring-mvc/spring-mvc.log
{
    daily
    rotate 30
    maxage 30
    copytruncate
    missingok
    notifempty
    compress
    dateext
    dateformat _%Y-%m-%d_%H-%M
    delaycompress
    create 644 spring-mvc syslog
    su spring-mvc syslog
}

логротат gc

cat /etc/logrotate.d/spring-mvc-gc.conf 
/var/log/spring-mvc/gc.log
{
    daily
    rotate 30
    maxage 30
    copytruncate
    missingok
    notifempty
    compress
    dateext
    dateformat _%Y-%m-%d_%H-%M
    delaycompress
    create 644 spring-mvc syslog
    su spring-mvc syslog
}

3

У цьому питанні відповідь від @PbxMan має розпочати:

Запустіть програму Java як службу в Linux

Редагувати:

Є ще один, менш приємний спосіб запустити процес перезавантаження, використовуючи cron:

@reboot user-to-run-under /usr/bin/java -jar /path/to/application.jar

Це працює, але не дає приємного інтерфейсу для запуску / зупинки для вашої програми. Ви все одно можете просто killвсе одно ...


Не дуже, тому що Spring Boot пропонує спеціальні функції для цього.
Трістан

2

Я не знаю про "стандартний" спосіб, який можна зменшити для роботи з додатком Java, але це, безумовно, хороша ідея (ви хочете скористатися можливостями збереження і моніторингу операційної системи, якщо вони є) . Це на дорожній карті, щоб забезпечити щось із підтримки інструменту Spring Boot (maven і gradle), але наразі вам, мабуть, доведеться скочувати своє. Найкраще рішення, про яке я зараз знаю, - це Foreman , який має декларативний підхід та команду з одним рядком для упаковки сценаріїв init для різних стандартних форматів ОС (monit, sys V, upstart тощо). Є також свідчення того, що люди налаштовували речі з градулами (наприклад, тут ).


2

Ви використовуєте Maven? Потім слід спробувати плагін AppAssembler:

Плагін Application Assembler - це плагін Maven для створення сценаріїв для запуску програм Java. ... Усі артефакти (залежності + артефакт від проекту) додаються до класного шляху в генерованих скриптах бін.

Підтримувані платформи:

Unix-варіанти

Windows NT (Windows 9x НЕ підтримується)

Обслуговувач Java (JSW)

Дивіться: http://mojo.codehaus.org/appassembler/appassembler-maven-plugin/index.html


2

Наступна конфігурація потрібна у файлі build.gradle у проектах Spring Boot.

build.gradle

jar {
    baseName = 'your-app'
    version = version
}

springBoot {
    buildInfo()
    executable = true   
    mainClass = "com.shunya.App"
}

виконуваний = вірно

Це потрібно, щоб зробити повністю виконувану банку в системі Unix (Centos і Ubuntu)

Створіть .conf файл

Якщо ви хочете налаштувати власні властивості JVM або аргументи запуску програми Spring Boot, ви можете створити .conf файл з тим самим іменем, що і назва програми Spring Boot, і розмістити його паралельно файлу jar.

Враховуючи, що ваш app.jar - це назва вашої програми Spring Boot, ви можете створити наступний файл.

JAVA_OPTS="-Xms64m -Xmx64m"
RUN_ARGS=--spring.profiles.active=prod
LOG_FOLDER=/custom/log/folder

Ця конфігурація встановить 64 Мб оперативної пам’яті для програми Spring Boot та активує профіль prod.

Створіть нового користувача в Linux

Для підвищення безпеки ми повинні створити конкретного користувача для запуску програми Spring Boot як сервісу.

Створіть нового користувача

sudo useradd -s /sbin/nologin springboot

У Ubuntu / Debian змініть вищевказану команду так:

sudo useradd -s /usr/sbin/nologin springboot

Встановити пароль

sudo passwd springboot

Зробіть Springboot власником виконуваного файлу

chown springboot:springboot your-app.jar

Запобігати модифікації файлу jar

chmod 500 your-app.jar

Це дозволить налаштувати дозволи jar, щоб їх не можна було записати, а їх може читати чи виконувати лише власник Springboot.

Ви можете необов'язково зробити ваш jar файл незмінним за допомогою команди змінити атрибут (chattr).

sudo chattr +i your-app.jar

Для відповідного файлу .conf слід також встановити відповідні дозволи. .conf вимагає просто доступу для читання (Octal 400) замість доступу для читання + виконання (Octal 500)

chmod 400 your-app.conf

Створіть сервіс Systemd

/etc/systemd/system/your-app.service

[Unit]
Description=Your app description
After=syslog.target

[Service]
User=springboot
ExecStart=/var/myapp/your-app.jar
SuccessExitStatus=143

[Install]
WantedBy=multi-user.target

Автоматично перезапустити процес, якщо він загине ОС

Додайте нижче два атрибути (Restart і RestartSec), щоб автоматично перезапустити процес у разі відмови.

/etc/systemd/system/your-app.service

[Service]
User=springboot
ExecStart=/var/myapp/your-app.jar
SuccessExitStatus=143
Restart=always
RestartSec=30

Ця зміна призведе до перезапуску програми Spring Boot у разі відмови із затримкою на 30 секунд. Якщо ви припините послугу за допомогою команди systemctl, то перезапуск не відбудеться.

Служба розкладу при запуску системи

Щоб позначити додаток для автоматичного запуску під час завантаження системи, використовуйте таку команду:

Увімкнути програму Spring Boot при запуску системи

sudo systemctl enable your-app.service

Почніть зупинку служби

systemctl можна використовувати в Ubuntu 16.04 LTS та 18.04 LTS для запуску та зупинки процесу.

Почніть процес

sudo systemctl start your-app

Зупиніть процес

sudo systemctl stop your-app

Список літератури

https://docs.spring.io/spring-boot/docs/current/reference/html/deployment-install.html


1

Слідкуйте за відмінною відповіддю Чада, якщо ви отримаєте помилку "Помилка: не вдалося знайти або завантажити основний клас" - і ви витрачаєте пару годин на те, щоб усунути неполадки, чи виконує ваш скрипт оболонки, який запускає додаток java, або запускає його від самого systemd - і ви знаєте, що ваш classpath правильний на 100%, наприклад, вручну запускається скрипт оболонки, а також виконується те, що у вас є в systemd execstart. Будьте впевнені, ви керуєте речами як правильний користувач! У моєму випадку я спробував різних користувачів, після досить довгого усунення несправностей - я, нарешті, мав уявлення, поставив root як користувач - вуаля, програма запустилася правильно. Після того як я визначив, що це помилка користувача, яchown -R user:user папка та підпапки та додаток працювали правильно як вказаний користувач та група, тому більше не потрібно запускати його як root (погана безпека).


1

У файлах системних одиниць можна встановити каталог змінних оточення або через EnvironmentFile. Я б запропонував робити такі дії, оскільки, здається, це найменша кількість тертя.

Зразок одиничного файлу

$ cat /etc/systemd/system/hello-world.service
[Unit]
Description=Hello World Service
After=systend-user-sessions.service

[Service]
EnvironmentFile=/etc/sysconfig/hello-world
Type=simple
ExecStart=/usr/bin/java ... hello-world.jar

Потім встановіть файл, під /etc/sysconfig/hello-worldяким містяться великі назви змінних Spring Boot. Наприклад, названа змінна server.portбуде слідувати формі SERVER_PORTяк змінна середовища:

$ cat /etc/sysconfig/hello-world
SERVER_PORT=8081

Тут використовується механізм, що програми Spring Boot приймуть список властивостей, а потім переведуть їх, зробивши все великі регістри та замінивши крапки підкресленнями. Після того, як додаток Spring Boot проходить цей процес, він шукає змінні середовища, які відповідають, і використовує будь-які знайдені відповідно.

Це більш детально висвітлено в цьому запитанні щодо запитань: Як встановити властивість Spring Boot з підкресленням у назві за допомогою змінних середовища?

Список літератури


1

Це можна зробити за допомогою сервісу Systemd в Ubuntu

[Unit]
Description=A Spring Boot application
After=syslog.target

[Service]
User=baeldung
ExecStart=/path/to/your-app.jar SuccessExitStatus=143

[Install] 
WantedBy=multi-user.target

Ви можете перейти за цим посиланням для більш детального опису та різних способів зробити це. http://www.baeldung.com/spring-boot-app-as-a-service


1

Створіть сценарій з назвою your-app.service (rest-app.service). Ми повинні розмістити цей скрипт у / etc / systemd / system directory. Ось зразок вмісту сценарію

[Unit]
Description=Spring Boot REST Application
After=syslog.target

[Service]
User=javadevjournal
ExecStart=/var/rest-app/restdemo.jar
SuccessExitStatus=200

[Install]
WantedBy=multi-user.target

Далі:

 service rest-app start

Список літератури

введіть опис посилання тут


Виглядає так само , як це -> stackoverflow.com/a/30497095/516167
MariuszS
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.