nginx php-fpm配置优化

1.LNMP运行原理图

在这里插入图片描述

2.CGI 相关概念

CGI 是 Web Server 与 Web Application 之间数据交互的一种协议

CGI全称是“通用网关接口(Common Gateway Interface)”,是外部应用程序(CGI)与Web 服务器之间的接口标准,也是Web服务器与其它程序或其它机器上的程序进行“交谈(交互)”的一种工具,其程序一般运行在网络服务器上。CGI可以用任何一种语言编写,只要这种语言具有标准输入、输出和环境变量。如php、python等

nginx只是内容的分发者。比如nginx接收到的请求是/index.php(php请求),根据nginx配置文件,nginx知道这个不是静态文件,需要找php解释器来处理,那么会通过nginx的nginx_http_fastcgi_module,通过socket的方式连接到php,将请求交给php解释器。Nginx会传相关数据给php解释器。比如url,post数据,http header请求头数据等等。所以CGI就是规定了要传那些数据、以什么样的格式传给后方处理这个请求的协议。

CGI工作流程图:

在这里插入图片描述
CGI缺点:

  1. 每当客户请求CGI程序的时候,Web服务器就请求操作系统生成一个新的CGI解析器进程。处理完一个请求后退出,下一个请求来时再创建新的进程。每次重新创建关闭消耗系统资源
  2. CGI方式服务器上有多少请求就会有多少CGI子进程,每个子进程都需要启动CGI解析器,加载配置等初始化操作。这也是CGI性能低下主要原因,当用请求多了,会大量抢占系统资源,如CPU,内存等

3 Fast CGI相关概念

FastCGI 全称 “快速通用网关接口” (FastCommonGatewayInterface),同CGI,是一种通信协议,但比CGI在效率上做了一些优化。

FastCGI像是一个常驻(long-live)型的CGI,它可以一直执行着,只要激活后,不会每次都要花时间去fork一个进程(这是CGI最为人诟病的fork-and-execute 模式)。

FastCGI与语言无关的、可伸缩架构的CGI开放扩展,其主要行为是将CGI解析器进程保持在内存中并以此获得较高的性能。

FastCGI工作流程图:
在这里插入图片描述

  1. Web服务器启动时载入FastCGI进程管理器(IIS ISAPI、Apache Module、Nginx Fastcgi)
  2. FastCGI进程管理器自身初始化,启动多个CGI解析器进程(如果会用php-fpm管理器可见多个php-fpm进程【work进程】)并等待来自Web服务器的连接
  3. 当客户端请求到达Web服务器时,Web FastCGI 进程管理器选择并通过socket连接到一个CGI解析器,Web服务器将CGI环境变量和标准输入(通过socket连接,然后发送数据信息)发送到FastCGI子进程php-fpm进程中
  4. FastCGI 子进程处理完成处理后,将标准输出和错误信息从同一个socket连接返回到Web服务器。当FastCGI子进程关闭连接时,请求便告处理完成。FastCGI子进程接着等待并处理来自FastCGI进程管理器(运行在Web服务器中)的下一个连接。而在CGI模式中,php-cgi进程在此便退出了

4 php-CGI

php (Web Application)自带的CGI管理器

php-cgi的不足
php-cgi变更php.ini配置后需要重启php-cgi才能让新的php.ini生效,不可以平滑重启。直接杀死php-cgi进程,php就不能运行了,但是php-fpm就没有这个问题,守护进程会平滑从新生成新的子进程。

php-fpm
php-fpm (FastCGI Process Manage) 对Web Server 提供的FastCGI 协议的接口程序,额外提供了相对只能的任何管理。

php-fpm说明:

  1. php-fpm就是针对php的,Fastcgi的一种实现,它负责管理一个进程池,来处理来自Web服务器的请求。
  2. php-fpm 是一个PHP FastCGI的管理器,它能够调度php-cgi进程的程序
  3. 修改php.ini之后,php-cgi进程没有办法平滑重启,但php-fpm对此的应对方法是的进程使用新的配置,已经存在的程序让按照之前的配置执行到结束。用这种方式进行平滑过渡

