首页 > 解决方案 > 使用示例 init 脚本将 HSQLDB 作为 systemd 服务运行

问题描述

HSQLDB 文档有使用示例init 脚本在 Unix 上将 HSQLDB 作为守护程序运行的说明。但是,这假设一个 System V 设置,而我的目标是基于 systemd 的设置。

HSQLDB 的一个挑战是关闭过程很棘手——它涉及连接到数据库并发出关闭命令,因此即使使用 systemd 也几乎需要一个脚本。

虽然 systemd 带有 SysV init 脚本的兼容性功能,它会自动为每个 init 脚本创建一个 systemd 包装器,但我尝试实现一个原生 systemd 服务,尽可能依赖 init 脚本(因为,如前所述,复杂的关机逻辑需要一个脚本)。

我的方法是放置 init 脚本/usr/sbin并围绕它创建以下 systemd 服务包装器:

[Unit]
Description=HSQLDB Server
After=network.target nss-lookup.target

[Service]
Type=forking
PIDFile=/run/hsqldb.pid
User=hsqldb
WorkingDirectory=~
ExecStart=/usr/sbin/hsqldb start
ExecStop=/usr/sbin/hsqldb stopcompact

[Install]
WantedBy=multi-user.target

但是,这失败了,因为 init 脚本期望在不同的地方成为 root。脚本本身有一个检查,当以对文件系统的根目录没有写访问权限的用户运行时,它会导致它失败——这是一个可以从脚本中删除的检查,但随后会在其中创建 pid 文件/run失败。

除了依赖兼容性功能之外,还有什么简单的方法可以使这项工作?让systemd以root身份运行脚本(通过User在服务文件中设置)会起作用吗?有什么反对这样做的理由吗?在这种情况下,我还有什么其他选择?

标签: hsqldbsystemdinit

解决方案


这适用于一些修改:

  • .service文件中,删除User=设置:这将导致 systemd 以 root 身份运行 init 脚本。
  • 在同一个文件中,dropWorkingDirectory=因为它只会控制 init 脚本运行的目录(可以从任何地方运行)。
  • init 脚本从数据库服务帐户的主目录运行,因此这将是许多文件(例如server.properties,以及从那里引用的任何文件)的默认路径——确保它们位于正确的位置。
  • Systemd 期望服务进程归启动它的帐户(在这种情况下为 root)或 PID 文件归 root 所有。默认情况下,HSQLDB 初始化脚本不这样做——确保chown root $PIDFILE在调用之前插入exit 0(在我的例子中是第 455 行)。

通过这些更改,HSQLDB 可以干净利落地启动和停止。唯一的问题是我收到来自 systemd 的警告,上面写着:

Supervising process 1541 which is not our child. We'll most likely not notice when it exits.

这可能意味着 systemd 不会注意到服务是否在没有被 systemd 停止的情况下崩溃或以其他方式退出。


推荐阅读