編譯LNMP之nginx+php-fpm

Nginx系列文章:http://www.cnblogs.com/f-ck-need-u/p/7576137.htmlphp


nginx和php-fpm有兩種通訊方式:tcp socket和unix socket。tcp socket能夠跨主機配置nginx+php-fpm,unix socket是同一主機進程間通訊的一種方式,數據的進出都是在內核中進行,效率比tcp socket高,要求php-fpm開啓sock監聽,且不能跨主機配置nginx+php-fpm。所以,若是nginx+php-fpm在同一主機上是,建議使用unix socket的鏈接通訊方式。html

1. 編譯nginx

rpm包格式的nginx地址:http://nginx.org/packages/
源碼包下載地址:http://nginx.org/en/download.html 。本文下載的是最新穩定版nginx-1.12.1。 mysql

shell> groupadd -r nginx
shell> useradd -r -g nginx nginx
shell> wget http://nginx.org/download/nginx-1.12.1.tar.gz
shell> tar xf nginx-1.12.1.tar.gz
shell> cd nginx-1.12.1
shell> ./configure \
  --user=nginx \
  --group=nginx \
  --prefix=/usr/local/nginx-1.12.1 \
  --error-log-path=/var/log/nginx/error.log \
  --http-log-path=/var/log/nginx/access.log \
  --pid-path=/var/run/nginx/nginx.pid  \
  --lock-path=/var/lock/subsys/nginx \
  --with-http_ssl_module \
  --with-http_flv_module \
  --with-http_stub_status_module \
  --with-http_gzip_static_module \
  --with-pcre \
  --with-threads 

shell> make && make install
shell> ln -s /usr/local/nginx-1.12.0 /usr/local/nginx

./configure過程當中,--with-XX_module的表示啓用某模塊即功能,--without-XX_module表示禁用模塊即功能。在./configure --help的結果中,出現--with-XX_module的表示XX模塊默認是禁用的,須要手動啓用,出現--without-XX_module表示XX模塊默認是啓用的,須要手動禁用。如下是一些常見選項的說明:nginx

--prefix=/usr/local/nginx-1.12.0 # 定義安裝路徑,不寫時默認爲/usr/local/nginx
--sbin-path=                                 # 定義應用程序存放路徑,不寫時默認爲<prefix>/sbin/nginx
--conf-path=                                 # 定義配置文件路徑,不寫時默認爲<prefix>/conf/nginx.conf
--error-log-path=/var/log/nginx/error.log    # 在配置文件中沒有指定error log時的錯誤日誌路徑,不寫時默認爲<prefix>/logs/error.log
--http-log-path=/var/log/nginx/access.log    # 在配置文件中沒有指定access log時的訪問日誌路徑, 不寫時默認爲<prefix>/logs/access.log
--pid-path=/var/run/nginx/nginx.pid          # pid文件路徑,沒指定時默認爲<prefix>/logs/nginx.pid
--lock-path=/var/lock/subsys/nginx           # 鎖文件路徑
--user=nginx                                 # 在配置文件中沒有指定user指定時,worker進程的運行身份,不寫時默認爲nobody
--group=nginx                                # 在配置文件中沒有指定user(不是group,配置文件中沒有group指令)指定時,worker進程的運行組

--with-select_module       # 啓用select方法模型,當找不到epoll時自動啓用select
--without-select_module   
--with-poll_module         # 啓用poll方法模型,當找不到epoll時自動啓用poll
--without-poll_module  

--with-http_ssl_module            # 啓用ssl功能
--with-http_flv_module            # 啓用flv視頻流功能
--with-http_stub_status_module    # 啓用nginx狀態監控功能,在啓動後在瀏覽器使用root/status顯示狀態信息
--with-http_gzip_static_module    # 啓用gzip壓縮功能壓縮web服務器響應客戶端的響應報文
--http-client-body-temp-path=/var/tmp/nginx/client   # 定義客戶端請求報文主體的臨時文件存放路徑,不寫爲<prefix>/client_body_temp
--http-proxy-temp-path=/var/tmp/nginx/proxy          # 定義從代理服務器收到的臨時文件存放路徑,不寫爲<prefix>/proxy_temp
--http-fastcgi-temp-path=/var/tmp/nginx/fcgi         # 定義從fastcgi服務器收到的臨時文件存放路徑,不寫爲<prefix>/fastcgi_temp
--http-uwsgi-temp-path=/var/tmp/nginx/uwsgi          # 定義從uwsgi服務器收到的臨時文件存放路徑,不寫爲<prefix>/uwsgi_temp
--http-scgi-temp-path=/var/tmp/nginx/scgi            # 定義從scgi服務器收到的臨時文件存放路徑,不寫爲<prefix>/scgi_temp
--with-pcre                                          # 設置pcre庫的路徑,yum安裝的pcre-devel能夠不寫路徑
--with-threads                                       # 設置nginx支持多線程

