Nginx

如何在不重新載入/重新啟動 fpm 本身的情況下將池添加到 FPM(nginx)?

  • September 8, 2014

我正在建構一個環境(在 ubuntu 10.04.02 機器上)來處理具有許多(應支持至少 1000 個)子域的網站,每個子域由不同的 FPM 池提供服務,並具有不同的使用者。

所以沒什麼新鮮的;我的問題是創建(並啟動)一個新的 fpm 池而無需重新載入/重新啟動 FPM,這將導致(我知道,非常快)停機時間。

我寫了一個 python 守護程序,在需要的時候:

  1. 創建系統使用者
  2. 設置子域的 Web 根目錄
  3. 在我的 /etc/php5/fpm/fpm.d/ 文件夾中創建 subdomain.conf

我四處搜尋,但我沒有找到使用一個池呼叫 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使用新的子域,但有點不穩定,並且當並發級別增加一點時經常崩潰。

任何的想法?

我不相信有任何方法可以在不重新啟動/重新載入的情況下添加池(根據this)。

我確實認為冗餘是解決此問題的最佳方法,我確實相信,您可以通過reload. 由於這是一個優雅的重新載入,它應該等待程序完成。

本質上,將SIGUSR2信號傳遞給 php-fpm,它會優雅地重新載入所有工作人員 + 重新載入 fpm conf/binary。

我相信這相當於

kill -USR2 `cat $php_fpm_PID`

因此,您修改 conf - 並重新載入 - 不應導致明顯的停機時間。

另一種選擇是為每個使用者執行一個程序 - 您可以添加新使用者而無需終止現有程序,但資源要求要高得多(而且,對於 1000 多個使用者來說不太可能)。

另一種選擇是為新使用者創建一個臨時的 php-cgi 程序,並延遲重新載入伺服器直到稍後(即低負載期,或者當您有多個使用者要添加時)。這將減少停機時間,但仍會立即啟動新使用者的子域。

以上都不是完全理想的,沒有停機的唯一實用解決方案是多伺服器方法。

如果您無法承受任何停機時間,唯一的選擇是添加冗餘

  1. 讓一些負載平衡器在 2 個(或更多)伺服器前執行。
  2. 以您想要的方式配置熱備
  3. 切換
  4. 以您想要的方式配置“新”熱備用
  5. 每次需要更改時重複並重複

編輯:很可能只用一個硬體來執行這樣的設置。只需添加更多在不同 IP 上執行的 nginx 實例並在它們之間創建故障轉移設置。如果此選項對您的案例有意義,則不由我決定。

引用自:https://serverfault.com/questions/259245