php-fpm的实现:

  1. php-fpm的实现就是创建一个master进程,在master进程中创建worker pool(fork出多个子进程worker)并让其监听socket,这些worker子进程各自accept请求,子进程的处理非常简单,它在启动后阻塞在eccept上,有请求到达后开始读取请求数据,读取完成后开始处理然后再返回,在这期间是不会接收其它请求的,也就是说php-fpm的子进程同时只能响应一个请求,只有把这个请求处理完后才会accept下一个请求
  2. php-fpm的的master进程与worker进程之间不会直接通信,master通过共享内存获取worker进程信息,比如worker进程当前状态,已处理请求数等。当master进程要杀掉一个worker进程时则通过发送信号的方式通知worker进程
  3. php-fpm可以同时监听多个端口,每个端口对应一个worker pool,而每个pool对应多个worker进程

php-fpm的三种工作模式说明:

[www] 
user = nobody #进程的发起用户和用户组,用户user是必须设置,group不是 nobody 任意用户
group = nobody

listen = [::]:9000 #监听ip和端口,[::] 代表任意ip 

chdir = /app #在程序启动时将会改变到指定的位置(这个是相对路径,相对当前路径或chroot后的“/”目录) 

pm = dynamic 
#选择进程池管理器如何控制子进程的数量,
#static:对于子进程的开启数路给定一个锁定的值(pm.max_children), #dynamic:子进程的数目为动态的,它的数目基于下面的指令的值(以下为dynamic适用参数) 

pm.max_children = 16 #同一时刻能够存活的最大子进程的数量 
pm.start_servers = 4 #在启动时启动的子进程数量 
pm.min_spare_servers = 2 #处于空闲"idle"状态的最小子进程,如果空闲进程数量小于这个值,那么相应的子进程会被创建 pm.max_spare_servers = 16 #最大空闲子进程数量,空闲子进程数量超过这个值,那么相应的子进程会被杀掉。 
catch_workers_output =Yes #将worker的标准输出和错误输出重定向到主要的错误日志记录中,如果没有设置,根据FastCGI的指定,将会被重定向 到/dev/null上 
;slowlog = log/$pool.log.slow #默认关闭,慢日志路径,默认在php的安装目录下的var/log目录中 
;request_slowlog_timeout = 0 #脚本超过多长时间 就记录到日志文件

php-fpm三种工作模式:

模式
ondemand内存优先
static静态池
dynamic服务优先

php-fpm进程管理一共有三种模式:ondemand, static,dynamic,我们可以在同一个fpm的master配置三种模式。php-fpm的工作模式和nginx类似,都是一个master,多个worker。每个worker都在accept本机pool内的监听套接字。

1.ondemand (内存优先):

;  ondemand - no children are created at startup. Children will be forked when
;             new requests will connect. The following parameter are used:
;             pm.max_children           - the maximum number of children that
;                                        			 can be alive at the same time.
;             pm.process_idle_timeout   - The number of seconds after which
;                                         				   an idle process will be killed.

在php-fpm启动的时候,不会给这个pool启动任何一个worker,按需启动,当有连接过来才启动。

php-fpm配置如下(php-fpm.conf):
[test]
listen = 127.0.0.1:9000
pm = ondemand
pm.max_children = 10
pm.process_idle_timeout = 10s;

新建worker的触发条件是连接的到来,而不是实际的请求(例如:只进行连接,比如telnet,不发请求数据也会创建worker)worker的数量受限于pm.max_children配置
。同时受限于全局配置process.max (准确来说,三种模式都受限于全局配置),如果空闲时间超过pm.process_idle_timeout大小,会执行关闭对应的worker。整个机制还能会关闭所有的worker。

优缺点:

  • 优点:按流量需求创建,不浪费系统资源(在硬件如此便宜时代,这个优点显得很鸡肋)
  • 缺点:由于php-fpm是短链接,所以每次请求都会先建立连接,建立连接的过程必然会频繁的fork进程然后销毁,所以在大流量的系统master进程会频繁的占用系统的CPU资源,不适合大流量环境的部署

