nginx+php-fpm优化项配置
最近基于nginx部署了一些php项目,对里面的工作模式和配置项学习了一下。
什么是php-fpm
fpm全程是FastCGI Process Manager(什么是CGI就不谈了),首先他是一个PHP FastCGI用于处理http请求;其次他是一个管理器,可以管理php进程、配置项等(官方文档)。对于nginx来说,nginx自己处理静态内容,而动态内容需要交给相应的后端CGI程序处理,php-fpm就是连接php和nginx的一个通道。
php-fpm与mod_php的区别
说到这两者的区别就不得不说nginx和apache的区别了。nginx是异构非阻塞模型,每个worker可以同时处理若干请求;而apache是一个阻塞模型,通过fork出子线程来对应处理某一个请求。所以php-fpm以一个独立服务的形式存在,nginx需要时只需要请求fpm即可,运行时的权限等也是由php-fpm的配置来控制的;而mod_php需要被apache加载到子线程中去,权限等也是继承自apache。从这个角度看,php-fpm有更大的灵活性。
(当然Apache也可以跟php-fpm结合起来,这里暂不讨论)
性能上看,仅从这两者很难说性能好坏,因为他们都不能改变php的运行方式。但是由于nginx比apache在设计上更加优秀(或者说是apache历史包袱太重),通常能够承受更大的并发,加上内存占用少、负载均衡等,使得综合性能nginx有一些优势。
nginx配置 (官方链接)
master_process on|off;
是否以master/worker模式工作,默认on(就像上图那样)。如果设置为off,则由master进程亲自处理请求,不启动worker;否则master只起管理worker进程的作用。
worker_processes xxx;
Nginx worker的进程个数,默认为auto(1.9.10之后)。通常被设定为cpu(逻辑)核心数,这样可以发挥多核并行的优势。如果设置为auto,则nginx会自动设置为cpu核数。
worker_cpu_affinity xxx;
worker绑定cpu选项,默认不设置。如果不设置,则不同worker进程可能会分配到不同的cpu核心执行,这样会降低并发的效果。如果设置为auto(1.9.10之后),系统自动绑定到合适的cpu核心。也可以手动使用掩码设置,如四个worker的情况下设置 worker_cpu_affinity 0001 0010 0100 1000;
worker_priority xxx;
worker的优先级,linux在新一轮调度中,执行顺序和时间片分配长短都跟优先级有关。此配置默认值是0,取值范围是-20~20 (越小优先级越高)。
worker_rlimit_nofile number;
设置每个worker最多可以打开的文件数。
events { worker_connections number; }
每个worker可以同时处理的最大连接数,默认1024。这个值的大小不能超过worker_rlimit_nofile的大小;另外如果nginx作为反向代理服务器,通常要耗费两倍的连接(服务器+客户端)。
events { accept_mutex on|off; }
1.11.3前默认值是on,之后默认值是off。此选项是为了负载均衡设计的,若此选项打开,nginx会使worker一个一个地接受请求,而不是一起被唤醒去争抢这个请求(惊群问题)。但是实际上,在负载比较大的情况下,关闭选项能够加快tcp连接的建立速度,而且处于休眠状态的worker也并不多,所以之后这个选项被默认关闭了。在之前陶辉的《深入理解Nginx》中阐述“当某一个worker进程建立的链接数量打到worker_connections的7/8的时候,会大大减小这个worker建立tcp连接的机会”,但是随着nginx版本迭代,这个策略似乎已经变了,之后待我搞清楚会单独写一个东西出来讨论一下。
events { accept_mutex_delay number; }
当accept_mutex开启时,若尝试accept失败,worker会最多等待number秒来重试。默认值500ms(个人感觉有点大)。
events { use method; }
使用什么方法管理连接,默认不同系统使用不同方法(文档),一般linux 2.6以后使用epoll。
events { multi_accept on|off; }
默认off。如果打开,则一个worker会同时accept多个连接。关于这个的讨论比较少,个人觉得是打开这个选项可能会导致负载很不平衡,但是对效率应该是有提高的。
php-fpm配置
php-fpm也是master/worker的工作方式,它有两个配置文件,一个php-fpm.conf,另一个是php-fpm.d/www.conf。安装后创建的默认配置文件中有详细的注释。只有几个www.conf中的配置需要注意一下。
pm = dynamic|static
选择是以何种方式管理,static静态模式,启动的子进程个数是固定的;dynamic动态模式,会在一个区间内动态变化,在这个模式下后面很多参数才会起作用。
pm.max_children = number
必填,最大子进程数(至少为1)。一定要注意php-fpm是阻塞模型,这个参数决定了服务器的服务能力。假设这个值设为1,某个请求请求了一个很耗时的php文件,那么其他的所有请求都会被挂起,直到这个请求被处理完才会被处理。
pm.start_servers = number
启动时启动的进程数。pm=dynamic下才有效,必须小于max_children。
pm.max_requests = number
默认0(不限制),当一个子进程处理了number个request之后会重启。这是因为php(或者第三方插件)可能发生内存泄漏,重启就把内存重置了= =|||| 还是设置一下比较好,但是这个值不要太小,否则可能出现某一时刻多个process都在重启,服务能力下降严重。