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

相關內容