使用 python 重新启动 apache 会导致端口更改

使用 python 重新启动 apache 会导致端口更改

我正在使用 python bottle web 框架来创建一个服务管理器,所以我为服务创建了端点,重新启动/停止我正在使用时发生的有线事情

os.system('service apache2 restart')

或者

os.system('/etc/init.d/apache2 restart')

Apache 接管了我的 Bottle 应用程序的端口,所以如果我正在运行lsof -i :8080(8080 是我的 Bottle 应用程序端口),我会看到

COMMAND   PID     USER   FD   TYPE  DEVICE SIZE/OFF NODE NAME
python  27396     root    3u  IPv4 1298282      0t0  TCP *:http-alt (LISTEN)
apache2 27426     root    3u  IPv4 1298282      0t0  TCP *:http-alt (LISTEN)
apache2 27428 www-data    3u  IPv4 1298282      0t0  TCP *:http-alt (LISTEN)
apache2 27429 www-data    3u  IPv4 1298282      0t0  TCP *:http-alt (LISTEN)
apache2 27430 www-data    3u  IPv4 1298282      0t0  TCP *:http-alt (LISTEN)
apache2 27432 www-data    3u  IPv4 1298282      0t0  TCP *:http-alt (LISTEN)
apache2 27433 www-data    3u  IPv4 1298282      0t0  TCP *:http-alt (LISTEN)
apache2 27435 www-data    3u  IPv4 1298282      0t0  TCP *:http-alt (LISTEN)

文件 /etc/apache2/ports 具有以下内容

# If you just change the port or add more ports here, you will likely also
# have to change the VirtualHost statement in
# /etc/apache2/sites-enabled/000-default.conf

Listen 80

<IfModule ssl_module>
    Listen 443
</IfModule>

<IfModule mod_gnutls.c>
    Listen 443
</IfModule>

# vim: syntax=apache ts=4 sw=4 sts=4 sr noet

当然,如果我在 shell 中运行相同的命令,一切都会按预期进行

注意:python 脚本以 root 身份运行

答案1

这是因为默认情况下,子进程会继承其父进程的文件描述符。

由于您的 Web 应用程序打开了此端口,因此它会将os.system请求发送到正在运行的 Apache Web 服务器。

您需要改变您的python代码来执行以下操作。

  • 称呼os.fork()
  • 关闭您的 Web 应用程序所使用的监听服务器端口的文件描述符。(注意不要 不是调用shutdown它。
  • 拨打您的os.system()请求。
  • 退出你的分叉进程。

较新版本的 Python 引入了一种默认行为,即FD_CLOEXEC在所有文件描述符上添加属性以避免此行为。您也可以使用该fcntl模块在监听套接字上自己执行相同的操作,但这可能会破坏应用程序的其他方面,因此您需要对此进行测试。

相关内容