apache2.4 + php-fpm

背景

最近移植 apache2.4 + php5 到 H3 ,一般是apache 支持 php 是通過mod_php 方式的,即需要
LoadModule php5_module modules/libphp5.so
但是要編譯出 給apache 用的 libphp5.so 的話,編譯 php5 時需要 configure 指定 --with-apxs2 = /usr/local/httpd/apache/bin/apxs 參數,但是在交叉編譯的情況下apxs 是無法運行的,所以無法編譯出 libphp5.so 。除非放到H3板子上進行編譯,那樣的話肯定不妥!

——那還有什麼辦法可以讓 apache 支持 php 嗎? 有的。

Sapi通過通過一系列的接口,使得外部應用可以和PHP交換數據並可以根據不同應用特點實現特定的處理方法,我們常見的一些sapi有:

  • apache2handler:這是以apache作爲webserver,採用mod_PHP模式運行時候的處理方式,也是現在應用最廣泛的一種。

  • cgi:這是webserver和PHP直接的另一種交互方式,也就是大名鼎鼎的fastcgi協議,在最近幾年fastcgi+PHP得到越來越多的應用,也是異步webserver所唯一支持的方式。

  • cli:命令行調用的應用模式

apache 與 php 的關係

apache 是一個webserver ,主要工作是接收請求,返回數據,本身不具備解析.php 文件的能力,這就需要藉助 mod_php 或者 使用 cgi 協議與 php 解析進程進行數據交互。

php-fpm 的作用

實現fastcgi 協議,解析.php 文件,並返回解析後的內容。
(可以理解爲 fastcgi 協議 是cgi 協議的改良版)

php-fpm 的編譯

  • From release 5.3.3 onwards, PHP now includes the fastCGI process manager (php-fpm) in the stock source code.

  • Your distribution or OS will either include it in the stock PHP package, or make it available as an add-on package; you can build it from source by adding --enable-fpm to your ./configure options.

./configure 的時候添加 --enable-fpm 選項,就能編譯出php-fpm。

php-fpm 的啓動腳本

/etc/init.d/php5-fpm
常用啓動方法(默認開機啓動)
/etc/init.d/php5-fpm start
/etc/init.d/php5-fpm restart
/etc/init.d/php5-fpm stop

查看是否啓動成功:ps | grep php-fpm

ps | grep php-fpm
 3072 root     96272 S    php-fpm: master process (/etc/php5-fpm.conf)
 3073 nobody   96272 S    php-fpm: pool www
 3074 nobody   96272 S    php-fpm: pool www
 3224 root      3080 S    grep php-fpm

php-fpm 的配置文件

/etc
├── php5-fpm.conf
├── php5-fpm.d
│ └── www.conf
├── php.ini

配置修改要點:

  • www.conf
    注意 user group 要與 apache 的 httpd.conf 中的一致
    [www]
    user = nobody
    group = nogroup
    listen = 127.0.0.1:9000
    listen.owner = nobody
    listen.group = nogroup
    listen.mode = 0666
    pm = dynamic
    

apache 端配置

httpd.conf
修改要點:

  • mpm 需要改成 event 模式

    # LoadModule mpm_prefork_module modules/mod_mpm_prefork.so
    #LoadModule mpm_worker_module modules/mod_mpm_worker.so
    LoadModule mpm_event_module modules/mod_mpm_event.so
    
  • 確保啓用了 mod_proxy_fcgi

    LoadModule proxy_module modules/mod_proxy.so
    LoadModule proxy_fcgi_module modules/mod_proxy_fcgi.so
    
  • 添加支持 index.php

    DirectoryIndex index.html
    DirectoryIndex index.php
    
  • 添加 vhost 並 使用 ProxyPassMatch

    <VirtualHost *:80>                                                      
     ServerAdmin [email protected]                                           
     DocumentRoot "/usr/share/htdocs"                                        
     ServerName localhost                    
     <Directory "/usr/share/htdocs">
      Options None
      Require all granted                                            
     </Directory>                               
     ProxyRequests Off
     ProxyPassMatch "^/(.*\.php(/.*)?)$" "fcgi://127.0.0.1:9000/usr/share/htdocs/$1"
    </VirtualHost> 
    

    注意 ProxyPassMatch “^/(.*\.php(/.*)?)$” “fcgi://127.0.0.1:9000/usr/share/htdocs/$1” 中的
    127.0.0.1:9000 後面的路徑要與 DocumentRoot 一致。
    其作用大致是 所有以 .php 結尾的請求都轉發給 127.0.0.1:9000 ,php-fpm 會一直監聽127.0.0.1:9000,並解析.php 文件。

測試驗證

在 /usr/share/htdocs 下寫一個index.php 用最簡單的phpinfo()函數。

<?php 
 phpinfo();
?>

並將原來的index.html 改名或者刪掉:

# ls /usr/share/htdocs/
index.hide  index.php

打開瀏覽器輸入ip 地址,正常的話可以打開看到這樣的頁面。
在這裏插入圖片描述

遇到的問題:

無法打開頁面,查看/var/log/error_log
AH01071: Got error 'Unable to open primary script: /usr/share/htdocs/index.php (No such file or directory)\n’

找不到文件?
網上找了很多資料,大多都是說只要保證 ProxyPassMatch 那行 127.0.0.1:9000 後的路徑地址與DocumentRoot 一致,www.conf 裏的 user group 要與http.conf 中的一致就可以了。可是我的就是不行!

最終我無意中發現吧 index.php 放到 /www 裏,OK 了!這是爲什麼呢?
“fcgi://127.0.0.1:9000/usr/share/htdocs/index.php” 最終卻是要讀取/www/index.php ? 這是個什麼奇怪的設定?

查找相關設置發現 在php.ini 中設置了 doc_root = “/www” ,
有兩種解決方法:

  • 方法1.建立軟連接 /www 指向 /usr/share/htdocs
    ln -sf /usr/share/htdocs /www
  • 方法2. 直接改 doc_root
    php.ini 中的
    doc_root = “/www”
    改爲
    doc_root = “/usr/share/htdocs”



參考資料:

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章