我试图解决的问题是在启动或停止自定义服务时启动和停止侦听器服务。具体案例是 RHEL7 上的 IBM MQ V8,但相同的原则也应适用于 Oracle DB 和侦听器等。
侦听器服务应在主服务之后启动并在主服务之前停止。
我将发布我自己的 systemd 单元文件作为答案,但我正在寻找其他回复来改进我的答案。
答案1
主要服务 /etc/systemd/system/[电子邮件受保护]定义为:
[Unit]
Description=IBM MQ V8 QM %i
Requires=qm-listener@%i.service
Before=qm-listener@%i.service
[Service]
Type=forking
User=mqm
Group=mqm
ExecStart=/opt/mqm/bin/strmqm %i
LimitNOFILE=10240
LimitNPROC=4096
ExecStop=/opt/mqm/bin/endmqm %i
KillMode=none
[Install]
WantedBy=multi-user.target
监听服务/etc/systemd/system/[电子邮件受保护] 定义为:
[Unit]
Description=IBM MQ V8 %i Listener
PartOf=qm@%i.service
[Service]
Type=simple
User=mqm
Group=mqm
ExecStart=/opt/mqm/bin/runmqlsr -t TCP -m %i
LimitNOFILE=10240
LimitNPROC=4096
ExecStop=/opt/mqm/bin/endmqlsr -m %i
KillMode=none
[Install]
WantedBy=multi-user.target
我正在使用模板函数以便单个单元文件可用于管理多个队列管理器。启动队列管理器 QM1 的实际命令是
$ sudo systemctl start qm@QM1
这将实例化并启动服务 qm@QM1 以及 qm-listener@QM1
我在创建此内容时学到的一些附加注释:
- 类型是分叉的[电子邮件受保护]因为命令 strmqm 在分叉实际的 qmgr 进程后退出[电子邮件受保护]类型很简单,因为runmqlsr进程是主进程
- KillMode 为 none 是必需的,因为 systemd 默认情况下会在执行 ExecStop 命令后向 cgroup 中的所有进程发送 SIGTERM。 MQ 在收到 SIGTERM 时抛出错误。
- 未指定 PIDfile,因为 MQ 不会生成 PIDfile,如果指定,systemd 会认为启动失败
- 添加了 LimitNOFILE 和 LimitNPROC,因为 /etc/security/limits.conf 或 /etc/security/limits.d/*conf 中定义的限制仅适用于 pam 登录会话,并且由 systemd 启动的服务不在 pam 登录会话中运行。
- 监听器中的 PartOf 确保当相应的 qm 服务停止时它也停止
我不确定 PartOf 选项是否是正确的选择。