Nginx php-fpm配置优化Tips

Nginx Tip 1: 组织Nginx配置文件

Nginx配置文件位于/etc/nginx目录,一种较好的组织方式是采用Debian/Ubuntu Apache风格设置:

## Main configuration file ##
/etc/nginx/nginx.conf

## Virtualhost configuration files on ##
/etc/nginx/sites-available/
/etc/nginx/sites-enabled/

## Other config files on (if needed) ##
/etc/nginx/conf.d/

虚拟主机文件有2个目录,由于site-available目录可以包含任何内容,例如测试配置,以及复制和创建的配置,旧配置等。而sites-enabled目录则只包含实际激活的配置,并且只需要从sites-available目录建立以恶软链接到sites-enabled目录下就可以。

不过,记住要在nginx.conf配置文件最后包含以下两行

## Load virtual host conf files. ##
include /etc/nginx/sites-enabled/*;

## Load another configs from conf.d/ ##
include /etc/nginx/conf.d/*;

Nginx Tip 2: 设置Nginx work_processesworker_connections

默认的worker_processesworker_connections的设置够用,但是这值可以按照以下公式做一些优化:

max_clients = worker_processes * worker_connections

默认的基础配置职能处理大约1000个连接

worker_processes  1;
worker_connections  1024;

对于繁忙的网站上述配置会导致缓慢响应,因为Nginx被I/O操作锁住了。要避免锁情况发生,可以采用 每个服务器处理器核心对应一个worker_process的设置方式,类似:

worker_processes [number of processor cores];

要检查你的服务器CPU核心数量,可以采用

cat /proc/cpuinfo | grep processor | wc -l

例如,输出 24 则设置Nginx的worker_processes如下

worker_processes 24;

worker_connections默认设置值1024通常可以满足要求(我感觉可能和应用有关,对于不同的web应用这个数值可以上下调整)。

Nginx Tip 3: 隐藏Nginx服务器Tokens/版本号

隐藏服务器tokens/版本号通常对于一些过期版本有好处,只需要在 http/server/location段落设置:

server_tokens off;

Nginx Tip 4: Nginx请求/上传最大Body size(client_max_body_size

如果你希望允许用户通过HTTP上传文件,可能需要增加post的限制大小。这个设置是通过client_max_body_sizehttp/server/location段落设置。默认是1Mb,可以修改为20Mb并且增加相应的缓存大小:

client_max_body_size 20m;
client_body_buffer_size 128k;

如果在看到以下错误就表明client_max_body_size设置过小了:Request Entity Too Large(413)

Nginx Tip 5: Nginx静态文件缓存控制(浏览器缓存控制指令)

浏览器缓存对于节约服务器资源和带宽非常重要。在Nginx中设置以下基本配置(logging关闭并且失效头部设置为360天):

location ~* \.(jpg|jpeg|gif|png|css|js|ico|xml)$ {
    access_log      off;
    log_not_found   off;
    expires         360d;
}

Nginx Tip 6: 传递PHP请求给php-fpm

这里可以设置默认的tcp/ip堆栈或者直接使用Unix socket连接。需要设置PHP-FPM监听在准确的相同ip:port或者unix socket(注意:socket的权限)。默认设置是使用ip:port(也就是127.0.0.1:9000):

# Pass PHP scripts to PHP-FPM
location ~* \.php$ {
    fastcgi_index   index.php;
    fastcgi_pass    127.0.0.1:9000;
    #fastcgi_pass   unix:/var/run/php-fpm/php-fpm.sock;
    include         fastcgi_params;
    fastcgi_param   SCRIPT_FILENAME    $document_root$fastcgi_script_name;
    fastcgi_param   SCRIPT_NAME        $fastcgi_script_name;
}

也可以将PHP-FPM和Nginx运行在不同的服务器上。

Nginx Tip 7: 保护(拒绝)访问Nginx的隐含文件

要注意服务器根目录或者其他公共目录下的隐含文件,也就是以.开头的不希望网站用户访问的文件。例如公共目录下包含的版本控制文件和目录,例如.svn以及一些IDE属性文件和.htaccess文件。使用以下配置拒绝所有隐藏文件等访问并关闭日志

location ~ /\. {
    access_log off;
    log_not_found off; 
    deny all;
}

PHP-FPM Tip 1 - php-fpm配置文件

通常PHP-FPM配置文件位于/etc/php-fpm.conf/etc/php-fpm.d目录下。比较好的方法是将所有pool配置都存放在/etc/php-fpm.d目录下。需要在php-fpm.conf配置中使用

include=/etc/php-fpm.d/*.conf

PHP-FPM Tip 2 - PHP-FPM 全局配置微调

默认emergency_restart_thresholdemergency_restart_intervalprocess_control_timeout 都设置成关闭。不过,建议使用如下配置

emergency_restart_threshold 10
emergency_restart_interval 1m
process_control_timeout 10s

上述配置表示如果10个PHP-FPM子进程以SIGSEGV或者SIGBUS信号方式在1分钟内连续退出,则PHP-FPM就会自动重启。这个设置也子进程在从master进程获得reaction信号的等待时间限制为10秒。

PHP-FPM Tip 3 - PHP-FPM pool配置

PHP-FPM可以针对不同网站使用不同的pool并且非常精确地分配资源,甚至对每个pool使用不同的用户和组身份。以下是针对3个不同站点的PHP-FPM pool的文件结构:

/etc/php-fpm.d/site.conf
/etc/php-fpm.d/blog.conf
/etc/php-fpm.d/forums.conf

以及每个pool的案例配置

  • /etc/php-fpm.d/site.conf

[site]
listen = 127.0.0.1:9000
user = site
group = site
request_slowlog_timeout = 5s
slowlog = /var/log/php-fpm/slowlog-site.log
listen.allowed_clients = 127.0.0.1
pm = dynamic
pm.max_children = 5
pm.start_servers = 3
pm.min_spare_servers = 2
pm.max_spare_servers = 4
pm.max_requests = 200
listen.backlog = -1
pm.status_path = /status
request_terminate_timeout = 120s
rlimit_files = 131072
rlimit_core = unlimited
catch_workers_output = yes
env[HOSTNAME] = $HOSTNAME
env[TMP] = /tmp
env[TMPDIR] = /tmp
env[TEMP] = /tmp
  • /etc/php-fpm.d/blog.conf

[blog]
listen = 127.0.0.1:9001
user = blog
group = blog
request_slowlog_timeout = 5s
slowlog = /var/log/php-fpm/slowlog-blog.log
listen.allowed_clients = 127.0.0.1
pm = dynamic
pm.max_children = 4
pm.start_servers = 2
pm.min_spare_servers = 1
pm.max_spare_servers = 3
pm.max_requests = 200
listen.backlog = -1
pm.status_path = /status
request_terminate_timeout = 120s
rlimit_files = 131072
rlimit_core = unlimited
catch_workers_output = yes
env[HOSTNAME] = $HOSTNAME
env[TMP] = /tmp
env[TMPDIR] = /tmp
env[TEMP] = /tmp
  • /etc/php-fpm.d/forums.conf

[forums]
listen = 127.0.0.1:9002
user = forums
group = forums
request_slowlog_timeout = 5s
slowlog = /var/log/php-fpm/slowlog-forums.log
listen.allowed_clients = 127.0.0.1
pm = dynamic
pm.max_children = 10
pm.start_servers = 3
pm.min_spare_servers = 2
pm.max_spare_servers = 4
pm.max_requests = 400
listen.backlog = -1
pm.status_path = /status
request_terminate_timeout = 120s
rlimit_files = 131072
rlimit_core = unlimited
catch_workers_output = yes
env[HOSTNAME] = $HOSTNAME
env[TMP] = /tmp
env[TMPDIR] = /tmp
env[TEMP] = /tmp

PHP-FPM Tip 4 - PHP-FPM Pool 进程管理器(pm)配置

使用PHP-FPM进程管理等最佳方式是使用动态进程管理,这样PHP-FPM进程就只会在需要的时候启动。这个设置类似Nginx worker_processesworker_connections设置。每个进程都会消耗内存,所以如果网站非常繁忙并且服务器有充足内存则可以设置较大值,如果用于内存缺乏的VPS则针对每秒少量请求,设置较小的值。

建议先测试服务器能够处理多少PHP-FPM进程:首先启动Nginx和PHP-FPM并加载一些PHP页面,特别是一些大型页面。然后检查每个PHP-FPM进程消耗掉内存量,可以使用tophtop。假设服务器准备预留220Mb内存运行PHP-FPM,而每个进程大约消耗24Mb内存(一些使用插件的大型内容管理系统的每个页面请求会轻易消耗20-40Mb),则简单的计算max_children值就是:220/24 = 9.17

此时pm.max_children建议设置为9,案例可以参考下面的配置

pm.max_children = 9
pm.start_servers = 3
pm.min_spare_servers = 2
pm.max_spare_servers = 4
pm.max_requests = 200

默认的每个进程可以处理的最大请求是没有限制的,不过最好设置一个较低的值,例如200以避免一些内存问题。

参考

Last updated