首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么systemd不知道某个服务是否失败?

为什么systemd不知道某个服务是否失败?
EN

Unix & Linux用户
提问于 2020-04-15 16:02:30
回答 1查看 937关注 0票数 1

我试图在Ubuntu18.04上提供spring引导应用程序(由其他人开发--我不是java程序员)。开发人员以前在/etc/init.d中添加了符号链接来启用服务--它在启动时很好地启动。但是,如果服务随后失败,systemd仍然报告它正在运行:

代码语言:javascript
复制
root@example.com:/var/log/apps# systemctl status crm-service
● crm-service.service - LSB: crm-service
   Loaded: loaded (/etc/init.d/crm-service; generated)
   Active: active (exited) since Wed 2020-04-15 12:27:15 BST; 3h 56min ago
     Docs: man:systemd-sysv-generator(8)
  Process: 8656 ExecStop=/etc/init.d/crm-service stop (code=exited, status=0/SUCCESS)
  Process: 8703 ExecStart=/etc/init.d/crm-service start (code=exited, status=0/SUCCESS)

Apr 15 12:27:15 example.com systemd[1]: Starting LSB: crm-service...
Apr 15 12:27:15 example.com crm-service[8703]: /var/services/crm-service.conf: line 1: -Xms96M: command not found
Apr 15 12:27:15 example.com crm-service[8703]: Started [8747]
Apr 15 12:27:15 example.com systemd[1]: Started LSB: crm-service.

虽然我看到同一系统单元文件的春天在互联网上张贴,但我没有看到任何可能解决这个问题。

  1. 如何使系统查看服务的真实状态?(它将打开一个监听套接字,但在一个随机的高端口上)
  2. 是否有一种方法可以让systemd温和地尝试重新启动它知道已经失败的服务?
EN

回答 1

Unix & Linux用户

回答已采纳

发布于 2020-04-15 16:22:49

Systemd有很多批评者,其中很多都很好,但事实并非如此。Systemd可以跟踪从启动脚本中分叉(或克隆)的所有进程和线程,如果没有剩余的进程和线程,则认为服务已死。

我看到的第一个问题是: systemd不使用/etc/init.d中的start/stop脚本,它只是一个兼容性的加注。相反,systemd使用单元文件,即它的所有服务的配置文件。

systemd模块有效地为/etc/init.d中的所有服务生成一个单元文件。这并不总是好的,因为init脚本缺少所需的信息(或者不可能从它们中提取信息)。

如果退出代码为非零,则该compat模块的工作方式是系统d认为init脚本失败,因此服务不能工作。零退出代码意味着成功执行。如果init脚本是错误的,并且即使失败,它也会给出一个零退出代码,那么它将欺骗systemd。

init脚本的错误最有可能的原因是它在后台启动进程,然后总是以零退出。对于大多数由自定义提供程序编写的init脚本,我的常见经验是.也许他们中的大多数人都有一个重要的改进的地方。不要相信他们,看看他们做了什么,并修复他们。在你的情况下,最好是检查一下,

  • 它如何启动您的java应用程序
  • 它是从哪里开始的
  • 从哪个用户开始

并使用一个单元文件复制相同的功能。

无法从systemd自动重新启动initscript,但是可以从单元文件中重新启动initscript。

注意,如果一个Java程序随机崩溃,它也是一个严重的问题。所有正常的java框架都正确地处理自己的致命错误(它们捕获所有异常,记录它并继续)。

init脚本中另一个很可能的错误是它找不到您的JVM (很可能是: /usr/bin/java),因此它用一个空字符串替换它,从而尝试将JVM标志作为shell命令启动。显然,您的系统中没有-Xms96M命令,但是/usr/bin/java -Xms96M ...可以工作。

spring引导应用程序的一个示例单元文件:

代码语言:javascript
复制
[Unit]
Description=Crm Spring Boot App Example
After=network.target

[Service]
Type=simple
ExecStart=/usr/bin/java -Xms96M ...other flags... your.spring.boot.jar
User=exampleuser
Group=examplegroup
StandardOutput=syslog
StandardError=syslog
SyslogIdentifier=exampleapp
WorkingDirectory=/path/to/app/home

[Install]
WantedBy=multi-user.target
Alias=exampleapp.service

这个单元文件还将Java进程的标准输出和错误重定向到syslog。

若要自动重新启动应用程序,请插入

代码语言:javascript
复制
RestartSec=5s
Restart=on-failure

进入[Service]部分。

有一个关于GoLinuxCloud.com的系统教程。

票数 3
EN
页面原文内容由Unix & Linux提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://unix.stackexchange.com/questions/580257

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档