1. 程式人生 > >apache相關補充

apache相關補充

空閑 後處理 內置 ssr 依次 amp 返回結果 httpd apache 版本

apache相關補充

sendfile機制

    1)不用sendfile的傳統網絡傳輸過程:
        read(file, tmp_buf, len)
        write(socket, tmp_buf, len)
    2)硬盤 >> kernel buffer >> user buffer >> kernel socket buffer >>  協議棧
    3)一般網絡應用通過讀硬盤數據,寫數據到socket來完成網絡傳輸, 底層執行過程:
        1>系統調用 read() 產生一個上下文切換:從 user mode 切換到 kernel mode,然後 DMA 執行拷貝,把文件數據從硬盤讀到一個 kernel buffer 裏。
        2>數據從 kernel buffer 拷貝到 user buffer,然後系統調用 read() 返回,這時又產生一個上下文切換:從kernel mode 切換到 user mode。
        3>系統調用 write() 產生一個上下文切換:從 user mode 切換到 kernel mode, 然後把步驟2讀到 user buffer 的數據拷貝到 kernel buffer(數據第2 次拷貝到kernel buffer),不過這次是個不同的 kernel buffer,這個 buffer和 socket相關聯。
        4>系統調用 write() 返回,產生一個上下文切換:從 kernel mode 切換到 user mode( 第4 次切換), 然後DMA從 kernel buffer 拷貝數據到協議棧(第4次拷貝)
        上面4個步驟有4次上下文切換,有4次拷貝,如果能減少切換次數和拷貝次數將會有效提升性能
    4)在kernel 2.0+ 版本中,系統調用 sendfile() 就是用來簡化上面步驟提升性能的。sendfile() 不但能減少切換次數而且還能減少拷貝次數
    5)用 sendfile() 來進行網絡傳輸的過程:
        sendfile(socket, file, len);
        硬盤 >> kernel buffer (快速拷貝到kernel socket buffer)>>  協議棧
        1>系統調用 sendfile() 過 通過 DMA 到 把硬盤數據拷貝到 kernel buffer被 ,然後數據被 kernel 直接拷貝到另外一個與 socket 相關的 kernel buffer有 。這裏沒有 user mode 和 kernel mode  之間的切換,在 kernel 中直接完成了從一個 buffer 到另一個 buffer的拷貝。
        2>DMA把數據從 kernel buffer 直接拷貝給協議棧,沒有切換,也不需要數據從 user mode 拷貝到 kernel mode ,因為數據就在kernel 裏。

反響代理功能

    1)啟用反向代理
        ProxyPass "/" "http://www.example.com/"
        ProxyPassReverse "/" "http://www.example.com/"
    2)特定URL反向代理
        ProxyPass "/images" "http://www.example.com/"
        ProxyPassReverse "/images" http://www.example.com/
    3)示例:
        <VirtualHost *>
            ServerName www.magedu.com
            ProxyPass / http://localhost:8080/
            ProxyPassReverse / http://localhost:8080/
        </VirtualHost>

ARP

    APR(Apache portable Run-time libraries ,Apache 可移植運行庫) 主要為上層的應用程序提供一個可以跨越多操作系統平臺使用的底層支持接口庫。
    在早期的Apache 版本中,應用程序本身必須能夠處理各種具體操作系統平臺的細節,並針對不同的平臺調用不同的處理函數
    隨著Apache 的進一步開發,Apache 組織決定將這些通用的函數獨立出來並發展成為一個新的項目。
    這樣,APR 的開發就從Apache 中獨立出來,Apache僅僅是使用 APR 而已。
    目前APR 主要還是由Apache 使用,由於APR 的較好的移植性,因此一些需要進行移植的C 程序也開始使用APR,開源項目比如用於服務器壓力測試的Flood loader tester,該項目不僅僅適用於Apache ,http://httpd.apache.org/test/flood

CGI

    CGI是為了保證web server傳遞過來的數據是標準格式的,方便CGI程序的編寫者。
    web server(比如說nginx)只是內容的分發者。
    如果請求/index.html,那麽web server會去文件系統中找到這個文件,發送給瀏覽器,這裏分發的是靜態數據。
    如果請求的是/index.php,根據配置文件,nginx知道這個不是靜態文件,需要去找PHP解析器來處理,那麽他會把這個請求簡單處理後交給PHP解析器。
    Nginx會傳哪些數據給PHP解析器呢?url要有吧,查詢字符串也得有吧,POST數據也要有,HTTP header不能少吧。
    CGI就是規定要傳哪些數據、以什麽樣的格式傳遞給後方處理這個請求的協議。
    當web server收到/index.php這個請求後,會啟動對應的CGI程序,這裏就是PHP的解析器。
    接下來PHP解析器會解析php.ini文件,初始化執行環境,然後處理請求,再以規定CGI規定的格式返回處理後的結果,退出進程,web server再把結果返回給瀏覽器。
    CGI程序的性能問題在哪呢?
        "PHP解析器會解析php.ini文件,初始化執行環境",就是這個初始化執行環境,標準的CGI對每個請求都會執行這些步驟,所以處理每個時間的時間會比較長。

FastCGI

    Fastcgi是用來提高CGI程序性能的。
    首先,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-cgi進程的程序。

總結

    fastcgi是一個協議,php-fpm實現了這個協議。
    修改了php.ini配置文件後,沒辦法平滑重啟,所以就誕生了php-fpm。
        修改php.ini之後,php-cgi進程的確是沒辦法平滑重啟的。
        php-fpm對此的處理機制是新的worker用新的配置,已經存在的worker處理完手上的活就可以停止了,通過這種機制來平滑過度。
    Fastcgi是CGI的升級版,一種語言無關的協議,用來溝通程序(如PHP, Python, Java)和Web服務器(Apache2, Nginx), 理論上任何語言編寫的程序都可以通過Fastcgi來提供Web服務。
    Fastcgi的特點是會在一個進程中依次完成多個請求,以達到提高效率的目的,大多數Fastcgi實現都會維護一個進程池。
    而PHP-fpm就是針對於PHP的,Fastcgi的一種實現,他負責管理一個進程池,來處理來自Web服務器的請求。
    目前,PHP-fpm是內置於PHP的。
    但是PHP-fpm僅僅是個“PHP Fastcgi 進程管理器”, 它仍會調用PHP解釋器本身來處理請求,PHP解釋器(在Windows下)就是php-cgi.exe.

apache相關補充