zoukankan      html  css  js  c++  java
  • 编译LNMP之nginx+php-fpm

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


    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的连接通信方式。

    1. 编译nginx

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

    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模块默认是启用的,需要手动禁用。以下是一些常见选项的说明:

    --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。

    提供服务管理脚本/etc/rc.d/init.d/nginx。

    #!/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。

    [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命令加入环境变量。

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

    2. 编译PHP

    此处只给编译步骤,具体编译细节和编译选项说明见:编译php

    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;
    
  • 相关阅读:
    WEB存储
    2D变形
    HTML5音频与视频
    HTML5 canvas元素
    HTML5表单
    Can't finish GitHub sharing process Successfully created project 'springcloud-parent' on GitHub,
    Intellij idea上传项目到github
    Git for Windows安装和基本设置
    Eclipse注释快捷键、如何生成API以及可能遇到的问题解决
    mysql忘记密码
  • 原文地址:https://www.cnblogs.com/f-ck-need-u/p/7657493.html
Copyright © 2011-2022 走看看