กำหนดค่า java daemon ด้วย systemd


11

ฉันกำลังใช้คำจำกัดความนี้สำหรับsystemdงาน:

 [Unit]
 Description=Some job

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

 [Install]
 WantedBy=multi-user.target

สคริปต์ถูกเรียกใช้ดังต่อไปนี้ (การเรียกรูทีนแบบง่ายที่ฟังบนซ็อกเก็ต tcpip และผนวกอินพุตกับไฟล์):

 #!/bin/sh

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

หลังจากsystemctl start somejobกระบวนการแสดงว่ากำลังทำงานพร้อมกับพาเรนต์init:

 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

หลังจากดำเนินการsystemctl stop somejobตามกระบวนการจะไม่ปรากฏอีกต่อไป (และปิดพอร์ต)

ดังนั้นทุกอย่างจึงดูดีและสวยงาม

คำถามของฉันคือ: นี่เป็นวิธีแก้ปัญหาที่ยอมรับได้สำหรับการเรียกใช้จาวาดีมอนsystemdหรือมีคำเตือนหรือไม่

คำตอบ:


14

นี่คือการแก้ไขเล็กน้อย:

  1. network.targetเพราะมันฟังบนซ็อกเก็ตเครือข่ายให้มันขึ้นของ
  2. nohupไม่จำเป็นเนื่องจากsystemdจะทำให้ daemonize ปฏิบัติการสำหรับคุณ
  3. ฉันคิดว่าเชลล์สคริปต์ที่แยกต่างหากจะเป็น overkill ดังนั้นเพียงรวมมันเข้ากับไฟล์บริการ
  4. < /dev/nullไม่จำเป็นต้องเปลี่ยนเส้นทาง ( และอื่น ๆ ) เนื่องจาก systemd ตั้งค่าบริบท I / O มาตรฐานที่เหมาะสม อันที่จริงถ้าคุณใช้การเปลี่ยนเส้นทางออก systemd จะเข้าสู่ระบบอะไรส่งออกมาตรฐานโดยโปรแกรม Java ในวารสารของมันมีกลไกในการเข้าสู่ระบบไม่พิเศษที่จำเป็น
  5. การเรียกใช้ asynchonously จากเชลล์ที่เรียกใช้ ( &) ไม่จำเป็นหรือเหมาะสม
  6. มีรูปแบบพฤติกรรมที่เฉพาะเจาะจงตามที่กำหนดType=forkingและหากไม่ได้ตามด้วยสิ่งที่ผิดพลาด ดังนั้นลองType=simple(หรือType=notify)

ดังนั้นไฟล์บริการจะเป็นดังนี้:

[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

หมายเหตุ:

  1. คุณไม่สามารถใช้javaเป็นชื่อของโปรแกรมเพื่อเรียกใช้ systemd ไม่ค้นหาPATHไฟล์ที่เรียกใช้งานได้และชื่อของไฟล์ที่เรียกทำงานที่กำหนดให้ExecStartต้องเป็นค่าสัมบูรณ์ /usr/bin/envดังนั้นหากคุณต้องการค้นหาเส้นทางที่คุณต้องเรียกใช้ผ่านเปลือกหรือ เราเลือก/bin/shที่นี่
  2. เนื่องจากนี่เป็นType=simpleเชลล์ที่ต้องใช้execJava จึงไม่เรียกใช้เป็นกระบวนการลูก systemd ควบคุมบริการผ่านกระบวนการหลักและจำเป็นต้องเป็น Java ไม่ใช่กระบวนการหลักของเชลล์
  3. เนื่องจากสิ่งนี้ไม่ได้เรียกใช้ Java โดยตรงโดยตรง systemd จะใส่ชื่อลงshในบัญชีรายวันของมันเป็นชื่อบริการ ดูที่วิธีหลีกเลี่ยง / usr / bin / env ที่ถูกทำเครื่องหมายใน systemd ล็อกเป็นไฟล์เรียกทำงานสำหรับข้อมูลเพิ่มเติมเกี่ยวกับเรื่องนี้

เท่าที่ฉันรู้ไม่มีข้อแม้พิเศษในการใช้งานจาวาแอปพลิเคชันด้วย Systemd


1
นั่นไม่ได้ผล ปัญหาที่ 1: นี่ไม่ใช่เปลือกหอย ไม่มีตัวดำเนินการเปลี่ยนเส้นทาง คุณไม่ต้องการเปลี่ยนเส้นทางนั้นจริงๆ ปัญหาที่ 2: ExecStart ต้องการชื่อพา ธ สัมบูรณ์ ปัญหาที่ 3: unix.stackexchange.com/questions/229523
JdeBP

หัวดีขึ้น ฉันทำได้แค่จัดการแก้ไขปัญหาเท่านั้น 1. คุณจะแก้ไข Prob 2,3 ได้อย่างไร
Yun-Chih Chen

1
ดูคำตอบว่าแก้ไขแล้ว
JdeBP

ฉันไม่คิดว่านี่เป็นสิ่งที่จำเป็น
faho

สวัสดี @ Yun-ChihChen คุณจะหยุดกระบวนการได้อย่างไร ExecStrop จะมีลักษณะอย่างไร ฉันใช้ init.d พร้อมกับไฟล์ pid แต่พบว่าง่ายกว่านี้ ดังนั้นฉันต้องแน่ใจว่าฉันรู้วิธีหยุด ฯลฯ ขอบคุณ
อาจารย์สีดำ
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.