如何向 FPM(nginx)添加池而无需重新加载/重新启动 fpm 本身?

如何向 FPM(nginx)添加池而无需重新加载/重新启动 fpm 本身?

我正在构建一个环境(在 ubuntu 10.04.02 机器上)来处理具有许多(应该支持至少 1000 个)子域的网站,每个子域由不同的 FPM 池和不同的用户提供服务。

所以没什么新鲜的;我的问题是创建(并启动)一个新的 fpm 池,而不必重新加载/重新启动 FPM,这将导致(我知道,非常快)停机。

我编写了一个 python 守护进程,当需要时:

  1. 创建系统用户
  2. 设置子域名的 Web 根目录
  3. 在我的 /etc/php5/fpm/fpm.d/ 文件夹中创建 subdomain.conf

我在 google 上搜索了一下,但没有找到使用一个池来调用 fpm 的方法,这可能是一个“临时”解决方案:主 fpm 实例运行所有池,每个新池都有自己的 fpm 实例,然后我使用 cron 每周/每月/不知道停止并重新加载 fpm

如果确实重要,服务器在 nginx 上运行,配置为使用 unix socket 到 fcgi,这是我的 nginx 测试配置:

server{
    listen          80;
    server_name     ~^(?<domain>.+)\.test\.local$; # foo.test.local > myapp_foo
    root            /var/www/myapp/subdomains/myapp_$domain/htdocs;
    location / {
        index index.php;
    }
    location ~* \.(gif|jpg|png|ico)$ {
        expires 30d;
    }
    location ~ \.php$ {
        fastcgi_pass    unix:/var/web-sock/myapp_$domain-fpm.sock;
        fastcgi_param   SCRIPT_FILENAME     $document_root$fastcgi_script_name;
        include         fastcgi_params;
    }
}

..和我的子域-fpm.conf:

[myapp_foo]
listen = /var/web-sock/myapp_foo-fpm.sock

user = myapp_foo
group = myapp_foo

pm = dynamic
pm.max_children = 30
pm.start_servers = 1
pm.min_spare_servers = 1
pm.max_spare_servers = 30

我曾尝试使用php5-cgi和/或spawn-fcgi新的子域,但有点不稳定,并且在并发级别稍微增加时经常崩溃。

任何想法?

答案1

我不相信有任何方法可以在不重新启动/重新加载的情况下添加池(根据)。

我确实认为冗余是解决这个问题的最佳方法,我确实相信,你可以用 来实现你想要的reload。因为它是一个优雅重载它应该等待进程完成。

本质上,将SIGUSR2信号传递给 php-fpm,它将正常地重新加载所有工作者 + 重新加载 fpm conf/binary。

我相信这相当于

kill -USR2 `cat $php_fpm_PID`

因此,您修改配置 - 并重新加载 - 不应导致明显的停机时间。

另一种选择是每个用户运行一个进程 - 您可以添加新用户而不终止现有进程,但资源要求明显更高(并且对于 1000 多个用户来说可能不切实际)。

更多选择是为新用户创建一个临时的 php-cgi 进程,并延迟重新加载服务器,直到稍后(即低负载期,或需要添加多个用户时)。这将减少停机时间,但仍会立即启动新用户的子域。

以上任何一种方法都不是完美的,唯一可行的不停机解决方案就是采用多服务器方法。

答案2

如果你不能承受任何停机时间,唯一的选择就是增加冗余

  1. 让一些负载均衡器在2个(或更多)服务器前面运行。
  2. 按你想要的方式配置热备
  3. 切换
  4. 按您想要的方式配置“新”热备用
  5. 每次需要改变时都要重复

编辑:仅使用一个硬件就可以运行这样的设置。只需添加在不同 IP 上运行的更多 nginx 实例,并在它们之间创建故障转移设置。此选项是否适合您的用例,由我决定。

答案3

听起来你资源匮乏。为什么不在同一硬件上运行两个 Web 服务器?

尝试这样的操作:

+---------------+
|    nginx :80  |
|   /     \     |
| :8081  :8080  |
+---------------+

这样,您的负载平衡服务(本例中为 nginx)就可以在两个端口之间路由。这样,您可以根据需要随时启动或关闭服务(进行更新)等。

当然,您需要两个 FPM 池、两个用户等等。

答案4

抱歉回答我自己的问题,但我发现此解决方案这正是我所寻找的...3 年前 ;)

基本上,这个想法是为每个池设置一个初始化脚本,只需进行一些修改就可以很好地工作。

抱歉,如果我没有在这里重复这些步骤,但实际上,只需从该链接复制粘贴即可!

进一步阅读:php-fpm ondemand 与 systemd

希望能帮助到别人;)

相关内容