Aplikasi Spring Boot sebagai Layanan

197

Bagaimana cara mengkonfigurasi aplikasi Spring Boot yang dikemas sebagai jar yang dapat dieksekusi sebagai Layanan dalam sistem linux? Apakah ini pendekatan yang disarankan, atau haruskah saya mengubah aplikasi ini untuk berperang dan menginstal ke Tomcat?

Saat ini saya dapat menjalankan aplikasi boot Spring dari screensesi, apa yang baik, tetapi memerlukan mulai manual setelah server reboot.

Apa yang saya cari adalah saran / arahan umum atau init.dskrip sampel , jika pendekatan saya dengan jar yang dapat dieksekusi tepat.

MariuszS
sumber
Untuk memulai, apakah distribusi Anda menggunakan pemula atau systemd?
yglodt

Jawaban:

138

Karya-karya berikut untuk springboot 1.3 dan di atasnya:

Sebagai layanan init.d

Jar yang dapat dieksekusi memiliki perintah mulai, berhenti, restart, dan status yang biasa. Ini juga akan mengatur file PID di direktori / var / run biasa dan masuk ke direktori / var / log biasa secara default.

Anda hanya perlu menghubungkan botol Anda ke /etc/init.d seperti itu

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

ATAU

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

Setelah itu Anda bisa melakukan hal yang biasa

/etc/init.d/myapp start

Kemudian siapkan tautan di mana pun runlevel yang Anda inginkan aplikasi mulai / berhenti saat boot jika diinginkan.


Sebagai layanan systemd

Untuk menjalankan aplikasi Spring Boot yang terinstal di var / myapp Anda dapat menambahkan skrip berikut di /etc/systemd/system/myapp.service:

[Unit]
Description=myapp
After=syslog.target

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

[Install]
WantedBy=multi-user.target

NB: jika Anda menggunakan metode ini, jangan lupa untuk membuat file jar sendiri dapat dieksekusi (dengan chmod + x) jika tidak maka akan gagal dengan kesalahan "Izin ditolak".

Referensi

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

chad
sumber
1
Bagaimana cara kerja "JAR yang sepenuhnya dapat dieksekusi" bekerja? Saya menggunakan CentOS 6.6. Saya menambahkan <executable>true</executable>ke saya pom.xml, tetapi file JAR yang dipaket tidak menjalankan (.... ./myapp.jar ... cannot execute binary file)
Abdull
5
Jawaban ini hanya berfungsi untuk Milestone 1.3 saat ini, yang belum dirilis. Cabang 1.1 dan 1.2 perlu memeriksa tanggapan lain di sini.
voor
6
Apakah Anda tahu orang-orang cara menyampaikan argumen pegas seperti -Dspring.profiles.active=prodke layanan ini? Pertanyaan - stackoverflow.com/questions/31242291/…
nKognito
2
Saya tidak dapat menghentikan aplikasi spring-boot. /etc/init.d stoptidak menghentikan aplikasi, itu mencoba untuk memulainya lagi.
tintin
2
Jika Anda ingin memantau proses dan memulai kembali jika ia mati tanpa sistem daemon, periksa patrickgrimard.com/2014/06/06/…
ruX
112

Berikut ini adalah cara termudah untuk menginstal aplikasi Java sebagai layanan sistem di Linux.

Mari kita asumsikan Anda menggunakan systemd(yang dilakukan oleh distro modern mana pun saat ini):

Pertama, buat file layanan dengan /etc/systemd/systemnama misalnya javaservice.servicedengan konten ini:

[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

Kedua, beri tahu systemdfile layanan baru:

systemctl daemon-reload

dan aktifkan, sehingga berjalan saat boot:

systemctl enable javaservice.service

Akhirnya, Anda dapat menggunakan perintah berikut untuk memulai / menghentikan layanan baru Anda:

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

Asalkan Anda menggunakan systemd , ini adalah cara yang paling tidak mengganggu dan bersih untuk mengatur aplikasi Java sebagai layanan sistem.

Apa yang saya sukai terutama tentang solusi ini adalah kenyataan bahwa Anda tidak perlu menginstal dan mengkonfigurasi perangkat lunak lain. Dikirimsystemd mengerjakan semua pekerjaan untuk Anda, dan layanan Anda berperilaku seperti layanan sistem lainnya. Saya menggunakannya dalam produksi untuk sementara waktu sekarang, pada distro yang berbeda, dan hanya berfungsi seperti yang Anda harapkan.

Kelebihan lainnya adalah, dengan menggunakan /usr/bin/java, Anda dapat dengan mudah menambahkanjvm parameter seperti -Xmx256m.

Baca juga systemdbagian dalam dokumentasi Boot Musim Semi resmi: http://docs.spring.io/spring-boot/docs/current/reference/html/deployment-install.html

yglodt
sumber
Sayangnya systemd tidak tersedia untuk Centos 6
MariuszS
bagaimana ia tahu bagaimana menghentikannya? Merekam pid dan kemudian membunuhnya?
Kabut
2
Dengan Spring Boot 1.3+ Anda dapat menghasilkan file perang yang sepenuhnya dapat dieksekusi, jadi tidak perlu untuk java -jar ... bit, cukup gunakan nama file di sana.
Pierre Henry
1
Saya lebih suka menggunakan commandline java penuh karena dengan cara itu Anda dapat menambahkan parameter jvm.
yglodt
1
Untuk urutan boot yang tepat Anda mungkin ingin menambahkan pernyataan memesan ke [Unit]bagian, misalnya After=mysql.service, Before=apache2.service.
rustyx
57

Anda juga dapat menggunakan supervisord yang merupakan daemon yang sangat berguna, yang dapat digunakan untuk mengontrol layanan dengan mudah. Layanan ini ditentukan oleh file konfigurasi sederhana yang menentukan apa yang harus dijalankan dengan pengguna mana di direktori mana dan sebagainya, ada banyak pilihan. supervisord memiliki sintaks yang sangat sederhana, jadi itu membuat alternatif yang sangat baik untuk menulis skrip init SysV.

Di sini file konfigurasi supervisord sederhana untuk program yang Anda coba jalankan / kontrol. (masukkan ini ke /etc/supervisor/conf.d/yapp.conf Anda )

/etc/supervisor/conf.d/yappapp.conf Anda

[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

Untuk mengontrol aplikasi, Anda perlu menjalankan supervisorctl , yang akan memberi Anda prompt di mana Anda bisa memulai, menghentikan, status aplikasi Anda.

CLI

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

Jika supervisorddaemon sudah berjalan dan Anda telah menambahkan konfigurasi untuk serivce Anda tanpa me-restart daemon, Anda cukup melakukan rereaddan updatememerintahkan disupervisorctl shell.

Ini benar-benar memberi Anda semua flexibilites yang Anda miliki menggunakan skrip SysV Init, tetapi mudah digunakan dan dikontrol. Lihatlah dokumentasinya .

flazzarini
sumber
Akhirnya sesuatu berhasil untuk saya di luar kotak. Terima kasih banyak atas petunjuk supervisor.
Vitaly Sazanovich
Ini melakukan pekerjaan yang sama dengan systemd, yang dibangun di sebagian besar distro Linux saat ini.
rustyx
18

Saya baru saja melakukan ini sendiri, jadi berikut ini adalah di mana saya sejauh ini dalam hal script pengontrol layanan CentOS init.d. Sejauh ini bekerja dengan baik, tapi saya bukan hacker Bash, jadi saya yakin ada ruang untuk perbaikan, jadi pemikiran untuk memperbaikinya dipersilahkan.

Pertama-tama, saya memiliki skrip konfigurasi pendek /data/svcmgmt/conf/my-spring-boot-api.shuntuk setiap layanan, yang mengatur variabel lingkungan.

#!/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

Saya menggunakan CentOS, jadi untuk memastikan bahwa layanan saya dimulai setelah server restart, saya memiliki skrip kontrol layanan di /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

Seperti yang Anda lihat, itu memanggil skrip konfigurasi awal untuk mengatur variabel lingkungan dan kemudian memanggil skrip bersama yang saya gunakan untuk memulai kembali semua layanan Boot Musim Semi saya. Naskah yang dibagikan itu adalah tempat dagingnya semuanya dapat ditemukan:

#!/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

Saat berhenti, ia akan mencoba menggunakan Spring Boot Actuator untuk melakukan shutdown yang terkontrol. Namun, jika Actuator tidak dikonfigurasi atau gagal dimatikan dalam kerangka waktu yang masuk akal (saya berikan 5 detik, yang sebenarnya agak pendek), prosesnya akan mati.

Selain itu, skrip membuat asumsi bahwa proses java menjalankan aplikasi akan menjadi satu-satunya dengan "my-spring-boot-api.jar" dalam teks rincian proses. Ini adalah asumsi yang aman di lingkungan saya dan berarti bahwa saya tidak perlu melacak PID.

Steve
sumber
3
Tidak perlu menulis skrip start / stop Anda sendiri. Ini disediakan pada Spring Boot 1.3 dan lebih tinggi. Lihat docs.spring.io/spring-boot/docs/current/reference/htmlsingle/… untuk lebih jelasnya.
gregturn
Senang mengetahui bahwa itu merupakan opsi, tetapi yang dilakukannya hanyalah menghilangkan kebutuhan untuk mengeksekusi menggunakan java -jar. Sisa skrip masih diperlukan.
Steve
Sangat berguna untuk saat /etc/init.d atau systemd bukan pilihan, terima kasih sudah berbagi.
bernardn
@Steve: Tidak. Anda sedang menciptakan kembali roda. Oh, dan kami memiliki systemd sekarang.
Martin Schröder
Ketika Anda perlu meneruskan parameter ke JVM (seperti parameter -javaagent atau -D) ini adalah cara unik, tks @Steve!
Dyorgio
14

Jika Anda ingin menggunakan Spring Boot 1.2.5 dengan Spring Boot Maven Plugin 1.3.0.M2, berikut solusinya:

<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>

Kemudian kompilasi sebagai ususal: mvn clean package buat symlink ln -s /.../myapp.jar /etc/init.d/myapp, buat itu dapat dieksekusi, chmod +x /etc/init.d/myappdan jalankan service myapp start(dengan Ubuntu Server)

Benjamin M
sumber
bagaimana dengan file WAR yang dapat dijalankan? itu tidak berfungsi untuk saya dengan tata letak PERANG.
Radu Toader
Menariknya ini bekerja dengan rilis 1.3.0.M2, tetapi saya mendapat kesalahan ketika saya mencoba 1.3.0.RC1.
JBCP
Adakah ide tentang bagaimana melakukan ini dengan gradle bukan maven?
Geir
Saat menggunakan Gradle, konfigurasi ini dilakukan dengan menggunakan springBoot { executable = true }blok.
Natix
@RaduToader: Apakah Anda dapat menjalankan file WAR sebagai layanan?
naveenkumarbv
9

Saya tahu ini adalah pertanyaan yang lebih lama, tetapi saya ingin menyajikan cara lain yaitu appassembler-maven-plugin . Inilah bagian yang relevan dari POM saya yang mencakup banyak nilai opsi tambahan yang kami temukan berguna:

<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>
tidak
sumber
6

SEBAGAI LAYANAN WINDOWS

Jika Anda ingin ini dijalankan di mesin windows, unduh winsw.exe dari

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

Setelah itu ganti namanya menjadi toples nama file (mis .: aplikasi-Anda .jar)

winsw.exe -> your-app.exe

Sekarang buat file xml -app.xml Anda dan salin konten berikut ke sana

<?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>

Pastikan bahwa exe dan xml bersama dengan toples di folder yang sama.

Setelah perintah terbuka ini muncul di Administrator previlege dan instal ke layanan windows.

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

Jika gagal dengan

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

Kemudian coba yang berikut ini:

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

itu dia :) .

Untuk menghapus layanan di windows

your-app.exe uninstall

Untuk melihat / menjalankan / menghentikan layanan: win + r dan ketik Alat administratif kemudian pilih layanan dari itu. Kemudian klik kanan pilih opsi - run / stop

Arundev
sumber
Saya telah mengikuti langkah-langkah yang sama untuk menjalankan spring boot jar sebagai layanan windows di intranet env perusahaan, tetapi layanannya tidak bangun. Ada jendela yang keluar dengan kesalahan: Kesalahan: 1067 Proses dihentikan tiba-tiba Bisakah Anda membantu atau menyarankan apa yang harus dilakukan?
Nikhil Singh Bhadoriya
Apakah Anda memiliki semua izin untuk melakukan itu? Jika Anda seorang administrator, ini tidak akan menyebabkan masalah. Bisakah Anda periksa apakah Anda memiliki hak administrator.
Arundev
stackoverflow.com/questions/18205111/… dapatkah kamu coba ini mungkin ini akan membantu kamu untuk menyelesaikan masalah.
Arundev
terima kasih atas tanggapan cepatnya, saya menjalankan dan menjalankan layanan dengan memperbaiki masalah dengan tag dalam file xml.
Nikhil Singh Bhadoriya
4

Skrip SysVInit saya untuk Centos 6 / RHEL (belum ideal). Script ini membutuhkan ApplicationPidListener .

Sumber dari /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 $?

Contoh file konfigurasi /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
MariuszS
sumber
4

Berikut ini adalah skrip yang menggunakan jar yang dapat dieksekusi sebagai layanan systemd.

Itu menciptakan pengguna untuk layanan dan file .service, dan menempatkan file jar di bawah / var, dan membuat beberapa kunci dasar hak istimewa.

#!/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

Contoh: masukkan deskripsi gambar di sini

Pengguna0
sumber
4

Saya mencoba membuat aplikasi springboot yang disajikan sebagai skrip shell gaya "init.d" dengan aplikasi java terkompresi yang ditempel di bagian akhir

Dengan menyinkronkan skrip-skrip ini dari /etc/init.d/spring-app ke /opt/spring-app.jar dan chmod'ing jar agar dapat dieksekusi, dimungkinkan untuk membuat "/etc/init.d/spring-app mulai "" /etc/init.d/spring-app stop "dan kemungkinan lain seperti pekerjaan status

Agaknya, sebagai skrip gaya init.d dari springboot terlihat bahwa mereka memiliki string ajaib yang diperlukan (seperti # Default-Start: 2 3 4 5 ) chkconfig akan dapat menambahkannya sebagai "layanan"

Tetapi saya ingin membuatnya bekerja dengan systemd

Untuk membuat ini berhasil, saya mencoba banyak penerima di jawaban lain di atas tetapi tidak ada yang bekerja untuk saya di Centos 7.2 dengan Springboot 1.3 Sebagian besar mereka akan memulai layanan tetapi tidak dapat melacak pid

Pada akhirnya saya menemukan hal berikut ini berfungsi untuk saya, ketika tautan /etc/init.d berada di tempat juga. File yang mirip dengan yang di bawah ini harus diinstal sebagai/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
Vorsprung
sumber
4

Saya akhirnya melakukan layanan systemd untuk tata letak WAR / JAR

Saya memanggil java -jar karena lebih fleksibel. Mencoba juga meletakkan ExecStart = spring-mvc.war tetapi meskipun dapat dieksekusi, saya mendapat 'Exec format error'

Pokoknya hari ini, systemd hadir di semua distro, dan menawarkan solusi yang bagus untuk mengarahkan ulang log (syserr penting ketika layanan Anda bahkan tidak memulai lokasi file log4j akan kosong :)).

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 - redirect input syslog dari aplikasi ke folder / file tertentu

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

logrotate

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
}

