Zero's Blog

Nginx+PHP-FPM

Nginx + PHP-FPM(FastCGI Process Manager)

简介

Apache的效率和承载能力受到大多人的诟病,Nginx 藉由 Nob-blocking 与 epool 这些特性,大幅提高了并发数和处理速度,愈发收到人们的喜爱,但由于 Nginx 本身只是单纯的 HTTP Server,如果执行 php,需要配合 CGI 来完成,Nginx 把请求转发给 fastcig 管理进程,处理之后在将结果返回给 Nginx。

什么是 PHP-FPM

相对于 Spawn-FCGI,PHP-FPM 在内存和CPU方面的控制更胜一筹,PHP-FPM 提供了更好的PHP进程管理方式。PHP-FPM 对于 PHP5.3 之前来说就是一个补丁,将 FastCGI 进程管理整合到PHP中,在 PHP 5.4 之后,PHP-FPM 已经集成到 PHP 的软件包中,在编译 PHP 过程中,增加 --enable-fpm 参数即可开启 PHP-FPM

环境介绍

系统环境

本文的安装环境采用:CentOS Linux release 7.1.1503 (Core)

软件获取

  • Nginx

官方网站:http://nginx.org
最新稳定版本:nginx-1.8.1.tar.gz
帮助文档:http://nginx.org/en/docs
编译参数说明:http://nginx.org/en/docs/configure.html

  • PHP

官方网站:http://www.php.net
稳定版:php-5.6.17.tar.gz

  • 软件仓库

yum 仓库包含 CentOS 官方和 EPEL 两个安装源

1
rpm -ivh http://mirrors.yun-idc.com/epel/7/x86_64/e/epel-release-7-5.noarch.rpm

安装 Nginx

安装模块依赖包

Nginx 的 gzip、rewrite、ssl 模块分别需要 zlib、pcre、openssl 的支持,可以通过源码或 yum 工具来安装

  • 安装zlib
1
2
\\ 使用 gzip 压缩
yum install zlib zlib-devel -y
  • 安装 pcre
1
2
\\ 使用 rewrite 功能
yum install pcre pcre-devel
  • 安装 openssl
1
2
\\ 如果需要 ssl 支持,不需要可以不安装
yum install openssl openssl-devel

安装 Nginx

1
2
3
4
wget http://nginx.org/download/nginx-1.8.1.tar.gz
tar zxf nginx-1.8.1.tar.gz
./configure --prefix=/usr/local/nginx --with-http_ssl_module  --with-http_stub_status_module --with-pcre
make && make install

启动 Nginx,测试安装

Nginx 的默认端口是 80,启动之前要确保 80 端口没有被占用,如果想保留 80 端口,只需要在 Nginx 配置文件中,listen 80;中80换成其他端口。

1
2
3
4
5
6
7
8
9
10
//启动 nginx
/usr/local/nginx/sbin/nginx
// 检查80端口是否启动
netstat -ntpl
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name    
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      28608/nginx: master 
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      917/sshd            
tcp6       0      0 :::22                   :::*                    LISTEN      917/sshd

通过浏览器访问 Nginx Server 会出现欢迎页面,说明 nginx 安装正常

安装 PHP 及 PHP-FPM

  • 安装依赖软件包

确保安装之前有安装 gd、png、curl、xml 等 lib 开发库

1
yum install gd-devel libjpeg-devel libpng-devel libxml2-devel bzip2-devel libcurl-devel -y

  • 下载软件包
1
2
3
wget http://cn2.php.net/distributions/php-5.6.17.tar.gz
tar zxf php-5.6.17.tar.gz 
cd php-5.6.17/
  • 编译安装 php5.6

以下参数支持,ftp、图片函数、pdo 等,因为使用了 php 自带的 mysqlnd,所以不需要额外安装 mysql 的 lib 库,如果是 64 位系统,参数后面需要添加 –wtih-libdir=lib64

1
2
./configure --prefix=/usr/local/php --with-config-file-path=/usr/local/php/etc --with-bz2 --with-curl --enable-ftp --enable-sockets --disable-ipv6 --with-gd --with-jpeg-dir=/usr/local --with-png-dir=/usr/local --with-freetype-dir=/usr/local --enable-gd-native-ttf --with-iconv-dir=/usr/local --enable-mbstring --enable-calendar --with-gettext --with-libxml-dir=/usr/local --with-zlib --with-pdo-mysql=mysqlnd --with-mysqli=mysqlnd --with-mysql=mysqlnd --enable-dom --enable-xml --enable-fpm --with-libdir=lib64
make && make install

注: 编译参数可以根据实际需求,增加或者删减

  • 配置 php-fpm
1
2
cp php.ini-production /usr/local/php/etc/php.ini
cp /usr/local/php/etc/php-fpm.conf.default /usr/local/php/etc/php-fpm.conf
  • 启动 PHP-FPM
1
2
3
4
5
6
7
8
9
10
11
12
13
14
systemctl start php-fpm
// init方式
cp /usr/local/src/php-5.6.17/sapi/fpm/init.d.php-fpm /etc/init.d/php-fpm
chmod +x /etc/init.d/php-fpm
/etc/init.d/php-fpm start
//执行没有报错,说明启动成功,还可以通过端口检查服务是否启动,9000 端口是 fpm 的服务端口
netstat -ntpl
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address               Foreign Address             State       PID/Program name   
tcp        0      0 127.0.0.1:9000              0.0.0.0:*                   LISTEN      23723/php-fpm       
tcp        0      0 0.0.0.0:22                  0.0.0.0:*                   LISTEN      1423/sshd           
tcp        0      0 :::22                       :::*                        LISTEN      1423/sshd

