我现在工作的公司有一个遗留服务,它的初始化脚本使用旧的 SysvInit,但在 systemd (CentOS 7) 上运行。
由于计算量很大,该服务大约需要 70 秒才能完成。我没有为 systemd 配置任何超时,也没有更改默认配置/etc/systemd/system.conf
,但当我执行service SERVICE stop
服务时,仍然会在 60 秒后超时。
检查journalctl -b -u SERVICE.service
我发现这个日志:
Sep 02 11:27:46 service.hostname systemd[1]: Stopping LSB: Start/Stop
Sep 02 11:28:46 service.hostname SERVICE[24151]: Stopping service: Error code: 255
Sep 02 11:28:46 service.hostname SERVICE[24151]: [FAILED]
我已经尝试将DefaultTimeoutStopSec
属性更改为/etc/systemd/system.conf
to 90s
,但超时仍然发生。
有谁知道为什么在 60 秒超时?还有其他地方配置了这个超时值吗?有什么方法可以检查吗?
该服务使用 java 7 运行并对其进行守护进程,它使用JSVC。我-wait
用值配置了参数120
。
答案1
我的 systemd 服务总是超时,因为启动也需要很长时间,所以这为我解决了这个问题:
编辑你的系统文件:
- 对于现代版本
systemd
: 跑步systemctl edit --full node.service
(将“node”替换为您的服务名称)。- 这将在 处创建一个系统文件,
/etc/systemd/system/node.service.d/
该文件将覆盖 处的系统文件/usr/lib/systemd/system/node.service
。这是配置系统文件的正确方法。有关如何使用的更多信息systemctl edit
是这里。
- 这将在 处创建一个系统文件,
- 直接编辑系统文件:我的系统文件位于
/usr/lib/systemd/system/node.service
.将“节点”替换为您的应用程序名称。然而,直接编辑文件是不安全的/usr/lib/systemd/
(见评论)
- 对于现代版本
使用
TimeoutStartSec
,TimeoutStopSec
或TimeoutSec
(更多信息这里) 指定启动和停止进程的超时时间。之后,我的 systemd 文件如下所示:[Unit] Description=MyProject Documentation=man:node(1) After=rc-local.service [Service] WorkingDirectory=/home/myproject/GUIServer/Server/ Environment="NODE_PATH=/usr/lib/node_modules" ExecStart=-/usr/bin/node Index.js Type=simple Restart=always KillMode=process TimeoutSec=900 [Install] WantedBy=multi-user.target
- 您还可以通过运行其中任何一个来查看当前超时状态(但您需要编辑服务才能进行更改!请参阅步骤 1)。令人困惑的是,相关属性的名称中带有一个“U”,表示微秒。看这个 Github 问题了解更多信息:
systemctl show node.service -p TimeoutStartUSec
systemctl show node.service -p TimeoutStopUSec
systemctl show node.service -p TimeoutUSec
- 您还可以通过运行其中任何一个来查看当前超时状态(但您需要编辑服务才能进行更改!请参阅步骤 1)。令人困惑的是,相关属性的名称中带有一个“U”,表示微秒。看这个 Github 问题了解更多信息:
接下来你需要重新加载 systemd
systemctl reload node.service
现在尝试启动您的服务
systemctl start node.service
如果那不起作用,尝试重新启动 systemctl
systemctl reboot
如果那不起作用,尝试使用
--no-block
systemctl 的选项,如下所示:systemctl --no-block start node.service
。该选项有描述这里: "不同步等待请求的操作完成。如果不指定,作业将被验证、入队,systemctl 将等待,直到单元的启动完成。通过传递此参数,仅验证和入队”。- 还可以选择使用 来
systemctl mask
代替systemctl start
.欲了解更多信息,请参阅这里。
- 还可以选择使用 来
评论更新:
TimeoutSec=infinity
:这里不要使用“无穷大”,而是使用大量的时间,例如TimeoutSec=900
(15 分钟)。如果应用程序需要“永远”退出,那么它可能会无限期地阻止重新启动。图片来源@Alexis Wilke 和@JCCyC- 不要编辑
/usr/lib/systemd/system
,systemctl edit
而是尝试或编辑/etc/systemd/system
以覆盖它们。您永远不应该编辑/usr/lib/
.信用@ryeager和@0xC0000022L
** 从 systemd 源文档更新 ** 当指定“无穷大”作为任何这些超时参数的值时,超时逻辑为残疾人。
JobTimeoutSec=, JobRunningTimeoutSec=,TimeoutStartSec=, TimeoutAbortSec=
默认值为“无穷大”(禁用作业超时),但 JobRunningTimeoutSec= 默认为 DefaultTimeoutStartSec= 的设备单位除外。
参考:在此输入链接描述
同样,此逻辑适用于服务级别,并在下面的 URL 中清楚地列出。参考:在此输入链接描述
答案2
运行时systemctl show SERVICE_NAME.service -p TimeoutStopUSec
我至少可以看到 systemd 为我的服务设置的超时。
我将脚本更改为常规单元文件之一,以便其正常工作。
答案3
不要编辑包的服务文件(该/usr/lib/systemd/system/
文件在包升级时将被覆盖),而是使用:
sudo EDITOR=/bin/vi systemctl edit <service-name>
(是的,nano 是默认编辑器!哎呀!)
这将安全地编辑该文件/etc/systemd/system/service-name.service.d/override.conf
。
该文件只需包含:
[Service]
# Override default 90 second timeout in pathological conditions
TimeoutStopSec=5 # or whatever value you want
输入以下命令查看整体效果:
systemctl cat <service-name>
答案4
为了实现你想要的,我使用以下 3 个命令,
要检查默认超时值,
systemctl show yourServiceName.service | grep ^Timeout
要增加默认超时值,
mkdir /etc/systemd/system/yourServiceName.service.d
echo -e "[Service]\nTimeoutStartSec=180" | tee /etc/systemd/system/yourServiceName.service.d/startup-timeout.conf
在哪里,
yourServiceName
: 是服务名称。例如,fluidd、weblogic等。TimeoutStartSec=180
:这里,我使用 180 秒/3 分钟作为超时值。