logrotate 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
}
Radu Toader
sumber
3

Dalam pertanyaan ini, jawaban dari @PbxMan akan membantu Anda memulai:

Jalankan Aplikasi Java sebagai Layanan di Linux

Edit:

Ada cara lain yang kurang bagus untuk memulai proses reboot, menggunakan cron:

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

Ini berfungsi, tetapi tidak memberi Anda antarmuka awal / berhenti yang bagus untuk aplikasi Anda. Anda masih bisa tetap killmelakukannya ...

yglodt
sumber
Tidak juga, karena Spring Boot menawarkan fitur-fitur khusus untuk melakukan ini.
Tristan
2

Saya tidak tahu cara "standar" untuk melakukan itu dengan aplikasi Java, tapi itu ide yang bagus (Anda ingin mendapat manfaat dari kemampuan sistem operasi yang tetap hidup dan pemantauan jika ada) . Ada di peta jalan untuk memberikan sesuatu dari dukungan alat Boot Spring (pakar dan gradasi), tetapi untuk sekarang Anda mungkin harus memutar sendiri. Solusi terbaik yang saya tahu saat ini adalah Foreman , yang memiliki pendekatan deklaratif dan perintah satu baris untuk mengemas skrip init untuk berbagai format OS standar (monit, sys V, pemula dll). Ada juga bukti orang-orang telah mengatur barang-barang dengan gradle (misalnya di sini ).