2.dynamic (服务优先):

;   dynamic - the number of child processes are set dynamically based on the
;             following directives. With this process management, there will be
;             always at least 1 children.
;             pm.max_children      - the maximum number of children that can
;                                   			 be alive at the same time.
;             pm.start_servers     - the number of children created on startup.
;             pm.min_spare_servers - the minimum number of children in 'idle'
;                                   				 state (waiting to process). If the number
;                                   				 of 'idle' processes is less than this
;                                    				number then some children will be created.
;             pm.max_spare_servers - the maximum number of children in 'idle'
;                                   				 state (waiting to process). If the number
;                                   				 of 'idle' processes is greater than this
;                                    				 number then some children will be killed.

在php-fpm启动时,会初始启动一些worker进程,在运行过程中动态的调整worker数量,worker数量受限于pm.max_children配置,同时受限全局配置process.max

php-fpm配置如下(php-fpm.conf):
[test]
listen = 127.0.0.1:9000
pm.max_children=10

; The number of child processes created on startup.
; Note: Used only when pm is set to 'dynamic'
; Default Value: min_spare_servers + (max_spare_servers - min_spare_servers) / 2
pm.start_servers=2
pm.min_spare_servers=1
pm.max_spare_servers=3

检查空闲worker数量,按照一定策略动态调整worker数量,增加或减少

  • 增加时,worker最大数量 >= max_children <= 全局process.max
  • 减少时,只有process(ilde状态[空闲状态]) > pm.max_spare_serves 时才会关闭一个空闲worker
  • process(idle状态) > pm.max_spare_servers ,关闭启动时间最长的一个worker,结束本次处理
  • process(idle状态) >= pm.max_children ,打印WARNING 日志,结束本次处理
  • process(idle状态) < pm.max_children,计算一个num值,然后启动num个worker,结束本次处理

优缺点:

  • 优点:动态扩容,不浪费系统资源
  • 缺点:如果所有worker都在工作,新的请求到来只能等待master在新建一个worker,这时可能最长等待1s

3.static (静态池):

;   static  - a fixed number (pm.max_children) of child processes;

php-fpm启动采用固定大小数量的worker,在运行期间也不会扩容,虽然也有1秒定时器,仅限于统计一些状态信息,例如空闲worker个数,活动worker个数,网络连接队列长度等信息

php-fpm配置如下(php-fpm.conf):
[test]
listen = 127.0.0.1:9000
pm.max_children=10

pm.max_children>0必须配置,且只有这一个参数生效

优缺点:

  • 优点:不用动态的判断负载情况,提升性能
  • 缺点:如何配置成static,只需要考虑max_children的数量,数量取决于CPU的个数和应用响应时间。一次性启动固定大小进程浪费系统资源

5.优化建议

1.模式选择
static管理模式适合比较大内存的服务器,dynamic则适合小内存的服务器,可以设置一个pm.min_spare_servers和pm.max_spare_servers合理范围,这样进程数会不断变动。ondemand模式则更适合微小内存,列如512MB或256MB,以及可用性要求不高的环境。php-fpm没有固定的配置,要根据实际情况设置

2.进程数不是越多越好
当前不是,pm.max_children进程多了,增加进程挂历的开销以及上下文切换的开销。更核心的是能并发执行的php-fpm进程不会超过CPU个数
如何设置,取决于你的代码若果代码是CPU计算密集型的,pm.max_children不能超过CPU内核数。如果不是,那么将pm.max_children的值大雨CPU的内存数,是非常明智的。

3.建议设置的进程数
适于dynamic方式:在 N + 20% 和 M/m之间

  • N是CPU内核数
  • M是PHP利用的内存数量
  • m 是每个php进程平均使用的内存数量 (一般php的进程使用的内存大小是30mb左右)

适于static方式:M / (m*1.2)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值