我知道这个问题已经被问了很多次,但迄今为止的答案并不令人满意。在过去的几个工作日里,我一直在努力寻找一个好的解决方案,我希望有人能为我指明正确的方向。
设想:
- 我在 Ubuntu 22.04 上有一个作为系统服务启动的网络服务器。
- Web 服务器作为非特权应用程序用户运行。
- 网络服务器需要能够启动脚本。
- 该脚本将运行 pg_restore。
- 该脚本需要能够在 pg_restore 运行时阻止 Web 服务器服务连接到 postgres。
- 目前,当脚本停止 Web 服务器服务(父级)时,脚本(子级)也会终止。脚本是否作为独立进程生成或使用 nohup 并在后台运行并不重要。当父服务停止或重新启动时,脚本立即终止。
可能的解决方案1:为应用程序用户禁用 postgres 中的连接。
参考:https://stackoverflow.com/questions/3185266/postgresql-temporarily-disable-connections
问题:连接恢复后,脚本仍需要重新启动 Web 应用程序服务,这会终止脚本。
可能的解决方案2:创建一个仅用于运行脚本的新服务。
参考:运行产生长时间运行的独立进程的 systemd 服务的“正确”方法是什么?
问题:创建一个 99.9% 的时间都不执行任何操作、仅运行一次脚本的系统服务似乎很笨拙。该脚本没有 root 权限,因此如果没有一些 sudo 体操,按需创建服务可能不是一个选择,除非我错过了一些东西。
可能的解决方案3:将网络服务器服务 KillMode 设置为“进程”。
参考:https://stackoverflow.com/questions/32208782/cant-detach-child-process-when-main-process-is-started-from-systemd
问题:在服务重新启动时,systemd 可能无法正确管理(终止)正常操作期间由 Web 服务器生成的任何进程。这可能会导致在进程失控时很难恢复系统资源。
可能的解决方案4:创建一个临时进程控制组 ala systemd-run。
参考:https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/7/html/resource_management_guide/chap-using_control_groups#sec-Creating_Transient_Cgroups_with_systemd-run
问题:我尝试systemd-run --user --scope whoami > /home/appuser/test.txt 2>&1
从 Web 服务内部(而不是从我的 shell)运行并收到以下错误消息:
Failed to connect to bus: $DBUS_SESSION_BUS_ADDRESS and $XDG_RUNTIME_DIR not defined (consider using --machine=<user>@.host --user to connect to bus of other user)
。经过搜索和搜索,我尝试了以下方法:
- 设置环境变量
export DBUS_SESSION_BUS_ADDRESS='unix:path=/run/user/$UID/bus'
.然后我收到错误:Failed to connect to bus: No such file or directory
。人们谈论在“正常登录/shell”中运行来解决,但这是一个网络服务,而不是普通用户。 - 一般建议是避免使用“sudo”和“su”。我也没用。
dbus
和软件包dbus-user-session
已安装。
感谢您的帮助。这让我抓狂了!