本文目錄一覽:
- 1、yum安裝php-fom提示依賴包php-common,可是php-common已經裝過,還是安裝不上
- 2、php-fpm 調用哪個php
- 3、php-fpm的工作機制
- 4、服務器程序源代碼分析之二:php-fpm
- 5、php-fpm與php什麼關係
- 6、如何用php-fpm 執行php程序
yum安裝php-fom提示依賴包php-common,可是php-common已經裝過,還是安裝不上
版本兼容問題,你的php-fpm依賴的是php-common5.4.16-42的版本,你已經安裝的版本是5.4.16-45
後面的小版本號不一致,要求的是-42,已安裝的是-45,依賴檢查判斷為可能存在不兼容,你需要手動卸載掉已安裝的-45的版本後再yum安裝php-fpm
php-fpm 調用哪個php
您好,我來為您解答:
PHP-FPM是一個PHP FastCGI管理器,是只用於PHP的。
PHP-FPM其實是PHP源代碼的一個補丁,旨在將FastCGI進程管理整合進PHP包中。必須將它patch到你的PHP源代碼中,在編譯安裝PHP後才可以使用。
新版PHP已經集成php-fpm了,不再是第三方的包了,推薦使用。PHP-FPM提供了更好的PHP進程管理方式,可以有效控制內存和進程、可以平滑重載PHP配置,比spawn-fcgi具有更多優點,所以被PHP官方收錄了。在./configure的時候帶 –enable-fpm參數即可開啟PHP-FPM,其它參數都是配置php的,轉載,僅供參考。
如果我的回答沒能幫助您,請繼續追問。
php-fpm的工作機制
概括來說,fpm 的實現就是創建一個 master 進程,在 master 進程中創建並監聽 socket,然後 fork 出多個子進程,這些子進程各自 accept 請求,子進程的處理非常簡單,它在啟動後阻塞在 accept 上,有請求到達後開始讀取請求數據,讀取完成後開始處理然後再返回,在這期間是不會接收其它請求的,也就是說 fpm 的子進程同時只能響應一個請求,只有把這個請求處理完成後才會 accept 下一個請求,這一點與 nginx 的事件驅動有很大的區別,nginx 的子進程通過 epoll 管理套接字,如果一個請求數據還未發送完成則會處理下一個請求,即一個進程會同時連接多個請求,它是非阻塞的模型,只處理活躍的套接字。
fpm 的 master 進程與 worker 進程之間不會直接進行通信,master 通過共享內存獲取 worker 進程的信息,比如 worker 進程當前狀態、已處理請求數等,當 master 進程要殺掉一個 worker 進程時則通過發送信號的方式通知 worker 進程。
fpm 可以同時監聽多個端口,每個端口對應一個 worker pool,而每個 pool 下對應多個 worker 進程,類似 nginx 中 server 概念。
在 php-fpm.conf 中通過[pool name]聲明一個 worker pool:
啟動 fpm 後查看進程:
具體實現上 worker pool 通過fpm_worker_pool_s這個結構表示,多個 worker pool 組成一個單鏈表
接下來看下 fpm 的啟動流程,從main()函數開始:
fpm_init()主要有以下幾個關鍵操作:
(1) fpm_conf_init_main():
解析 php-fpm.conf 配置文件,分配 worker pool 內存結構並保存到全局變量中:fpm_worker_all_pools,各 worker pool 配置解析到fpm_worker_pool_s-config中。
(2)fpm_scoreboard_init_main():
分配用於記錄 worker 進程運行信息的共享內存,按照 worker pool 的最大 worker 進程數分配,每個 worker pool 分配一個fpm_scoreboard_s結構,pool 下對應的每個 worker 進程分配一個fpm_scoreboard_proc_s結構。
(3)fpm_signals_init_main():
這裡會通過socketpair()創建一個管道,這個管道並不是用於 master 與 worker 進程通信的,它只在 master 進程中使用,具體用途在稍後介紹 event 事件處理時再作說明。另外設置 master 的信號處理 handler,當 master 收到 SIGTERM、SIGINT、SIGUSR1、SIGUSR2、SIGCHLD、SIGQUIT 這些信號時將調用sig_handler()處理:
(4)fpm_sockets_init_main()
創建每個 worker pool 的 socket 套接字。
(5)fpm_event_init_main():
啟動 master 的事件管理,fpm 實現了一個事件管理器用於管理 IO、定時事件,其中 IO 事件通過 kqueue、epoll、poll、select 等管理,定時事件就是定時器,一定時間後觸發某個事件。
在fpm_init()初始化完成後接下來就是最關鍵的fpm_run()操作了,此環節將 fork 子進程,啟動進程管理器,另外 master 進程將不會再返回,只有各 worker 進程會返回,也就是說fpm_run()之後的操作均是 worker 進程的。
在 fork 後 worker 進程返回了監聽的套接字繼續 main() 後面的處理,而 master 將永遠阻塞在fpm_event_loop(),接下來分別介紹 master、worker 進程的後續操作。
fpm_run()執行後將 fork 出 worker 進程,worker 進程返回main()中繼續向下執行,後面的流程就是 worker 進程不斷 accept 請求,然後執行 PHP 腳本並返回。整體流程如下:
worker 進程一次請求的處理被劃分為 5 個階段:
worker 處理到各個階段時將會把當前階段更新到fpm_scoreboard_proc_s-request_stage,master 進程正是通過這個標識判斷 worker 進程是否空閑的。
接下來我們來看下 master 是如何管理 worker 進程的,首先介紹下三種不同的進程管理方式:
前面介紹到在fpm_run()中 master 進程將進入fpm_event_loop():
這就是 master 整體的處理,其進程管理主要依賴註冊的幾個事件,接下來我們詳細分析下這幾個事件的功能。
(1)sp[1]管道可讀事件:
在 fpm_init() 階段 master 曾創建了一個全雙工的管道:sp,然後在這裡創建了一個 sp[0] 可讀的事件,當 sp[0] 可讀時將交由 fpm_got_signal() 處理,向 sp[1] 寫數據時 sp[0] 才會可讀,那麼什麼時機會向 sp[1] 寫數據呢?前面已經提到了:當 master 收到註冊的那幾種信號時會寫入 sp[1] 端,這個時候將觸發 sp[0] 可讀事件。
這個事件是 master 用於處理信號的,我們根據 master 註冊的信號逐個看下不同用途:
具體處理邏輯在 fpm_got_signal() 函數中,這裡不再羅列。
(2)fpm_pctl_perform_idle_server_maintenance_heartbeat():
這是進程管理實現的主要事件,master 啟動了一個定時器,每隔 1s 觸發一次,主要用於 dynamic、ondemand 模式下的 worker 管理,master 會定時檢查各 worker pool 的 worker 進程數,通過此定時器實現 worker 數量的控制,處理邏輯如下:
(3)fpm_pctl_heartbeat():
這個事件是用於限制 worker 處理單個請求最大耗時的,php-fpm.conf 中有一個request_terminate_timeout的配置項,如果 worker 處理一個請求的總時長超過了這個值那麼 master 將會向此 worker 進程發送kill -TERM信號殺掉 worker 進程,此配置單位為秒,默認值為 0 表示關閉此機制,另外 fpm 打印的 slow log 也是在這裡完成的。
除了上面這幾個事件外還有一個沒有提到,那就是 ondemand 模式下 master 監聽的新請求到達的事件,因為 ondemand 模式下 fpm 啟動時是不會預創建 worker 的,有請求時才會生成子進程,所以請求到達時需要通知 master 進程,這個事件是在fpm_children_create_initial()時註冊的,事件處理函數為fpm_pctl_on_socket_accept(),具體邏輯這裡不再展開,比較容易理解。
原文出處:
服務器程序源代碼分析之二:php-fpm
php作為排名top2 互聯網開發工具,非常流行,可以參考:中國最大的25個網站採用技術選型方案
php這個名稱實際上有兩層含義
直接定義:
php-fpm從php5.3.3開始已經進入到php源代碼包,之前是作為patch存在的
很少人會去讀php本身源代碼,我6年前解決php內存泄露問題的時候做了些研究,最近再查看了一番,發現php的開發者很有誠意,這是一款非常出色的服務器軟件,支持如下
在linux服務器上,如果不設置 events.mechanism ,那麼默認就是採用epoll,所以
php-fpm的IO模型並發處理能力和nginx是完全一致
nginx以性能卓越聞名,大部分程序員都認為php效率低下,看了源代碼,才知道這是傳奇啊
在高性能部署的時候,大家往往會針對性的優化nginx 。我自己之前部署php程序也犯了錯誤,8G內存的server,php-fpm的max children都會設置128+,現在看來太多了,參考nginx的部署:
php-fpm配置為 3倍 cpu core number就可以了
php-fpm穩定性比nginx稍差 這是因為php-fpm內置了一個php解析器,php-fpm進程就和php程序捆綁了,如果php腳本寫得不好,有死循環或者阻塞在某個遠端資源上,會拖累加載它的php-fpm進程
而nginx和後端應用服務器之間通過網絡連接,可以設置timeout,不容易堵死的
php-fpm的fastcgi是短連接 我原以為是長連接的,看了代碼才知道也是短連接,處理一個request就關閉掉
php-fpm接口採用fastcgi 非常遺憾,php-fpm和fastcgi完全綁定了,無法獨立使用 。只能部署在支持http-fcgi協議轉換程序背後(nginx)。其實可以考慮在php-fpm代碼包裏面引入http協議支持,這樣php-fpm可以獨立運行,讓nodejs無話可說
php-fpm等同於OpenResty OpenResty是一個國人開發的nginx模塊,就是在nginx引入lua解釋器. 實際上,它和php-fpm的唯一差別就是一個採用php語法,一個用lua,所以OpenResty要作為nginx增強包使用還可以,要選擇它作為一個主要編程工具,沒有任何必要
從架構上來說,php-fpm已經做到最好,超過大多數 python部署工具,我再也不黑它了
php-fpm與php什麼關係
首先,CGI是幹嘛的?CGI是為了保證web server傳遞過來的數據是標準格式的,方便CGI程序的編寫者
web server(比如說nginx)只是內容的分發者。比如,如果請求/index.html,那麼web server會去文件系統中找到這個文件,發送給瀏覽器,這裡分發的是靜態數據。好了,如果現在請求的是/index.php,根據配置文件,nginx知道這個不是靜態文件,需要去找PHP解析器來處理,那麼他會把這個請求簡單處理後交給PHP解析器。Nginx會傳哪些數據給PHP解析器呢?url要有吧,查詢字符串也得有吧,POST數據也要有,HTTP header不能少吧,好的,CGI就是規定要傳哪些數據、以什麼樣的格式傳遞給後方處理這個請求的協議。仔細想想,你在PHP代碼中使用的用戶從哪裡來的。
當web server收到/index.php這個請求後,會啟動對應的CGI程序,這裡就是PHP的解析器。接下來PHP解析器會解析php.ini文件,初始化執行環境,然後處理請求,再以規定CGI規定的格式返回處理後的結果,退出進程。web server再把結果返回給瀏覽器。
好了,CGI是個協議,跟進程什麼的沒關係。那fastcgi又是什麼呢?Fastcgi是用來提高CGI程序性能的。
提高性能,那麼CGI程序的性能問題在哪呢?”PHP解析器會解析php.ini文件,初始化執行環境”,就是這裡了。標準的CGI對每個請求都會執行這些步驟(不閑累啊!啟動進程很累的說!),所以處理每個時間的時間會比較長。這明顯不合理嘛!那麼Fastcgi是怎麼做的呢?首先,Fastcgi會先啟一個master,解析配置文件,初始化執行環境,然後再啟動多個worker。當請求過來時,master會傳遞給一個worker,然後立即可以接受下一個請求。這樣就避免了重複的勞動,效率自然是高。而且當worker不夠用時,master可以根據配置預先啟動幾個worker等着;當然空閑worker太多時,也會停掉一些,這樣就提高了性能,也節約了資源。這就是fastcgi的對進程的管理。
那PHP-FPM又是什麼呢?是一個實現了Fastcgi的程序,被PHP官方收了。
大家都知道,PHP的解釋器是php-cgi。php-cgi只是個CGI程序,他自己本身只能解析請求,返回結果,不會進程管理(皇上,臣妾真的做不到啊!)所以就出現了一些能夠調度php-cgi進程的程序,比如說由lighthttpd分離出來的spawn-fcgi。好了PHP-FPM也是這麼個東東,在長時間的發展後,逐漸得到了大家的認可(要知道,前幾年大家可是抱怨PHP-FPM穩定性太差的),也越來越流行。
網上有的說,fastcgi是一個協議,php-fpm實現了這個協議有的說,php-fpm是fastcgi進程的管理器,用來管理fastcgi進程的,對。php-fpm的管理對象是php-cgi。但不能說php-fpm是fastcgi進程的管理器,因為前面說了fastcgi是個協議,似乎沒有這麼個進程存在,就算存在php-fpm也管理不了他(至少目前是)。 有的說,php-fpm是php內核的一個補丁
以前是對的。因為最開始的時候php-fpm沒有包含在PHP內核裏面,要使用這個功能,需要找到與源碼版本相同的php-fpm對內核打補丁,然後再編譯。後來PHP內核集成了PHP-FPM之後就方便多了,使用–enalbe-fpm這個編譯參數即可。
有的說,修改了php.ini配置文件後,沒辦法平滑重啟,所以就誕生了php-fpm,是的,修改php.ini之後,php-cgi進程的確是沒辦法平滑重啟的。php-fpm對此的處理機制是新的worker用新的配置,已經存在的worker處理完手上的活就可以歇着了,通過這種機制來平滑過度。
還有的說PHP-CGI是PHP自帶的FastCGI管理器,那這樣的話幹嗎又弄個php-fpm出
不對。php-cgi只是解釋PHP腳本的程序而已。
如何用php-fpm 執行php程序
第一步:確定php-fpm配置文件的路徑,執行:
ps -aux | grep php-fpm
圖中,我的是在 /soft/php7/etc/ 目錄,在這個目錄下有個php-fpm.d目錄,打開這個目錄後,找到文件,修改該文件里:
user = www
group = www
原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-hk/n/233695.html