mengkonfigurasi java daemon dengan systemd

11

Saya menggunakan definisi ini untuk suatu systemdpekerjaan:

 [Unit]
 Description=Some job

 [Service]
 ExecStart=/usr/local/sbin/somejob
 User=dlt
 Type=forking

 [Install]
 WantedBy=multi-user.target

Script yang dipanggil adalah sebagai berikut (memanggil rutin sederhana yang mendengarkan soket tcpip dan menambahkan input ke file):

 #!/bin/sh

 cd /home/user/tmp/testout
 nohup java -jar /home/user/programming/tests/java/core/SocketTest/SocketTest.jar </dev/null >/dev/null &

Setelah systemctl start somejobproses terlihat berjalan, dengan initsebagai induknya:

 user@CANTANDO ~$ ps -u dlt eo pid,ppid,command
   PID  PPID COMMAND
  8718     1 java -jar /home/user/programming/tests/java/core/SocketTest/SocketTest.jar

Setelah melakukan systemctl stop somejobproses tidak muncul lagi (dan port ditutup).

Jadi semuanya tampak baik dan keren

Pertanyaan saya adalah: Apakah ini solusi yang dapat diterima untuk menjalankan daemon java dengan systemd, atau ada peringatan, dan dengan demikian cara lain yang lebih stabil atau aman untuk mencapai ini?

bulu mata
sumber

Jawaban:

14

Berikut beberapa modifikasi kecil:

  1. Karena mendengarkan pada soket jaringan, jadikanlah ketergantungan network.target.
  2. nohuptidak diperlukan karena systemdakan mengubah eksekusi untuk Anda.
  3. Saya pikir skrip shell yang terpisah akan menjadi berlebihan, jadi gabungkan saja ke dalam file layanan.
  4. Redirection ( < /dev/nulldan sebagainya) tidak diperlukan karena systemd menetapkan konteks I / O standar yang sesuai. Memang, jika Anda mengambil redirection out systemd akan mencatat apa pun yang dikirim ke output standar oleh program Java dalam jurnalnya, tanpa diperlukan mekanisme logging khusus.
  5. Menjalankan asynchonously dari shell pemohon ( &) tidak diperlukan atau tidak sesuai.
  6. Ada pola perilaku khusus yang diperlukan oleh Type=forking, dan jika tidak diikuti oleh kesalahan, kesalahan terjadi. Jadi cobalah untuk Type=simple(atau Type=notify).

Jadi file layanannya terlihat seperti ini:

[Unit]
Description=Some job
After=network.target

[Service]
WorkingDirectory=/home/user/tmp/testout
SyslogIdentifier=SocketTest
ExecStart=/bin/sh -c "exec java -jar /home/user/programming/tests/java/core/SocketTest/SocketTest.jar"
User=dlt
Type=simple

[Install]
WantedBy=multi-user.target

Catatan:

  1. Anda tidak bisa hanya menggunakan javanama program untuk dijalankan. systemd tidak mencari PATHexecutable, dan nama executable yang diberikan ExecStartharus absolut. Jadi jika Anda ingin mencari jalan Anda harus memohon melalui shell atau /usr/bin/env. Kami memilih di /bin/shsini.
  2. Karena ini Type=simpleshell harus execJava, tidak menjalankannya sebagai proses anak. systemd mengontrol layanan melalui proses utama, dan itu harus Java, bukan proses shell induk.
  3. Karena ini tidak memanggil Java executable secara langsung, systemd akan memasukkan nama shdalam jurnal sebagai nama layanan. Lihat Cara menghindari / usr / bin / env yang ditandai di log systemd sebagai executable untuk lebih lanjut tentang ini.

Sejauh yang saya tahu, tidak ada peringatan khusus untuk menjalankan aplikasi Java dengan Systemd.

Yun-Chih Chen
sumber
1
Itu tidak akan berhasil. Masalah 1: Ini bukan shell; tidak ada operator pengalihan. Anda sebenarnya tidak menginginkan pengalihan itu. Masalah 2: ExecStart menuntut nama path absolut. Masalah 3: unix.stackexchange.com/questions/229523
JdeBP
Kepala bagus. Saya hanya dapat mengatur untuk memperbaiki masalah 1. Bagaimana cara Anda memperbaiki Prob 2,3?
Yun-Chih Chen
1
Lihat jawabannya sebagai diedit.
JdeBP
Saya tidak berpikir sh diperlukan di sini.
faho
Halo @ Yun-ChihChen bagaimana Anda menghentikan proses. Seperti apa bentuk ExecStrop? Saya telah menggunakan init.d bersama dengan file pid tetapi menemukan ini lebih mudah. Jadi saya perlu memastikan saya tahu bagaimana harus berhenti dll. Terima kasih
black sensei