Dave Syer
sumber
2

Apakah Anda menggunakan Maven? Maka Anda harus mencoba Plugin AppAssembler:

Plugin Application Assembler adalah plugin Maven untuk menghasilkan skrip untuk memulai aplikasi java. ... Semua artefak (dependensi + artefak dari proyek) ditambahkan ke classpath dalam skrip bin yang dihasilkan.

Platform yang didukung:

Unix-varian

Windows NT (Windows 9x TIDAK didukung)

Java Service Wrapper (JSW)

Lihat: http://mojo.codehaus.org/appassembler/appassembler-maven-plugin/index.html

d0x
sumber
2

Konfigurasi berikut diperlukan dalam file build.gradle di proyek Boot Spring.

build.gradle

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

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

executable = true

Ini diperlukan untuk membuat jar yang sepenuhnya dapat dieksekusi pada sistem unix (Centos dan Ubuntu)

Buat file .conf

Jika Anda ingin mengkonfigurasi properti JVM kustom atau argumen menjalankan aplikasi Boot Spring, maka Anda dapat membuat file .conf dengan nama yang sama dengan nama aplikasi Boot Spring dan menempatkannya sejajar dengan file jar.

Mengingat app-jar Anda adalah nama aplikasi Boot Musim Semi Anda, maka Anda dapat membuat file berikut.

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

