随着php脚本语言使用的普及,目前webserice服务大部分都在用nginx+(php-fpm)的结构,了解了其工作过程后才可以在各个方面想办法做调整优化和故障排查,从以下几点总结一下这种模型。

一、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、nginx的工作简介(对应上图看)

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

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

1
2
3
fastcgi_connect_timeout   后端链接时间
fastcgi_send_timeout    数据发送时间,两次成功发送时间差,不是整个发送时间
fastcgi_read_timeout    数据接收时间,两次成功接收时间差,不是整个接收时间

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

1
2
fastcgi_buffer_size 存放fastcgi传过来的响应头,一般设置为分页大小
fastcgi_buffers 存放fastcgi传过来的相应内容,一般设置分页的倍数,格式例如 8  4k|8k

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

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

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进程可以配置执行多少个请求后进行重启,对应的池子的指令和执行多少个请求的指令如下:

1
2
3
pm = static | dynamic | ondemand 静态池、服务优先、内存优先
pm.max_children = 256  开启的最大php进程数
pm.max_requests = 1024   在执行了1024个请求后重启worker进程

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

二、此模型结构常见的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的配置不起作用:

1
2
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,所
以在连接请求较高的业务里要增大这个值。

第三种情况,网络卡时,客户端断开连接,nginx处显示499,然后php检查到前端nginx产生abort后,又master结束此条任务的继而产生502,一般此种情况的报警,先是499,过会儿变成502,再过一会变成504.

减少避免502报错优化建议:

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

php
的工作进程数也不是越大越好,这种进程模型运行时间长了占的内存会增大,一般一个php进程是占到30M左右的内存,开多少合适自己算吧,nginx的
worker进程一般也能跑到30M的内存,综合计算一下;php的执行时间可以根据你的服务标准来设定,超过服务时间浏览器返回的是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错误的。

第三种情况,客户端的网络及其差,php将请求处理完交给nginx后,nginx没能在超时时间内将内容全部吐给用户,这时也会超时,只有504而没有502。

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

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

1
2
3
4
fastcgi_connect_timeout
fastcgi_send_timeout 
fastcgi_read_timeout 
。。。。。。。。

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

WebService之nginx+(php-fpm)结构模型剖析及优化的更多相关文章

  1. nginx+php-fpm结构模型剖析及优化(转载)

    一.nginx和php-fpm的关系和分工 nginx是web服务器,php-fpm是一个PHPFastCGI进程管理器,两者遵循fastcgi的协议进行通信,nginx负责静态类似html文件的处理 ...

  2. 记录一次自己对nginx+fastcgi(fpm)+mysql压力测试结果

    nginx + fastcgi(fpm) 压力测试: CentOS release 5.9 16核12G内存 静态页面: 并发1000,压测200秒,测试结果: 系统最大负载5.47 成功响应: 25 ...

  3. 深入理解PHP之:Nginx 与 FPM 的工作机制

    网络上有很多关于如何配置 Nginx + FPM 的文章,但它们更多从操作的角度出发,告诉我们怎么做,但却没有告诉我们为什么要这么做,本文从 Nginx 与 FPM 的工作机制出发,探讨配置背后的原理 ...

  4. Nginx突破高并发的性能优化 - 运维笔记

    在日常的运维工作中,经常会用到nginx服务,也时常会碰到nginx因高并发导致的性能瓶颈问题.今天这里简单梳理下nginx性能优化的配置(仅仅依据本人的实战经验而述,如有不妥,敬请指出~) 一.这里 ...

  5. [Nginx] - PHP+FPM相关的配置

    CodeIgniter的配置: worker_processes ; events { worker_connections ; } http { include mime.types; defaul ...

  6. zabbix自定义key监控nginx和fpm(网站并发数)

    一. nginx编译参数 监控nginx,主要讲解监控并发数 --prefix=/usr/local/nginx --with-http_stub_status_module zabbix编译参数的查 ...

  7. nginx和fpm的进程数配置和502,504错误

    502 和 php-fpm.conf 1.php-cgi进程数不够用.php执行时间长,导致没有空闲进程处理新请求. 2.php-cgi进程死掉.php-fpm超时时间短,当前进程执行超时关闭连接. ...

  8. Nginx PHP fpm forbidden 原因

    可能是标红目录层级不一致 location / { root /var/www/html/public; index index.php; } location ~ \.php$ { root /va ...

  9. 对FPM 模块进行参数优化!

    Nginx 的 PHP 解析功能实现如果是交由 FPM 处理的,为了提高 PHP 的处理速度,可对FPM 模块进行参数跳转.FPM 优化参数:pm 使用哪种方式启动 fpm 进程,可以说 static ...

随机推荐

  1. HDFS 安全模式的理解

    安全模式是hadoop的一种保护机制,用于保证集群中的数据块的安全性. 当集群启动的时候,会首先进入安全模式.当系统处于安全模式时会检查数据块的完整性.假设我们设置的副本数(即参数dfs.replic ...

  2. [PHP] 算法-邻接矩阵图的广度和深度优先遍历的PHP实现

    1.图的深度优先遍历类似前序遍历,图的广度优先类似树的层序遍历 2.将图进行变形,根据顶点和边的关系进行层次划分,使用队列来进行遍历 3.广度优先遍历的关键点是使用一个队列来把当前结点的所有下一级关联 ...

  3. Java 内部类的简单介绍

    内部类的三种分类(成员内部类,局部内部类,匿名内部类) 1.成员内部类 (类似于成员变量和成员方法) 在类的外部类的方法中去调用内部类  输出结果: 另一种直接在别的类中使用内部类,不过需要先创建外部 ...

  4. jQuery js 中return false,e.preventDefault(),e.stopPropagation()的区别(事件冒泡)

    有时候遇到冒泡事件很烦人,真的..... 1.e.stopPropagation()阻止事件冒泡 <head> <title></title> <script ...

  5. Scoop及使用

    scoop window的命令行安装程序管理工具 通常我们下载软甲需要从网上搜索软件并下载安装等一系列复杂麻烦的过程 现在有了scoop 等一系列包管理器的诞生,就是省去了上述繁琐的搜索 - 下载 - ...

  6. 华为交换机MSTP+VRRP配置实例说明文档

    华为交换机MSTP+VRRP配置实例说明文档 拓扑图 IP地址规划表 设备名称 设备接口 对端设备 对端接口 VLAN VLAN /接口地址 备注 SW0 GE0/0/23 SW2 GE0/0/23 ...

  7. Salesforce 数据库操作简介

    Salesforce 中的数据库操作方式 Salesforce 为用户和开发者提供了四种基本的数据库操作方式: Apex 中的 DML 语句 Apex 中的 Database 类 SOQL 查询 SO ...

  8. Salesforce的报表和仪表板

    报表是现代企业中最常用到的功能之一.Salesforce中提供了强大的报表和仪表板功能. 报表和仪表板简介 报表是一组数据展示,用户可以自定义规则,只有符合相应规则的数据才会显示出来. Salesfo ...

  9. Android Studio_更新Gradle

    一.Gradle更新问题 Android Studio每次更新版本都会更新Gradle这个插件,而且有时候提示更新,却一直更新不了,那是因为中国伟大的长城问题.就是下图,我刚刚更新了,提示更新grad ...

  10. redis介绍 (8) window 下redis的集群(cluster命令)

    前言: 前段时间我在centos上搭建过一次redis集群,那是借助ruby搭建,这次我介绍一种纯redis集群命令的方式去搭建[最后我会简单介绍ruby搭建]. redis集群搭建(三主三备): 准 ...