在前面的編譯選項中,安裝路徑使用了版本號,且未指定程序目錄和配置文件路徑,雖然說提供了它們很方便,可是在升級nginx版本有些麻煩。因此,經過最後一步創建軟連接的方式,讓一切都變得簡單,能夠將新舊版本的nginx分離開來。這種方式安裝nginx,配置文件默認爲/conf/nginx.conf,應用程序路徑爲/sbin/nginx。web

提供服務管理腳本/etc/rc.d/init.d/nginx。sql

#!/bin/sh
#
# nginx - this script starts and stops the nginx daemon
#
# chkconfig: - 85 15
# description: Nginx is an HTTP(S) server, HTTP(S) reverse \
# proxy and IMAP/POP3 proxy server

# Source function library.
. /etc/rc.d/init.d/functions

# Source networking configuration.
. /etc/sysconfig/network

# Check that networking is up.
[ "$NETWORKING" = "no" ] && exit 0

nginx="/usr/local/nginx/sbin/nginx"
prog=$(basename $nginx)

sysconfig="/etc/sysconfig/$prog"
lockfile="/var/lock/subsys/nginx"
pidfile="/var/run/nginx/nginx.pid"

NGINX_CONF_FILE="/usr/local/nginx/conf/nginx.conf"

[ -f $sysconfig ] && . $sysconfig


start() {
    [ -x $nginx ] || exit 5
    [ -f $NGINX_CONF_FILE ] || exit 6
    echo -n $"Starting $prog: "
    daemon $nginx -c $NGINX_CONF_FILE
    retval=$?
    echo
    [ $retval -eq 0 ] && touch $lockfile
    return $retval
}

stop() {
    echo -n $"Stopping $prog: "
    killproc -p $pidfile $prog
    retval=$?
    echo
    [ $retval -eq 0 ] && rm -f $lockfile
    return $retval
}

restart() {
    configtest_q || return 6
    stop
    start
}

reload() {
    configtest_q || return 6
    echo -n $"Reloading $prog: "
    killproc -p $pidfile $prog -HUP
    echo
}

configtest() {
    $nginx -t -c $NGINX_CONF_FILE
}

configtest_q() {
    $nginx -t -q -c $NGINX_CONF_FILE
}

rh_status() {
    status $prog
}

rh_status_q() {
    rh_status >/dev/null 2>&1
}

# Upgrade the binary with no downtime.
upgrade() {
    local oldbin_pidfile="${pidfile}.oldbin"

    configtest_q || return 6
    echo -n $"Upgrading $prog: "
    killproc -p $pidfile $prog -USR2
    retval=$?
    sleep 1
    if [[ -f ${oldbin_pidfile} && -f ${pidfile} ]];  then
        killproc -p $oldbin_pidfile $prog -QUIT
        success $"$prog online upgrade"
        echo 
        return 0
    else
        failure $"$prog online upgrade"
        echo
        return 1
    fi
}

# Tell nginx to reopen logs
reopen_logs() {
    configtest_q || return 6
    echo -n $"Reopening $prog logs: "
    killproc -p $pidfile $prog -USR1
    retval=$?
    echo
    return $retval
}

case "$1" in
    start)
        rh_status_q && exit 0
        $1
        ;;
    stop)
        rh_status_q || exit 0
        $1
        ;;
    restart|configtest|reopen_logs)
        $1
        ;;
    force-reload|upgrade) 
        rh_status_q || exit 7
        upgrade
        ;;
    reload)
        rh_status_q || exit 7
        $1
        ;;
    status|status_q)
        rh_$1
        ;;
    condrestart|try-restart)
        rh_status_q || exit 7
        restart
        ;;
    *)
        echo $"Usage: $0 {start|stop|reload|configtest|status|force-reload|upgrade|restart|reopen_logs}"
        exit 2
esac

若是是systemd管理,則提供/usr/lib/systemd/system/nginx.service。shell

[Unit]
Description=The nginx HTTP and reverse proxy server
After=network.target remote-fs.target nss-lookup.target

[Service]
Type=forking
PIDFile=/var/run/nginx/nginx.pid
# Nginx will fail to start if /run/nginx.pid already exists but has the wrong
# SELinux context. This might happen when running `nginx -t` from the cmdline.
# https://bugzilla.redhat.com/show_bug.cgi?id=1268621
ExecStartPre=/usr/bin/rm -f /var/run/nginx/nginx.pid
ExecStartPre=/usr/local/nginx/sbin/nginx -t -c /usr/local/nginx/conf/nginx.conf
ExecStart=/usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf
ExecReload=/bin/kill -s HUP $MAINPID
KillSignal=SIGQUIT
TimeoutStopSec=5
KillMode=process
PrivateTmp=true

