You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过DBus即时获取systemd服务崩溃的通知?

问题描述

我有一个由多个进程组成的Linux应用,其中包含一个「监控进程」,负责在其他进程崩溃时执行相应处理操作。应用内所有进程都注册为systemd服务,目前监控进程通过DBus订阅每个服务的属性,监听ActiveState属性,当该属性变为failed时触发崩溃处理逻辑。

这种方式基本能用,但存在时序问题:进程崩溃时会生成coredump(在ARM系统上最多需要30秒),而ActiveState属性要等到coredump完全完成后才会变更,导致崩溃通知严重延迟。

如何通过DBus即时获取带有服务名的崩溃事件通知?

我已经尝试过以下操作:

  • 检查了Service和Unit接口的所有其他属性,崩溃发生时没有任何属性变更
  • 检查了systemd Manager对象的属性,均与该问题无关
  • 订阅了Manager对象的UnitNew信号,能收到coredump服务启动的通知,但无法从coredump服务的属性中明确得知是哪个服务崩溃了

需求:希望继续通过systemd(基于DBus)获取信息,优先采用通知而非轮询的方式。

解决思路

1. 监听UnitStateChanged信号追踪SubState变化

systemd的org.freedesktop.systemd1.Manager接口提供UnitStateChanged信号,会在单元的任意状态属性变更时触发,包括SubState。当进程崩溃开始生成coredump时,服务的SubState会从running切换为terminating,这个变更远早于ActiveState变为failed的时间。订阅该信号后,解析信号中的单元名(即服务名)和新的SubState值,一旦检测到terminating状态,即可判定对应服务的进程已崩溃,提前触发处理逻辑。

2. 利用JobNew信号捕获服务终止事件

进程崩溃时,systemd会立即创建终止作业(Job)处理该服务。org.freedesktop.systemd1.Manager的JobNew信号会在作业创建时触发,信号包含作业ID、作业类型(如stop)以及关联单元名(服务名)。订阅该信号后,当作业类型为stop且关联单元属于你的目标服务时,即可将其视为崩溃事件的早期通知。

3. 调整systemd配置加速ActiveState变更

如果允许修改服务的systemd配置,可以通过以下方式让ActiveState更快变为failed:

  • 设置服务的KillMode=mixed:systemd会先向主进程发送终止信号,同时立即将服务标记为deactivating,无需等待coredump完成。
  • 优化coredump处理:修改/etc/systemd/coredump.conf,比如设置Storage=none(不需要保留coredump时)或调整ProcessSizeMax限制coredump大小,减少处理时间,从而加快ActiveState的更新。但此方法会牺牲coredump完整性,需根据需求权衡。

4. 解析coredump服务的元数据

你之前通过UnitNew信号能收到coredump服务启动通知,可进一步查询该服务的org.freedesktop.systemd1.Service接口的ExecStart属性,解析其中的命令行参数——coredump服务的启动参数通常包含--unit=字段,对应崩溃的服务名。通过提取该参数值,就能关联到具体崩溃的服务。

内容的提问来源于stack exchange,提问作者Gyorgy Szekely

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 03:43:26