:::

7-2 Worker 模式

worker使用了多進程和多線程的混合模式。它也預先產生幾個子進程(數量比較少),然後每個子進程創建一些線程,同時包括一個監聽線程。每個請求過來,會被分配到1個線程來服務。

線程比起進程會更輕量,因為線程通常會共享父進程的內存空間,因此,內存的佔用會減少一些。在高並發的場景下,因為比起prefork有更多的可用線程,表現會更優秀一些。

  • 優點:佔據更少的內存,高並發下表現更優秀。
  • 缺點:必須考慮線程安全的問題,因為多個子線程是共享父進程的內存地址的。如果使用keep-alive的長連接方式,某個線程會一直被佔據,也許中間幾乎沒有請求,需要一直等待到超時才會被釋放。如果過多的線程,被這樣佔據,也會導致在高並發場景下的無服務線程可用。(該問題在prefork模式下,同樣會發生)
    註:keep-alive的長連接方式,是為了讓下一次的socket通信復用之前創建的連接,從而,減少連接的創建和銷毀的系統開銷。保持連接,會讓某個進程或者線程一直處於等待狀態,即使沒有數據過來。
  1. 更新套件庫
    apt-get update
  2. 升級套件
    apt-get upgrade
  3. 安裝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 
  4. 關閉mpm_prefork 相關模組(php版本請自行調整)並開啟 mpm_worker 相關模組 並啟用 php-fpm 設定,最後重啟apache使之生效
    a2dismod php7.0 mpm_prefork
    a2enmod mpm_worker actions
    a2enconf php7.0-fpm
    systemctl restart apache2
  5. 設定 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
  6. 重啟 php-fpm 後 php.ini 才會生效,先找出 php-fpm: master process 的程序編號
    ps aux|grep php-fpm
  7. 然後根據程序編號執行以下指令即可重啟 php-fpm
    kill -USR2 程序編號
  8. 編輯 mpm_worker 設定檔
    vi /etc/apache2/mods-available/mpm_worker.conf
  9. 建議內容如下:
    <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 )
  10. Worker模式下所能同時處理的請求總數=子進程總數xThreadsPerChild ,請求總數應該 >= MaxRequestWorkers。
  11. 如果負載很大,現有的子進程數不能滿足時,控制進程會派生新的子進程。
  12. 默認最大的子進程總數是16,加大時 也需要顯式聲明ServerLimit(最大值是20000)
  13. 需要注意的是,如果顯式聲明了ServerLimit,那麼它乘以 ThreadsPerChild的值必須大於等於MaxRequestWorkers,而且MaxRequestWorkers必須是ThreadsPerChild的整數倍,否則 Apache將會自動調節到一個相應值。
  14. 最後重新啟動Apache
    systemctl restart apache2
  15. 修改 /uploads/.htaccess
    vi /var/www/html/uploads/.htaccess
  16. 刪掉 php_flag engine off,並在最後加入:
    <Files "*.php">
      SetHandler none
      SetHandler default-handler
      Options -ExecCGI
      RemoveHandler .php
    </Files>
  17. 日後若要改回mpm_prefork模式的話,則反過來做即可
    a2dismod mpm_worker actions
    a2enmod php7.0 mpm_prefork
    systemctl restart apache2
  18. 記得刪掉php-fpm程序
     ps aux|grep php-fpm|awk '{print $2}'|xargs kill -9


參考自:https://www.jianshu.com/p/1e7273aa129f


:::

書籍目錄

展開 | 闔起

QR Code 區塊

http%3A%2F%2Fcampus-xoops.tn.edu.tw%2Fmodules%2Ftad_book3%2Fpage.php%3Ftbdsn%3D1350

計數器

今天: 869869869
昨天: 2865286528652865
總計: 3222507322250732225073222507322250732225073222507