Konfigurasi ini akan mengatur ram 64 MB untuk aplikasi Spring Boot dan mengaktifkan profil prod.

Buat pengguna baru di linux

Untuk meningkatkan keamanan, kita harus membuat pengguna tertentu untuk menjalankan aplikasi Spring Boot sebagai layanan.

Buat pengguna baru

sudo useradd -s /sbin/nologin springboot

Di Ubuntu / Debian, modifikasi perintah di atas sebagai berikut:

sudo useradd -s /usr/sbin/nologin springboot

Setel kata sandi

sudo passwd springboot

Buat pemilik springboot dari file yang dapat dieksekusi

chown springboot:springboot your-app.jar

Cegah modifikasi file jar

chmod 500 your-app.jar

Ini akan mengonfigurasi izin jar sehingga tidak dapat ditulis dan hanya dapat dibaca atau dieksekusi oleh springboot pemiliknya.

Secara opsional Anda dapat membuat file jar Anda sebagai tidak dapat diubah menggunakan perintah ubah atribut (chattr).

sudo chattr +i your-app.jar

Izin yang tepat juga harus ditetapkan untuk file .conf yang sesuai. .conf membutuhkan akses hanya baca (Oktal 400) alih-alih akses baca + eksekusi (Oktal 500)

chmod 400 your-app.conf

Buat layanan 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

