天天看點

supervisor 子程序退出_Supervisor 的使用和進階 (3)

本文主要介紹 supervisor 對 fastcgi 程序的管理

在php 中,php-fpm 有主程序來管理和維護子程序的數量。但是并不是所有的服務都有類似的主程序來做子程序的維護。在其他語言中,有很多比較有名的fastcgi 服務,例如py 的flup, c++ 實作的 FastCgi++等,如果這些服務在單機中啟動多個程序(極有可能),那如何管理這些程序是個比較頭疼的問題。

supervisor 的fastcgi 管理功能就是為了解決這個問題。supervisor 提供了如下配置,用于對fastcgi 的管理。在普通程序配置參數的基礎上,添加如下配置:

123456
           
[fcgi-program:x]socket = "tcp://10.3.2.10:9002"     ; 支援 tcp ,或者 Unix socketsocket_backlog = 1024               ; 2 的N次方, 根據機器配置設定, 預設是端口最大監聽量socket_owner = chrism:wheel         ; 監聽使用者組socket_mode = 0700                  ; 監聽模式
           

下面通過一個簡單的例子說明fastcgi的管理模式。

1. 實作一個簡單的fastcgi 服務

通過監聽127.0.0.1:9001 端口對 fastcgi 請求做處理。處理流程為:暫停1s,列印處理的程序id。(為了能看到不同程序做了響應,是以對程序暫停1s處理,并列印程序id。)

12345678910111213141516171819202122232425
           
// fastcgi.gopackage mainimport (	"net"	"net/http"	"net/http/fcgi"	"os"	"strconv"	"time")type FastCGIServer struct{}// 暫停1s, 列印辨別的程序idfunc (s FastCGIServer) ServeHTTP(resp http.ResponseWriter, req *http.Request) {	time.Sleep(time.Second)	resp.Write([]byte("ProcessId: " + strconv.Itoa(os.Getpid()) + "\n"))}func main() {	listener, _ := net.Listen("tcp", "127.0.0.1:9001")	srv := new(FastCGIServer)	fcgi.Serve(listener, srv)}
           

通過如下指令得到一個簡單的fastcgi 二進制檔案。

1
           
go build -o fastcgi fastcgi.go
           

生成的fastcgi 就是一個簡單的fastcgi 服務。

2. 修改 supervisor 的配置

修改supervisor 的配置,将fastcgi 服務添加到supervisor 管理,并啟動6個fastcgi 程序。

在supervisord.conf 添加如下配置:

123456789
           
[fcgi-program:fastcgi_test]socket=tcp://127.0.0.1:9001command=/root/test/fastcgiautostart=truestopwaitsecs=1000autorestart=trueuser=rootprocess_name=%(program_name)s_%(process_num)02dnumprocs=6
           

修改完成後,需要重新整理supervisord 的配置,并啟動fastcgi。

12
           
supervisorctl updatesupervisorctl start fastcgi_test:*
           

3. 修改nginx 的配置

Nginx 配置如下:

1234567
           
server {        listen 127.0.0.1:8080;        location / {                include         fastcgi.conf;                fastcgi_pass    127.0.0.1:9001;        }}
           

并通過如下指令重新加載 nginx 配置。

1
           
nginx -s reload
           

4. 做一個簡單的請求實驗

對nginx 重新加載配置後,我們請求8080 端口,看服務的請求情況:

異步 post 10次 (同步不會均勻配置設定)http 請求:

12
           
#  for i in `seq 1 10`; do curl 'http://127.0.0.1:8080/app?helloworld' & done#  ProcessId: 11319ProcessId: 11299ProcessId: 11300ProcessId: 11307ProcessId: 11307ProcessId: 11311ProcessId: 11311ProcessId: 11315ProcessId: 11315ProcessId: 11319
           

結果顯示,http請求被均勻的配置設定到不同的fastcgi 上。

5. 做程序意外退出的實驗

當某個 fastcgi 程序意外退出時(通過手動 kill 程序),supervisor 自動再次啟動一個fastcgi 做為補充(這是supervisor的基本功能),這就實作了PHP-FPM master 程序的主要功能。

實作原理

正常情況下,一個端口隻能被一個程序監聽。但是剛剛看到的情況是,多個fastcgi同時啟動,監聽 9001 端口。這是因為linux 系統中,如果父程序監聽端口拿到監聽的檔案描述符,fork 的子程序可以繼承父程序的檔案描述符,是以多個程序可以監聽同一個端口(php-fpm,nginx 的程序管理均是如此)。

通過pstree 指令我們可以看到supervisord 是父程序,管理了6個fastcgi子程序:

supervisor 子程式退出_Supervisor 的使用和進階 (3)

實作的功能

supervisor 在管理fastcgi 的程序中,和管理普通程序的差别是,supervisord 程序會建立socket 連結,共享給 supervisor 子程序 fastcgi ,但是非fastcgi 的程序不會被共享。

supervisor 子程式退出_Supervisor 的使用和進階 (3)