1. 程式人生 > >PHP底層原理——[面試系列]

PHP底層原理——[面試系列]

SAPI,即伺服器應用程式設計介面,實質上就是定義了一個統一的介面,它的核心就是一個結構體sapi_module_struct。SAPI提供給了外部應用跟php通訊的管道,這個外部應用包括不限於Apache,httpd,liunx終端等,sapi通俗的講就是php-cgi,php-cli,mod_php等,php就是php核心。


  • 什麼是CGI
  • 什麼是FastCGI
  • 什麼是PHP-Fpm
  • 什麼是PHP-cgi
  • Nginx和php-fpm是怎麼通訊的?
  • 什麼是代理和反向代理?
  • php-fpm支援三種執行模式
  • 如何優化?

php-fpm 三種執行方式:
第一種:是pm = static,始終保持一個固定數量的子程序,這個數由pm.max_children定義,這種方式很不靈活,也通常不是預設的。

第二種:是pm = dynamic,他是這樣的,啟動時,會產生固定數量的子程序(由pm.start_servers控制)可以理解成最小子程序數,而最大子程序數則由pm.max_children去控制,OK,這樣的話,子程序數會在最大和最小數範圍中變化,還沒有完,閒置的子程序數還可以由另2個配置控制,分別是pm.min_spare_servers和pm.max_spare_servers,也就是閒置的子程序也可以有最小和最大的數目,而如果閒置的子程序超出了pm.max_spare_servers,則會被殺掉。

可以看到,pm = dynamic模式非常靈活,也通常是預設的選項。但是,dynamic模式為了最大化地優化伺服器響應,會造成更多記憶體使用,因為這種模式只會殺掉超出最大閒置程序數(pm.max_spare_servers)的閒置程序,比如最大閒置程序數是30,最大程序數是50,然後網站經歷了一次訪問高峰,此時50個程序全部忙碌,0個閒置程序數,接著過了高峰期,可能沒有一個請求,於是會有50個閒置程序,但是此時php-fpm只會殺掉20個子程序,始終剩下30個程序繼續作為閒置程序來等待請求,這可能就是為什麼過了高峰期後即便請求數大量減少伺服器記憶體使用卻也沒有大量減少,也可能是為什麼有些時候重啟下伺服器情況就會好很多,因為重啟後,php-fpm的子程序數會變成最小閒置程序數,而不是之前的最大閒置程序數。

第三種:就是這篇文章中提到的pm = ondemand模式,這種模式和pm = dynamic相反,把記憶體放在第一位,他的工作模式很簡單,每個閒置程序,在持續閒置了pm.process_idle_timeout秒後就會被殺掉,有了這個模式,到了伺服器低峰期記憶體自然會降下來,如果伺服器長時間沒有請求,就只會有一個php-fpm主程序,當然弊端是,遇到高峰期或者如果pm.process_idle_timeout的值太短的話,無法避免伺服器頻繁建立程序的問題,因此pm = dynamic和pm = ondemand誰更適合視實際情況而定。

php 是如何儲存變數的?
什麼是引用計數?
答:每個php變數存在一個叫"zval"的變數容器中。一個zval變數容器,除了包含變數的型別和值,還包括兩個位元組的額外資訊。第一個是"is_ref",是個bool值,用來標識這個變數是否是屬於引用集合(reference set)。通過這個位元組,php引擎才能把普通變數和引用變數區分開來,由於php允許使用者通過使用&來使用自定義引用,zval變數容器中還有一個內部引用計數機制,來優化記憶體使用。第二個額外位元組是"refcount",用以表示指向這個zval變數容器的變數(也稱符號即symbol)個數。所有的符號存在一個符號表中,其中每個符號都有作用域(scope),那些主指令碼(比如:通過瀏覽器請求的的指令碼)和每個函式或者方法也都有作用域。