[Install]
WantedBy=multi-user.target

最後,將nginx命令加入環境變量。vim

shell> echo 'export PATH=/usr/local/nginx/sbin:$PATH' > /etc/profile.d/nginx.sh
shell> . /etc/profile.d/nginx.sh

2. 編譯PHP

此處只給編譯步驟,具體編譯細節和編譯選項說明見:編譯phpapi

yum install -y bzip2-level libmcrypt-devel openssl-devel libxml2-devel

tar xf php-5.5.38.tar.bz2 -C /tmp
cd /tmp/php-5.5.38
./configure --prefix=/usr/local/php --with-openssl --enable-mbstring --enable-sockets --with-freetype-dir --with-jpeg-dir --with-png-dir --with-libxml-dir=/usr --enable-xml --with-zlib --with-mcrypt --with-bz2 --with-mhash --with-config-file-path=/etc --with-config-file-scan-dir=/etc/php.d --with-mysql=mysqlnd --with-mysqli=mysqlnd --with-pdo-mysql=mysqlnd --enable-fpm

make
make install

# 提供php配置文件
cp php.ini-production /etc/php.ini

# 提供php-fpm服務管理腳本
cp sapi/fpm/init.d.php-fpm /etc/init.d/php-fpmd
chmod +x /etc/init.d/php-fpmd

# 提供php-fpm配置文件
cd /usr/local/php/
cp etc/php-fpm.conf.default etc/php-fpm.conf

# 修改php-fpm配置文件(作實驗的話改不改隨意)
vim etc/php-fpm.conf
pm.max_children = 50
pm.start_servers = 5
pm.min_spare_servers = 2
pm.max_spare_servers = 8

# 啓動php-fpm
service php-fpmd start

3. 配置nginx和php-fpm交互(tcp socket)

在nginx配置文件中加入相似以下location容器。瀏覽器

location ~ \.php$ {
    root           /php/;
    fastcgi_pass   192.168.100.16:9000;
    fastcgi_index  index.php;
    fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
    include        fastcgi_params;
}

該location表示當請求的url能匹配以.php結尾時,將以該容器的指令進行處理。root指令將此容器的document_root設置爲/php/,fastcgi_pass指令表示將該url請求代理至192.168.100.16主機上運行的php-fpm,因爲此處設置了SCRIPT_FILENAME,因此當請求的uri爲/a/a.php時,$document_root=/php/,$fastcgi_script_name=/a/a.php,這表示轉發請求至192.168.100.16主機上的/php/a/a.php。因此,在php-fpm所在主機192.168.100.16上必須將a.php放在事先已建立好的/php/目錄下,這和nginx主機上是否有/php/目錄無關。

這裏的include包含的文件都是一些fastcgi_param指令,fastcgi_param指令是nginx將相關參數賦值給php-fpm所需變量,並將它們傳遞給php-fpm,使得php-fpm知道處理哪一個文件、如何處理、處理的環境是如何的。

此處額外定義了一個php-fpm所需的變量SCRIPT_FILENAME,由於該變量沒有包含在fastcgi_params文件中。若是是rpm包安裝的nginx,則在fastcgi.conf文件中已包含該變量,此時簡寫爲以下配置便可:

location ~ \.php$ {
    root           /php/;
    fastcgi_pass   192.168.100.16:9000;
    fastcgi_index  index.php;
    include        fastcgi.conf;
}

還需注意,fastcgi_index在此處是多餘的。該指令表示的是當代理請求至php-fpm上時,若是uri以"/"結尾(嚴格地說,是$fastcgi_script_name的值以斜線結尾),則自動添加上此處指定的index.php。但注意,此處的location的匹配條件是以.php結尾,是不可能匹配以斜線結尾的,所以此處的fastcgi_index指令是多餘的。但若是修改成以下配置:

location ~ .*php {
    root           /php/;
    fastcgi_pass   192.168.100.16:9000;
    fastcgi_index  index.php;
    include        fastcgi.conf;
}

則fastcgi_index是能派上用場的,例如請求的uri爲"/a/php/",則將執行192.168.100.16上的/php/a/php/index.php文件。

4. 配置nginx和php-fpm交互(unix socket)

要配置unix socket的通訊方式,只需將php-fpm監聽在unix socket上便可。

修改php-fpm.conf:

;listen = 127.0.0.1:9000
listen = /dev/shm/php-cgi.sock

這裏的路徑是/dev/shm,這是將內存化爲虛擬磁盤用的,效率比磁盤速度高得多。

再在nginx.conf中的fastcgi_pass改成unix://協議便可。

fastcgi_pass unix:/dev/shm/php-cgi.sock;
相關文章
相關標籤/搜索