当前位置: 首页 > news >正文

systemd-notify(linux服务状态通知消息)

起因是redis安装systemd配置后,可以启动,但是systemctl start redis命令挂起无法退出,最后查出是因为redis的systemd配置启动类型为Type=notify,但是redis本身并没有编译为支持systemd的版本。

所以详细了解了下Type=notify。

notify启动类型举例(centos8):

例子服务程序:notify-srv.sh

#!/bin/bashsystemd-notify --ready --status="Waiting for data…"
sleep 10do_counter=1
while : ; dosystemd-notify --status="Processing $do_counter"sleep 5do_counter=$[ $do_counter + 1 ]
done

例子服务配置:notify-srv.service

[Unit]
Description=My Notify Test[Service]
Type=notify
ExecStart=/home/work/test/notify-srv.sh[Install]
WantedBy=multi-user.target

安装例子服务:

chmod +x /home/work/test/notify-srv.sh
cp ./notify-srv.service /usr/lib/systemd/system/notify-srv.service
systemctl daemon-reload

测试:

可以看到status文本的变化。

其中:

1、systemd-notify --ready --status 报告服务已启动,同时发送了status文本。

2、systemd-notify --status 报告更多的状态消息。

例子服务和systemd之间的通信通过$NOTIFY_SOCKET进行,$NOTIFY_SOCKET由systemd创建,在服务启动时通过环境变量NOTIFY_SOCKET传递给服务进程。

如:

复现问题一(Type=notify,服务不支持systemd-notify):

注释掉systemd-notify --ready --status

重启服务测试:

systemctl restart notify-srv 会挂起,不退出。

systemctl status notify-srv显示:

可以看到,和第一条status对比,由于systemd一直没有收到ready通知,所以active状态一直是start,systemctl start/restart一直不退出。但服务进程已经启动并正常运行。

复现问题二(Type=simple,服务支持systemd-notify):

修改service的启动类型为simple:

重载配置、重启服务测试:

如上图,服务状态running,但status消息不再显示,多了“$NOTIFY_SOCKET was not set”报错,因为Type=simple启动类型并未向服务进程传递环境变量NOTIFY_SOCKET,所以systemd-notify命令报错。

总结:

不支持systemd-notify的服务不可以使用Type=notify启动类型,可以改用Type=simple或其他启动类型。

以下是网友整理的systemd-notify使用手册:

systemd-notify 中文手册 [金步国]

systemd.service 中文手册 [金步国]

名称

systemd-notify — 向 systemd 报告服务状态的变化

大纲

systemd-notify [OPTIONS...] [VARIABLE=VALUE...]

描述

systemd-notify 可用于 在守护进程脚本中向 systemd 报告进程状态的变化。 可用于发送任意信息, 其中最重要的是 报告"启动已完成"的消息。

此工具基本上就是对 sd_notify() 的简单包装, 以便于在脚本中使用。详见 sd_notify(3) 手册。

注意,在报告状态更新的同时, 还可以传递一系列环境变量。

注意,在默认情况下(也就是调用此命令的服务单元含有 NotifyAccess=none), systemd 并不从此命令接受状态更新消息。

注意,服务单元的 sd_notify() 通知能够正常工作的前提, 是必须满足如下两个条件之一: (1)在 PID=1 的进程处理通知消息时,发送该通知的进程依然在运行; (2)发送该通知的进程是 systemd 派生的子进程(也就是匹配 NotifyAccess=mainNotifyAccess=exec 的进程)。 如果服务单元中的某个辅助进程在发送了 sd_notify() 通知之后就立即退出了, 那么 systemd 将有可能来不及将该通知关联到这个服务单元上。 在这种情况下,即使明确设置了 NotifyAccess=all , 该通知也可能会被忽略掉。

systemd-notify 会首先尝试以调用进程的PID来调用 sd_notify() (此操作仅在确实拥有足够权限的情况下才会成功), 如果失败,将会使用其自身的PID再次调用 sd_notify() 。 这种做法对于从 shell 脚本中调用 systemd-notify 命令非常有用, 特别是当服务的主进程是 shell 的时候(由于 NotifyAccess=all 的限制), 因为在这种情况下, shell 进程(而不是 systemd-notify 进程)将成为消息的发送者。

选项

能够识别的命令行选项如下:

--ready

向 systemd 报告"启动已完成"的消息。 这等价于 systemd-notify READY=1 。 详见 sd_notify(3) 手册。

--pid=

向 systemd 报告主守护进程的 PID 。 如果 PID 参数被省略, 将使用调用 systemd-notify 的进程的 PID 。 这等价于 systemd-notify MAINPID=$PID 。 详见 sd_notify(3) 手册。

--uid=USER

向 systemd 报告此消息来自哪个用户,也就是使用指定的 USER 取代调用此命令的用户,作为此通知消息的发送者。 USER 既可以是一个UID数值也可以是一个用户名字符串。 此选项需要足够的权限才能操作进程的用户标识。

--status=

向 systemd 发送一个任意内容的字符串消息。 这等价于 systemd-notify STATUS=… 。 详见 sd_notify(3) 手册。

--booted

用于检查系统的 init 进程是否为 systemd , 返回 0 表示系统的 init 进程是 systemd ,返回非零表示其他。 此选项并不发送任何消息,因此与其他选项没有任何关系。 详见 sd_booted(3) 手册。 另一种检查方法是 systemctl(1) 的 is-system-running 命令。 若返回 "offline" 则表示 系统的 init 进程不是 systemd

-h, --help

显示简短的帮助信息并退出。

--version

显示简短的版本信息并退出。

退出状态

返回值为 0 表示成功, 非零返回值表示失败代码。

--end--

相关文章:

  • 如何基于HAL库进行STM32开发
  • 模拟SIP终端向Freeswitch注册用户
  • 一键部署自己的私域直播
  • 具身系列——PPO算法实现CartPole游戏(强化学习)
  • operator 可以根据需要重载 == 运算符进行比较
  • Cadence高速系统设计工具
  • 0基础 | STM32 | TB6612电机驱动使用
  • DeepSeek辅助学术写作之提交和出版以及评审过程分析提示词分享祝你顺利毕业~
  • 肥胖风险的多类预测——CatBoost模型的89%
  • Y1——树状数组入门
  • 每天一道面试题@第五天
  • 推理能力:五一模型大放送
  • C# 运算符重载深度解析:从基础到高阶实践
  • 第3章 Python 3 基础语法001
  • 大模型:解码人工智能的算力革命与边界突破
  • Go反射-通过反射调用结构体的方法(带入参)
  • Spring 容器相关的核心注解​
  • xLua笔记
  • 【2025年】MySQL面试题总结
  • 【Java学习】关于springBoot的自动配置和起步依赖
  • 美国将于6月14日举行阅兵式,美媒报当天是特朗普生日
  • 安徽两位新任地级市政府党组书记亮相
  • 两部门调度部署“五一”假期安全防范工作,要求抓好旅游安全
  • 阿斯利康中国区一季度收入增5%,或面临最高800万美元新罚单
  • 辽宁省委书记郝鹏、省长王新伟赶到辽阳火灾事故现场指导善后处置工作
  • 呼伦贝尔市委常委、组织部长闫轶圣调任内蒙古交通集团党委副书记