加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

WebService之nginx+(php-fpm)结构模型剖析及优化

发布时间:2020-12-16 21:54:19 所属栏目:安全 来源:网络整理
导读:一、nginx?和?php-fpm?的关系和分工 nginx?是?web?服务器,?php-fpm?是一个?PHPFastCGI?进程管理器,两者遵循?fastcgi?的协议进行通信,?nginx?负责静态类似?html?文件的处理,?php-fpm?负责?php?脚本语言的执行,这么设计的目的是为了解耦前端?nginx?和后端

一、nginx?和?php-fpm?的关系和分工

nginx?是?web?服务器,?php-fpm?是一个?PHPFastCGI?进程管理器,两者遵循?fastcgi?的协议进行通信,?nginx?负责静态类似?html?文件的处理,?php-fpm?负责?php?脚本语言的执行,这么设计的目的是为了解耦前端?nginx?和后端的?php?,不至于让容易出问题的?php?脚本堵塞整个?nginx?的业务处理,影响用户体验,因为?php?脚本语言的执行是会比较容易出问题的。?nginx?之所以能处理成千上万高并发业务,除其本身的异步非阻塞模式,在与和其他模块的耦合扩展方法也是分不开的,在?nginx?的设计里不能接受的就是阻塞,不过并非完全没有梗,比如说用到的最多的多进程单线程的模式,由于?nginx?日志没有单独的处理进程,如果收集日志时处理不当就会把?worker?进程堵死。

对应nginx+php-fpm的模型结构图如下:

(图 1)

1、nginx?的工作简介(对应图1看)

在接到?php的脚本?请求后,?nginx?通过?fastcgi_pass?指令将请求传递给后端?php-fpm?的?worker?进程处理,在此过程中,?nginx?做了各种超时机制、缓存机制、?buffer?机制和长连接机制等来保障与后端的?php-fpm?能够良性高效的合作。

在超时机制方面控制?nginx?对后端?php?的等待时间,通过各种?timeout?指令进行控制,例如:

fastcgi_connect_timeout?后端链接时间

fastcgi_send_timeout?数据发送时间,两次成功发送时间差,不是整个发送时间

fastcgi_read_timeout?数据接收时间,两次成功接收时间差,不是整个接收时间

当超时后会返回?504?超时的状态码,在?buffer?机制指令也有很多,例如:

fastcgi_buffer_size?存放?fastcgi?传过来的响应头,一般设置为分页大小

fastcgi_buffers?存放?fastcgi?传过来的相应内容,一般设置分页的倍数,格式例如?8? 4k|8k

另外还有一些其它的缓存、长连接机制不做介绍,当设置不合理时也会出现?5XX?错误,nginx的文章介绍写了有很多的,不再做过多的说明。

2、php-fpm?工作介绍(对应图1看)

Php-fpm?是一个?PHPfastcgi?进程管理器,在启动后会有?master?和?worker?两种进程,?master?负责接收外部信号和管理?worker?进程,?worker?进程是负责干活的,处理?nginx?传过来的任务。

master?进程只有一个,负责监听端口和管理?worker?进程,每次传来任务,与前端的?nginx?建立?3?次握手后放入连接队列,供?worker?进程进行?accept?,当?worker?进程出现错误或执行超时时,负责将?worker?进程重启或者杀掉,是?php-fpm?模型中的大内总管。

Worker?进程是工作进程,每个?worker?进程都独立的执行?php?程序脚本,然后把执行的结果通过?fastcgi?协议交给?nginx?,执行过程中受?master?的管理。在工作中,?worker?进程去竞争?accept?管理进程?master?的链接队列,?accept?函数将从连接请求队列中获得连接信息,创建新的?socket?,并返回该套接字的?fd?,新创建的?socket?用于服务器与?nginx?的通信,而原来的套接字仍然处于监听状态。

php-fpm?可以配置多个?pool?,所有?pool?由?master?统一管理监听不同端口并分配不同?worker?进程池,?worker?进程池支持动态?prefork?同时也支持静态开启,服务器内存较大时建议直接计算后配置静态资源池,可以减少频繁?prefork?进程所带来的开销,提高服务质量,由于进程模型越跑程序耗费越大,因为每个?worker?进程可以配置执行多少个请求后进行重启,对应的池子的指令和执行多少个请求的指令如下:

