LNMP的併發考慮與資源分配

2021-07-14 23:25:30 字數 4699 閱讀 3186

phper當被問到你的程式效能如何?程式的併發可以達到多少?程式的瓶頸在哪兒?為了滿足業務需求應該購買多少臺伺服器?負載均衡中php應用伺服器需要多少臺?

可能這些問題在面試中會設定乙個應用的場景及一些前提條件,讓面試的人去設計,並提出看法建議,能夠回答得很好的人還是比較少的。

今天我們來談談lnmp的併發考慮和資源分配。

lnmp中的n是nginx充當web server

內容的分發者,會在檔案系統找到相應的檔案,就返回給瀏覽器,如:nginx。如果是靜態的檔案,就可以直接返回,但是如果是index.php需要解析並執行的指令碼檔案時,web server就無力了,需要將請求**給相應的指令碼語言的解析器來解釋並執行,最終將程式的執行結果,返回給web server,再返回給瀏覽器。

lnmp中的p是php充當後端的邏輯處理程式

那麼php與nginx的常規協作方式是如何的呢?需要我們明確幾個概念

cgi通用閘道器介面,是http協議中描述的,web server與後端處理程式程序間通訊的協議

php-cgi

php實現了cgi協議,使得web server與php共同完成乙個動態網頁的請求響應

fastcgi

是為了解決cgi效能問題,而規範的另外一種協議,為什麼說解決cgi效能問題,因為在面對各大中型**的業務需求中,cgi程式表現得越來越無力,因為cgi程式在每次接收到請求時都需要啟動新的程序,並初始化環境,然後執行程式,具體的協議內容,在此不引述。

php-fpm

實現了fastcgi協議,是php-cgi的程序管理器,解決高併發**的效能問題。

在最終回答lnmp的併發考慮與資源分配還需要明確的幾個概念

併發一般由單位內完成的請求數來衡量,如,每秒事務數(tps),每秒http請求數(hps),每秒查詢數(qps)。通常情況下,我們說php的併發,都是指一秒內php完成的動態請求的次數。如某**高峰期的動態請求併發為5000每秒,這個數字不算太高,但也不低。一般日活躍使用者數在1000萬-5000萬的**應用才能達到這個級別。

效能一般是指應用程式的處理速度,如果php的應用程式,開啟乙個頁面(執行乙個指令碼程式)通常需要在50-100ms完成,這對程式的效能要求還是比較高的。但是這還僅僅只是程式處理,php處理完成之後,還要交給web server,web server再將資料返回瀏覽器,這中間會有乙個網路延遲,通常網路正常的情況下,需要大約100ms,最終乙個動態網頁的請求大約200ms(理想的情況下)可以到達使用者瀏覽器端(僅僅是乙個html結構)。

php-fpm程序數

按照上面的描述,併發為5000每秒,每個請求完成大約200ms(具體頁面要具體分析,這裡只是乙個理想值),如果只有5臺php應用程式伺服器,那麼每台機器平均為併發1000每秒,如果是使用nginx+php-fpm的架構,php-fpm的php-cgi程序管理器的配置應該如何呢?我計算的結果為(具體的配置項說明在後文):

pm=static

pm.max_children=100

上面的100是如何得來的,由於機器平均併發為1000每秒,每個動態請求的處理時間為100ms,也就是說1個php-fpm的worker處理程序在1秒內可以處理10個請求,100個php-fpm的worker處理程序,就可以處理1000個請求。

當然需要結合伺服器硬體資源來進行配置,如果配置不當,很容易在請求高峰期或者流量猛增導致伺服器宕機。

網路頻寬

網路頻寬也會是乙個重要的因素,如果你的服務處理很強,但是使用者的請求和響應不能及時到達也是白忙活,這個引數如何計算呢?

併發5000每秒,每個請求的輸出為20k,則5000x20k=100000k=100m

這就要求你的公網負載均衡器外網出口頻寬至少要達到100m

記憶體上述中100個php-fpm的worker處理程序,理論上如果伺服器只執行php-fpm,那麼我們可以將伺服器記憶體的一半分配給php-fpm,通常情況下,我們可以認為乙個php-fpm的worker處理程序占用記憶體20m,那麼100x20m=2g,也就是說明伺服器的記憶體大約為4g

