:::
主內容區域
7-2 Worker 模式
worker使用了多進程和多線程的混合模式。它也預先產生幾個子進程(數量比較少),然後每個子進程創建一些線程,同時包括一個監聽線程。每個請求過來,會被分配到1個線程來服務。
線程比起進程會更輕量,因為線程通常會共享父進程的內存空間,因此,內存的佔用會減少一些。在高並發的場景下,因為比起prefork有更多的可用線程,表現會更優秀一些。
- 優點:佔據更少的內存,高並發下表現更優秀。
- 缺點:必須考慮線程安全的問題,因為多個子線程是共享父進程的內存地址的。如果使用keep-alive的長連接方式,某個線程會一直被佔據,也許中間幾乎沒有請求,需要一直等待到超時才會被釋放。如果過多的線程,被這樣佔據,也會導致在高並發場景下的無服務線程可用。(該問題在prefork模式下,同樣會發生)
註:keep-alive的長連接方式,是為了讓下一次的socket通信復用之前創建的連接,從而,減少連接的創建和銷毀的系統開銷。保持連接,會讓某個進程或者線程一直處於等待狀態,即使沒有數據過來。
- 更新套件庫
apt-get update - 升級套件
apt-get upgrade - 安裝php-fpm
#for Debian 10 Buster apt-get install -y php7.3-fpm #for Debian 9 Stretch apt-get install -y php7.0-fpm #for Debian 8 Jessie apt-get install -y php5.6-fpm - 關閉mpm_prefork 相關模組(php版本請自行調整)並開啟 mpm_worker 相關模組 並啟用 php-fpm 設定,最後重啟apache使之生效
a2dismod php7.0 mpm_prefork a2enmod mpm_worker actions a2enconf php7.0-fpm systemctl restart apache2 - 設定 php.ini,可參考 https://campus-xoops.tn.edu.tw/modules/tad_book3/page.php?tbdsn=220
#for Debian 10 Buster vi /etc/php/7.3/fpm/php.ini #for Debian 9 Stretch vi /etc/php/7.0/fpm/php.ini #for Debian 8 Jessie vi /etc/php/5.6/fpm/php.ini - 重啟 php-fpm 後 php.ini 才會生效,先找出 php-fpm: master process 的程序編號
ps aux|grep php-fpm - 然後根據程序編號執行以下指令即可重啟 php-fpm
kill -USR2 程序編號 - 編輯 mpm_worker 設定檔
vi /etc/apache2/mods-available/mpm_worker.conf - 建議內容如下:
<IfModule mpm_worker_module> StartServers 3 MinSpareThreads 75 MaxSpareThreads 250 ThreadsPerChild 25 MaxRequestWorkers 400 MaxConnectionsPerChild 0 </IfModule>- StartServers:一開始建立的子進程數,每個子進程中包含固定的ThreadsPerChild線程數
- MinSpareServers:最小數量的服務器進程,保存備用(最大預設值是75,達此數就不再主動建立新的進程,如果站點負載較大,可加大此值)
- MaxSpareServers:最大數量的服務器進程,保存備用(最大預設值是250,空閒進程數大於此值時,Apache會自動kill掉一些多餘進程。故不要設得過大,如果站點負載較大,可加大此值)
- ThreadsPerChild: 每個子進程的線程數(預設值是64, 如果負載較大,64也是不夠的。這時要顯式使用 ThreadLimit 指令,它的最大預設值是 20000)
- MaxRequestWorkers: 如果現有子進程中的線程總數不能滿足負載,控制進程將派生新的子進程
- MaxConnectionsPerChild:設置的是每個子進程可處理的請求數(0意味著子進程永不銷毀,但不建議,舊名MaxRequestsPerChild )
- Worker模式下所能同時處理的請求總數=子進程總數xThreadsPerChild ,請求總數應該 >= MaxRequestWorkers。
- 如果負載很大,現有的子進程數不能滿足時,控制進程會派生新的子進程。
- 默認最大的子進程總數是16,加大時 也需要顯式聲明ServerLimit(最大值是20000)
- 需要注意的是,如果顯式聲明了ServerLimit,那麼它乘以 ThreadsPerChild的值必須大於等於MaxRequestWorkers,而且MaxRequestWorkers必須是ThreadsPerChild的整數倍,否則 Apache將會自動調節到一個相應值。
- 最後重新啟動Apache
systemctl restart apache2 - 修改 /uploads/.htaccess
vi /var/www/html/uploads/.htaccess - 刪掉 php_flag engine off,並在最後加入:
<Files "*.php"> SetHandler none SetHandler default-handler Options -ExecCGI RemoveHandler .php </Files> - 日後若要改回mpm_prefork模式的話,則反過來做即可
a2dismod mpm_worker actions a2enmod php7.0 mpm_prefork systemctl restart apache2 - 記得刪掉php-fpm程序
ps aux|grep php-fpm|awk '{print $2}'|xargs kill -9
7-1-1 修改 php.ini