pm = static | dynamic | ondemand?静态池、服务优先、内存优先

pm.max_children = 256?开启的最大?php?进程数

pm.max_requests = 1024?在执行了?1024?个请求后重启?worker?进程

这也是我们线上服务器的配置,我们线上用的?web?服务的机器是?12?核?cpu?、?16G?内存,?nginx?开启?12?个?worker?进程,?php?开启?256?个进程,跑起来后每个进程大概占用?30M?内存,也就是(?256+12?)?*30=8G?,另外还跑了一些配管、监控、统计、日志收集等七七八八的软件,整体业务是比较轻松的,这种静态池的配置大大减少了?prefork?进程带来的开销,RT时间100ms以内的占到85%(这个与程序写的如何有关),运行一段时间后的开销截图如下:

二、此模型结构常见的5XX服务器端错误及优化(对应图1看)

1、nginx日志里?产生?502?错误

第一种情况,?php-fpm的worker进程?执行?php?程序脚本时,超过了配置的最长执行时间,?master?进程将?worker?进程杀掉,直接返回?502?。

返回?502?后?nginx?对应的?error?日志是?104: Connection reset by peer

对应的?php?执行时间的配置如下,一些版本中?php-fpm?的配置会覆盖?php.ini?的配置,使?php.ini?的配置不起作用:

php.ini?中默认?30s?:?max_execution_time =

php-fpm?中:?request_terminate_timeout =

第二种情况,?连接请求数(?accpet?之前)超出了端口所能监听的?tcp?连接的最大值(?backlog?的值),进不了?fpm?等待?accept?的链接队列,直接返回?502?,这里可能会产生?tcp?重传;

返回?502?后?nginx?对应的?error?日志是?111: Connection refused

backlog?的值是半连接和全连接的总和,他的存在也有短时间缓冲解耦?nginx?请求与?fpm?处理的作用,半连接指收到了?syn?请求,?3?次握手尚未建立,全连接指的是?3?次握手已经成功,不过尚未被?accpet?的请求,?fpm?里面有调节的参数,如果?fpm?的参数设置为?-1?,则默认走的是系统内核参数?net.core.somaxconn?的设置值,如果不设置可以在?/proc/sys/net/core/somaxconn?里查看,默认值是?128?,所以在连接请求较高的业务里要增大这个值。

  • 减少避免?502?报错优化建议

502主要从php-fpm的配置方考虑,根据服务器情况,?适量增大?php-fpm?的工作进程数,适当增加?php?的执行时间,适当增加?backlog?值?。

php?的工作进程数也不是越大越好,这种进程模型运行时间长了占的内存会增大,一般一个?php?进程是占到?30M?左右的内存,开多少合适自己算吧,?nginx?的?worker?进程一般也能跑到?30M?的内存,综合计算一下;?php?的执行时间可以根据你的服务标准来设定,超过服务时间浏览器返回的是?502?错误,这个按照实际的情况处理吧,反正我是觉得执行的慢有返回结果总比直接返回?502?错误的强;至于?backlog?值,当程序写的比较好时,建议设置其数量为?php?工作进程的?1?到?2?倍。

2、nginx日志里?产生?504?错误

第一种情况,php?的?worker?进程池处理慢,无法尽快处理等待?accept?的链接队列,导致?3?次握手后的链接队列长时间没有被?accept?,?nginx?链接等待超时;

返回?504?后?nginx?对应的?error?日志是?110: Connection timed out

第二种情况,后端php-fpm执行脚本的时间太长,超过了nginx配置的超时机制,这个时候也是会报出504错误的。

  • 减少避免504报错的优化建议

504主要从nginx的配置方考虑,根据业务情况配置好超时的各种机制,包含但不限于下属参数:

fastcgi_connect_timeout

fastcgi_send_timeout

fastcgi_read_timeout

。。。。。。。。

另外:?在配置过程中,比如遇到大并发或者是特殊业务的场景,不合理的fd、buffer等设置也会带来5XX错误,比如说大并发连接的业务要增大系统和单个程序的fd数量,如果是上传业务要增大头buffer等,这些要视情况而做优化,正所谓道法自然,术变万千,要以不变应万变。

关注微信公众号:PHP技术大全

PHPer升级为大神并不难!

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读