cpu由於php-fpm是乙個多程序的模型應用,cpu程序排程消耗也是很大的,並且php應用程式有問題也會導致cpu佔用率高,這就沒有量化的指標,需要具體情況具體分析了。但是有乙個小建議,可以部署乙個crontab每隔一分鐘檢測cpu佔用率超過多少就kill掉相應的php-fpm的worker處理程序。

如果nginx與php在同一臺機器,nginx與php-fpm使用unix域套接字代替tcp socke進行通訊,這個配置挺關鍵的,純echo的ab測試,採用unix域套接字每秒請求數提公升10%-20%

即nginx中配置:

fastcgi_pass unix:/data/server/var/php/php-fpm.sock;
php-fpm.conf中配置:

listen = /data/server/var/php/php-fpm.sock
最後遇到很多同學對php-fpm的程序管理器的核心配置不太了解,下面是我翻譯的配置說明:

php-fpm配置項

pm程序管理器以控制子程序的數量,可能的值有

static                        乙個固定的值,由pm.max_children指定

dynamic 動態的(工作方式和apache的prefork模式一致),但是保持至少乙個,由

pm.max_children 在同一時間最大的程序數

pm.start_servers php-fpm啟動時開啟的等待請求到來的程序數

pm.min_spare_servers 在空閒狀態下,執行的最小程序數,如果小於此值,會建立新的程序

pm.max_spare_servers 在空閒狀態下,執行的最大程序數,如果大於此值,會kill部分程序

ondemand 啟動時不會建立程序,當請求達到時建立子程序處理請求

pm.max_children 在同一時間最大的程序數

pm.process_idle_timeout 空閒多少秒之後程序會被kill

pm = static
pm.max_children

在同一時間最大的程序數

pm.max_children = 120
pm.start_servers

php-fpm啟動時開啟的等待請求到來的程序數,預設值為:min_spare_servers + (max_spare_servers - min_spare_servers) / 2

pm.start_servers = 80
pm.min_spare_servers

在空閒狀態下,執行的最小程序數,如果小於此值,會建立新的程序

pm.min_spare_servers = 60
pm.max_spare_servers

在空閒狀態下,執行的最大程序數,如果大於此值,會kill部分程序

pm.max_spare_servers = 120
空閒多少秒之後程序會被kill,預設為10s

pm.process_idle_timeout = 10s
pm.max_requests

每個程序處理多少個請求之後自動終止,可以有效防止記憶體溢位,如果為0則不會自動終止,預設為0

pm.max_requests = 5000
註冊的uri,以展示php-fpm狀態的統計資訊

pm.status_path = /status
其中統計頁面資訊有:

pool                         程序池名稱

process manager 程序管理器名稱(static, dynamic or ondemand)

start time php-fpm啟動時間

start since php-fpm啟動的總秒數

accepted conn 當前程序池接收的請求數

listen queue 等待佇列的請求數

max listen queue 自啟動以來等待佇列中最大的請求數

listen queue len 等待連線socket佇列大小

idle processes 當前空閒的程序數

active processes 活動的程序數

total processes 總共的程序數(idle+active)

max active processes 自啟動以來活動的程序數最大值

max children reached 達到最大程序數的次數

ping url,可以用來測試php-fpm是否存活並可以響應

ping.path = /ping
ping url的響應正文

ping.response = pong

LNMP的併發配置和資源分配

php程式效能如何?程式的併發可以達到多少?程式的瓶頸在哪兒?為了滿足業務需求應該購買多少臺伺服器?負載均衡中php應用伺服器需要多少臺?lnmp中的n是nginx充當web server 內容的分發者,會在檔案系統找到相應的檔案,就返回給瀏覽器,如 nginx。如果是靜態的檔案,就可以直接返回,但...

PCB與程序分配資源

pcb progress control block 程序控制塊。這裡先不討論pcb是什麼,其實程序這個概念本身就是乙個很難理解的概念,當乙個可執行程式被系統執行了以後,就變成了乙個程序。那麼這個程序中到底有什麼東西呢,系統究竟給這個程序分配了哪些資源?另外,程序在記憶體中的儲存是怎麼樣的?對於乙個...

FPGA管腳分配需要考慮的因數

在晶元的研發環節,fpga驗證是其中的重要的組成部分,如何有效的利用 fpga 的資源,管腳分配也是必須考慮的乙個重要問題。一般較好的方法是在綜合過程中通過時序的一些約 束讓對應的工具自動分配,但是從研發的時間段上來考慮這種方法往往是不可取的,rtl 驗證與驗證板設計必須是同步進行的,在驗證 出來時...