請關注公衆号: 搬磚程式員帶你飛,學習更多内容。
本文主要介紹 supervisor 對 fastcgi 程序的管理
fastcgi 程序的管理
在php 中,php-fpm 有主程序來管理和維護子程序的數量。但是并不是所有的服務都有類似的主程序來做子程序的維護。
在很多其他語言中,有很多比較有名的fastcgi 服務,例如py 的flup, c++ 實作的 FastCgi++等。如果這些服務在單機中啟動多個程序(極有可能),那如何管理這些程序是個比較頭疼的問題。 supervisor 的fastcgi 管理的功能就是為了解決這個問題。
配置
在普通程序的基礎上,添加如下配置:
[fcgi-program:x]
socket = "tcp://10.3.2.10:9002" // 支援 tcp ,或者 Unix socket
socket_backlog = 1024 // 2 的N次方, 根據機器配置設定, 預設是端口最大監聽量
socket_owner = chrism:wheel // 監聽使用者組
socket_mode = 0700 // 監聽模式
舉個例子
實作一個簡單的fastcgi 服務
通過監聽127.0.0.1:9001 端口對 fastcgi 請求做處理。處理流程為:暫停1s,列印處理的程序id。(為了能看到不同程序做了響應,是以對程序暫停1s處理,并列印程序id。)
// fastcgi.go
package main
import (
"net"
"net/http"
"net/http/fcgi"
"os"
"strconv"
"time"
)
type FastCGIServer struct{}
// 暫停1s, 列印辨別的程序id
func (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 二進制檔案。通過監聽127.0.0.1:9001 端口做fastcgi 處理。處理内容為暫停1s,并列印處理的程序id。(為了能看到不同程序做了響應,是以對程序暫停1s處理,并列印程序id。)
go build -o fastcgi fastcgi.go
生成的fastcgi 就是一個簡單的fastcgi 服務。功能為暫停1s,并輸出目前程序的程序ID。
修改 supervisor 的配置
修改supervisor 的配置,将fastcgi 服務添加到supervisor 管理,并啟動6個fastcgi 程序。
在supervisord.conf 添加如下配置:
[fcgi-program:fastcgi_test]
socket=tcp://127.0.0.1:9001
command=/root/test/fastcgi
autostart=true
stopwaitsecs=1000
autorestart=true
user=root
process_name=%(program_name)s_%(process_num)02d
numprocs=6
修改完成後,需要重新整理supervisord 的配置,并啟動fastcgi。
supervisorctl update
supervisorctl start fastcgi_test:* # 因為啟動的fastcgi 有多個,是以需要加 :*
修改nginx 的配置
Nginx 配置如下:
server {
listen 127.0.0.1:8080;
location / {
include fastcgi.conf;
fastcgi_pass 127.0.0.1:9001;
}
}
并通過如下指令重新加載 nginx 配置。
nginx -s reload
做一個簡單的請求實驗
對nginx 重新加載配置後,我們請求8080 端口,看服務的請求情況:
post 10次請求:
# 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
傳回結果,processId 被均勻的分到不同的fastcgi 上。
當某個 fastcgi_test 意外退出時,supervisor 可以再次啟動一個fastcgi_test 做補充,這就實作了PHP-FPM master 程序的主要功能。
實作原理
我們知道,正常情況下,一個端口隻能被一個程序監聽。但是剛剛看到的情況是,多個fastcgi同時啟動,監聽 9001 端口。這是因為linux 系統中,如果父程序監聽端口後,fork 的子程序可以繼承父程序的檔案描述符,是以多個程序可以監聽同一個端口。
通過pstree 指令我們可以看到:
實作的功能
supervisor 在管理fastcgi 的程序中,和管理普通程序的差别是,supervisord 程序會建立socket 連結,共享給 supervisor fork 的fastcgi 程序,但是非fastcgi 的程序不會被共享。
supervisor 的其他介紹:
有疑問加站長微信聯系(非本文作者)