配置 Nginx

nginx主配置文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
cat nginx.conf
user  nobody;
worker_processes  8;  
worker_cpu_affinity 00000001 00000010 00000100 00001000 00010000 00100000 01000000 1000000;
worker_rlimit_nofile 65535;
error_log  logs/error.log  notice;
#error_log  logs/error.log  info;
pid        logs/nginx.pid;
events {
    use epoll;
    worker_connections  10240;
}
http {
    include       mime.types;
    default_type  application/octet-stream;
    server_names_hash_bucket_size 128;
    client_header_buffer_size 32k;
    client_body_buffer_size 32k;
    client_max_body_size 8m; 
    large_client_header_buffers 4 32k;
    
    log_format access  '$http_host $remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent"';
    index index.php index.html;
    autoindex off;
    fastcgi_intercept_errors on;
    #access_log  logs/access.log  main;
    sendfile        on;
    tcp_nopush     on;
    tcp_nodelay    off;
    keepalive_timeout  65;
    fastcgi_connect_timeout 300;
    fastcgi_send_timeout 300;
    fastcgi_read_timeout 300;
    fastcgi_buffer_size 64k;
    fastcgi_buffers 4 64k;
    fastcgi_busy_buffers_size 128k;
    fastcgi_temp_file_write_size 128k;
    gzip  on;
    gzip_min_length 1k;
    gzip_http_version 1.0;
    gzip_comp_level 2;
    gzip_buffers  4 16k;
    gzip_proxied any;
    gzip_disable "MSIE [1-6]\.";
    gzip_types  text/plain text/css application/x-javascript application/xml application/xml+rss text/javascript;
    gzip_vary on;
    server_name_in_redirect off;
    include /usr/local/nginx/conf/vhost/*.conf;
}

虚拟主机配置文件

增加测试站点www.zerounix.com

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
server {
    listen 80;
    server_name www.zerounix.com;
    root /data/website/www.zerounix.com;
    charset utf-8;
    index index.php index.html index.htm ;
    access_log  logs/www.zerounix.com_access.log access;
    error_log   logs/www.zerounix.com_error.log;
    location / {
        try_files $uri $uri/ /index.php$is_args$args;
    }
    location ~ .*\.(php|php5)$ {
        fastcgi_pass 127.0.0.1:9000;
        include        fastcgi.conf;
        try_files $uri =404;
    }
}

Nginx 将会连接回环地址 9000 端口执行 php 文件,需要使用 tcp/ip 协议,速度较慢,建议设置为 socket 方式连接。将 fastcgi_pass 127.0.0.1:9000 变更为 fastcgi_pass unix:/dev/shm/php-fpm.socket; 同时变更 php-fpm 配置文件,在 listen = 127.0.0.1:9000 添加 listen = /dev/shm/php5-fpm.socket;分别重启 nginxphp-fpm 服务

启动 Nginx

1
/usr/local/nginx/sbin/nginx

创建 PHP 测试文件

/data/website/www.zerounix.com/phpinfo.php 添加

1
2
3
<?php 
var_export($_SERVER)
?>

测试访问

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
curl -x 172.16.11.210:80 www.zerounix.com/phpinfo.php
array (
  'USER' => 'nobody',
  'HOME' => '/',
  'FCGI_ROLE' => 'RESPONDER',
  'SCRIPT_FILENAME' => '/data/website/www.zerounix.com/phpinfo.php',
  'QUERY_STRING' => '',
  'REQUEST_METHOD' => 'GET',
  'CONTENT_TYPE' => '',
  'CONTENT_LENGTH' => '',
  'SCRIPT_NAME' => '/phpinfo.php',
  'REQUEST_URI' => '/phpinfo.php',
  'DOCUMENT_URI' => '/phpinfo.php',
  'DOCUMENT_ROOT' => '/data/website/www.zerounix.com',
  'SERVER_PROTOCOL' => 'HTTP/1.1',
  'GATEWAY_INTERFACE' => 'CGI/1.1',
  'SERVER_SOFTWARE' => 'nginx/1.8.1',
  'REMOTE_ADDR' => '172.16.11.210',
  'REMOTE_PORT' => '55060',
  'SERVER_ADDR' => '172.16.11.210',
  'SERVER_PORT' => '80',
  'SERVER_NAME' => 'www.zerounix.com',
  'REDIRECT_STATUS' => '200',
  'HTTP_USER_AGENT' => 'curl/7.29.0',
  'HTTP_HOST' => 'www.zerounix.com',
  'HTTP_ACCEPT' => '*/*',
  'HTTP_PROXY_CONNECTION' => 'Keep-Alive',
  'PHP_SELF' => '/phpinfo.php',
  'REQUEST_TIME_FLOAT' => 1454568561.60866,
  'REQUEST_TIME' => 1454568561,
  )

说明 php 解析正常

总结

Nginx 安装配置相对容易,但是要调优就是另外一件事了,如果设定的不恰当,在高并发的时候,经常会出现 502 Bad Gateway。之后会研究下调优的为问题。