FastCGI 脚本中的异步子进程

FastCGI 脚本中的异步子进程

假设我希望我的服务器在对路径的任何 HTTP 请求/sleep(即)上休眠,但也在休眠之前http://hostname/sleep发送完整的响应( )。HTTP 200

使用nginx快速CGI,我已经配置了路径nginx配置:

location /sleep {
    fastcgi_pass unix:/path/to/fcgiwrap.socket;
    include fastcgi_params;
    fastcgi_param SCRIPT_FILENAME /path/to/script.sh;
}

这将调用以下脚本 ( /path/to/script.sh):

#!/bin/sh
# -*- coding: utf-8 -*-
cat << EOF
Content-Type: text/html

<html><head><title>Sleep</title><meta charset="UTF-8"></head>
<body><p>Sleep: $(date)</p></body></html>
EOF
sleep 1 && sudo systemctl suspend < /dev/null > /dev/null 2>&1 &

即使这会使系统休眠,快速CGI将阻塞直到子进程完成,这意味着 Web 请求在系统睡眠之前不会完成。那么,我如何将最终命令从监督中分离出来快速CGI以便响应完成,但命令在后台继续运行,在这种情况下最终使系统休眠?

答案1

您可以通过插入用作 systemd 触发器的文件来解耦 cgi 和挂起。请参阅man systemd.path参考资料 以了解基于路径的单元激活。它的优点是不需要从 cgi 使用 sudo。

创建单元文件/etc/systemd/system/mycgitrigger.path

[Path]
PathModified=/some/writeable/file
[Install]
WantedBy=multi-user.target

并启用它。更改 cgi 脚本以简单地将任何内容写入文件/some/writeable/file以触发关机。将短超时和关机命令放在单元文件中 /etc/systemd/system/mycgitrigger.service(无需启用)。

答案2

显而易见的解决方案是

echo "sleep 1 && sudo systemctl suspend" | at now

相关内容