supervisor nginx_Supervisor 的使用和进阶 (3)
在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次方, 根據機器配置設置, 默認是端口最大監(jiān)聽量socket_owner = chrism:wheel ; 監(jiān)聽用戶組socket_mode = 0700 ; 監(jiān)聽模式 |
下面通過一個簡單的例子說明fastcgi的管理模式。
1. 實現一個簡單的fastcgi 服務
通過監(jiān)聽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:* |
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 進程的主要功能。
實現原理
正常情況下,一個端口只能被一個進程監(jiān)聽。但是剛剛看到的情況是,多個fastcgi同時啟動,監(jiān)聽 9001 端口。這是因為linux 系統(tǒng)中,如果父進程監(jiān)聽端口拿到監(jiān)聽的文件描述符,fork 的子進程可以繼承父進程的文件描述符,因此多個進程可以監(jiān)聽同一個端口(php-fpm,nginx 的進程管理均是如此)。
通過pstree 命令我們可以看到supervisord 是父進程,管理了6個fastcgi子進程:
實現的功能
supervisor 在管理fastcgi 的進程中,和管理普通進程的差別是,supervisord 進程會創(chuàng)建socket 鏈接,共享給 supervisor 子進程 fastcgi ,但是非fastcgi 的進程不會被共享。
總結
以上是生活随笔為你收集整理的supervisor nginx_Supervisor 的使用和进阶 (3)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: tictoc正方形网络模型_反卷积:可视
- 下一篇: c++ char 转 string_4.