Các dịch vụ vẫn ở trạng thái không thành công sau khi dừng với systemctl


19

chúng tôi có một kịch bản systemd đơn giản để khởi động máy chủ MineCraft theo kiểu dịch vụ. SO là CentOS 7. Ở đây tập lệnh:

[Unit]
Description=Minecraft Server
After=syslog.target network.target

[Service]
Type=simple
WorkingDirectory=/root/Minecraft
ExecStart=/bin/java -Xmx1024M -Xms1024M -jar minecraft_server.jar nogui
Restart=on-failure

[Install]
WantedBy=multi-user.target

Bắt đầu dịch vụ hoạt động tốt nhưng khi dừng, dịch vụ vẫn ở trạng thái không thành công. Xem:

systemctl status minecraftd.service
minecraftd.service - Minecraft Server
   Loaded: loaded (/usr/lib/systemd/system/minecraftd.service; disabled)
   Active: active (running) since Mon 2015-06-01 16:00:12 UTC; 18s ago
 Main PID: 20975 (java)
   CGroup: /system.slice/minecraftd.service
           └─20975 /bin/java -Xmx1024M -Xms1024M -jar minecraft_server.jar nogui
systemctl stop minecraftd.service
systemctl status minecraftd.service
minecraftd.service - Minecraft Server
   Loaded: loaded (/usr/lib/systemd/system/minecraftd.service; disabled)
   Active: failed (Result: exit-code) since Mon 2015-06-01 16:01:37 UTC; 3s ago
  Process: 20975 ExecStart=/bin/java -Xmx1024M -Xms1024M -jar minecraft_server.jar nogui (code=exited, status=143)
 Main PID: 20975 (code=exited, status=143)

Bất kỳ ý tưởng?

Cảm ơn

Câu trả lời:


27

Mã thoát 143 có nghĩa là chương trình đã nhận được tín hiệu SIGTERM để hướng dẫn nó thoát, nhưng nó không xử lý tín hiệu đúng cách. Điều này hầu như luôn luôn do lỗi lập trình và khá phổ biến với các ứng dụng Java thuộc mọi loại.

Bạn sẽ có thể ngăn chặn điều này bằng cách thêm mã thoát vào tệp đơn vị làm trạng thái thoát "thành công":

[Service]
SuccessExitStatus=143

Nó hoạt động. Bây giờ dịch vụ đang ở trạng thái không hoạt động, như mong đợi.
kalise

4
Cách "thích hợp" để xử lý tín hiệu với ứng dụng Java là gì? Cái gần nhất tôi có thể tìm thấy là hook shutdown, nhưng không có tài liệu nào đề cập đến việc hook hook làm thay đổi mã thoát của ứng dụng.
SPoage

@SPoage stackoverflow.com/q/2975248/1068283 Nhưng, có vẻ như, Java luôn thoát với mã 143 trong trường hợp này, ngay cả khi có móc tắt máy.
Michael Hampton

10

Để bổ sung cho câu trả lời của Michael, mã thoát 143 là bình thường ở đây, đó là cách mà java VM nhận được tín hiệu SIGTERM, được gửi bởi systemd để dừng quá trình. Tín hiệu SIGTERM có giá trị số là 15 (xem man signal).

Bây giờ theo đặc tả Posix, "Trạng thái thoát của lệnh bị chấm dứt vì nhận được tín hiệu sẽ được báo cáo là lớn hơn 128". ( http://pub.opengroup.org/onlinepub/009695399/utilities/xcu_chap02.html#tag_02_08_02 )

Ở đây, Java VM thêm 128 + 15 và bạn nhận được mã thoát này là 143.

Mã thoát không bằng 0 ở đây có ý nghĩa, vì điều này cho phép thấy rằng chương trình java của bạn đã thoát do tín hiệu bên ngoài và bạn có cơ hội tìm hiểu tín hiệu nào.


Văn bản đặc tả POSIX được tham chiếu dường như chỉ định cách trình bao hoạt động và nói "Shell là trình thông dịch ngôn ngữ lệnh". Một máy ảo Java dường như không phải là thứ được bao phủ bởi đặc tả đó. Cách shell giải thích một máy ảo Java (hoặc bất kỳ chương trình nào khác) kết thúc do SIGTERM - rằng nó sẽ đặt mã thoát thành 143 - chắc chắn được bao phủ bởi đặc tả, nhưng tôi khá chắc chắn rằng không có shell nào liên quan ở đây.
doshea

Bạn nói đúng rằng đặc tả POSIX này được hướng vào hệ vỏ UNIX, nhưng ở đây có vẻ như các tác giả JVM đã quyết định thực hiện mã trả về của họ theo cùng một cách.
Manu
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.