Mulai ulang proses secara otomatis jika terbunuh oleh OS

Tambahkan dua atribut di bawah ini (Restart dan RestartSec) untuk memulai kembali proses kegagalan secara otomatis.

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

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

Perubahan ini akan membuat aplikasi Spring Boot restart jika terjadi kegagalan dengan penundaan 30 detik. Jika Anda menghentikan layanan menggunakan perintah systemctl maka restart tidak akan terjadi.

Jadwalkan layanan di startup sistem

Untuk menandai aplikasi agar mulai secara otomatis saat boot sistem, gunakan perintah berikut:

Aktifkan aplikasi Spring Boot saat startup sistem

sudo systemctl enable your-app.service

Mulai Stop Layanan

systemctl dapat digunakan di Ubuntu 16.04 LTS dan 18.04 LTS untuk memulai dan menghentikan proses.

Mulai prosesnya

sudo systemctl start your-app

Hentikan prosesnya

sudo systemctl stop your-app

Referensi

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

ismael
sumber
1

Menindaklanjuti jawaban Chad yang sangat baik, jika Anda mendapatkan kesalahan "Kesalahan: Tidak dapat menemukan atau memuat kelas utama" - dan Anda menghabiskan beberapa jam mencoba memecahkan masalah, apakah Anda menjalankan skrip shell yang memulai aplikasi java Anda atau memulainya dari systemd sendiri - dan Anda tahu classpath Anda 100% benar, misalnya menjalankan skrip shell secara manual dan menjalankan apa yang Anda miliki di systemd execstart. Pastikan Anda menjalankan sesuatu sebagai pengguna yang benar! Dalam kasus saya, saya telah mencoba pengguna yang berbeda, setelah beberapa saat pemecahan masalah - saya akhirnya punya firasat, meletakkan root sebagai pengguna - voila, aplikasi dimulai dengan benar. Setelah menentukan itu adalah masalah pengguna yang salah, sayachown -R user:user folder dan subfolder dan aplikasi berjalan dengan benar sebagai pengguna dan grup yang ditentukan sehingga tidak perlu lagi menjalankannya sebagai root (keamanan buruk).

JGlass
sumber
1

Dalam file unit systemd Anda dapat mengatur direktori variabel lingkungan atau melalui EnvironmentFile. Saya akan mengusulkan melakukan hal-hal seperti ini karena tampaknya merupakan jumlah gesekan paling sedikit.

File unit sampel

$ 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

Kemudian, atur file /etc/sysconfig/hello-worldyang menyertakan nama huruf besar dari variabel Boot Spring Anda. Misalnya, variabel yang dipanggil server.portakan mengikuti formulir SERVER_PORTsebagai variabel lingkungan:

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

Mekanisme yang dieksploitasi di sini adalah bahwa aplikasi Boot Spring akan mengambil daftar properti dan kemudian menerjemahkannya, membuat semuanya huruf besar, dan mengganti titik-titik dengan garis bawah. Setelah aplikasi Boot Spring melewati proses ini, ia kemudian mencari variabel lingkungan yang cocok, dan menggunakan yang ditemukan sesuai.

Ini disorot secara lebih rinci dalam T&J SO yang berjudul: Bagaimana mengatur properti Spring Boot dengan garis bawah pada namanya melalui Variabel Lingkungan?

Referensi

slm
sumber
1

Itu dapat dilakukan dengan menggunakan layanan Systemd di 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

Anda dapat mengikuti tautan ini untuk deskripsi yang lebih terperinci dan berbagai cara untuk melakukannya. http://www.baeldung.com/spring-boot-app-as-a-service

mujeeb rahman
sumber
1

Buat skrip dengan nama your-app.service (rest-app.service). Kita harus menempatkan skrip ini di direktori / etc / systemd / system. Berikut adalah contoh konten skrip

[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

Lanjut:

 service rest-app start

Referensi

masukkan deskripsi tautan di sini

ismael
sumber
Terlihat sama seperti ini -> stackoverflow.com/a/30497095/516167
MariuszS