1、一些常见的状态码为:php
200 – 服务器成功返回网页html
2、分析
(1)502 Bad Gateway缘由分析
将请求提交给网关如php-fpm执行,可是因为某些缘由没有执行完毕致使php-fpm进程终止执行。说到此,这个问题就很明了了,与网关服务如php-fpm的配置有关了。
php-fpm.conf配置文件中有两个参数就须要你考虑到,分别是max_children和request_terminate_timeout。
max_children最大子进程数,在高并发请求下,达到php-fpm最大响应数,后续的请求就会出现502错误的。能够经过netstat命令来查看当前链接数。
设置max_children也须要根据服务器的性能进行设定,通常来讲一台服务器正常状况下每个php-cgi所耗费的内存在20M左右。因此在峰值的时候,全部php-cgi所耗内存为20 max_children数。
request_terminate_timeout设置单个请求的超时终止时间。还应该注意到php.ini中的max_execution_time参数。当请求终止时,也会出现502错误的。
当积累了大量的php请求,你重启php-fpm释放资源,但一两分钟不到,502又再次呈现,这是什么缘由致使的呢? 这时还应该考虑到数据库,查看下数据库进程是否有大量的locked进程,数据库死锁致使超时,前端终止了继续请求,可是SQL语句还在等待释放锁,这时就要重启数据库服务了或kill掉死锁SQL进程了。
I、Nginx错误访问日志:
2013/09/19 01:09:00 [error] 27600#0: 78887 recv() failed (104: Connection reset by peer) while reading response header from upstream
client: 192.168.1.101, server: test.com, request: "POST /index.php HTTP/1.1", upstream: "fastcgi://unix:/dev/shm/php-fcgi.sock:",
host: "test.com", referrer: "http://test.com/index.php"前端
II、PHP-FPM报错日志:
WARNING: child 25708 exited on signal 15 (SIGTERM) after 21008.883410 seconds from startnginx
(2) 504 Gateway Time-out缘由分析
504错误通常是与nginx.conf配置有关了。主要与如下几个参数有关:fastcgi_connect_timeout、fastcgi_send_timeout、fastcgi_read_timeout、fastcgi_buffer_size、fastcgi_buffers、fastcgi_busy_buffers_size、fastcgi_temp_file_write_size、fastcgi_intercept_errors。特别是前三个超时时间。若是fastcgi缓冲区过小会致使fastcgi进程被挂起从而演变为504错误。web
3、nginx与php进程间通讯
(1)FastCGI原理
FastCGI是一个运用于Http Server和动态脚本语言间通讯的接口,多数流行的Http Server都支持FastCGI,包括Apache、Nginx和lighttpd等。同时,FastCGI也被许多脚本语言支持,其中就有PHP。
FastCGI接口方式采用C/S结构,能够将HttP服务器和脚本解析服务器分开,同时在脚本解析服务器上启动一个或者多个脚本解析守护进程。当HttP服务器每次遇到动态程序时,能够将其直接交付给FastCGI进程来执行,而后将获得的结果返回给客户端。这种方式可让HttP服务器专注地处理静态请求或者将动态脚本服务器的结果返回给客户端,这在很大程度上提升了整个应用系统的性能。
(2)Nginx+php-fpm实现原理
Nginx自己不会对PHP进行解析,终端对PHP页面的请求将会被Nginx交给FastCGI进程监听的IP地址及端口,由php-fpm做为动态解析服务器处理,最后将处理结果再返回给nginx。其实,Nginx就是一个反向代理服务器。Nginx经过反向代理功能将动态请求转向后端php-fpm,从而实现对PHP的解析支持,这就是Nginx实现PHP动态解析的原理。sql
Nginx不支持对外部程序的直接调用或者解析,全部的外部程序(包括PHP)必须经过FastCGI接口来调用。FastCGI接口在Linux下是socket(这个socket能够是文件socket,也能够是ip socket)。为了调用CGI程序,还须要一个FastCGI的wrapper(wrapper能够理解为用于启动另外一个程序的程序),这个wrapper绑定在某个固定socket上,如端口或者文件socket。当Nginx将CGI请求发送给这个socket的时候,经过FastCGI接口,wrapper接收到请求,而后派生出一个新的线程,这个线程调用解释器或者外部程序处理脚本并读取返回数据;接着,wrapper再将返回的数据经过FastCGI接口,沿着固定的socket传递给Nginx;最后,Nginx将返回的数据发送给客户端。 Nginx 简单配置
location ~ .php$ {
root /home/admin/web/nginx/html/;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME /home/admin/web/nginx/html/$fastcgi_script_name;
include fastcgi_params;
}数据库
当nginx接收到一个http请求时,经过配置文件找到对应的server。而后匹配server中的全部location,找到最匹配的。而在location中的命令会启动不一样的模块去完成工做,好比rewrite模块、index模块。所以在nginx中模块能够看做真正的劳动工做者。nginx的模块是被编译到nginx中的,属于静态方式。启动nginx时,模块被自动加载。不像apache,把模块单独编译成so文件,在配置文件中指定是否加载。因此,单比模块加载方面,nginx也比apache速度上有提高。
location ~ .php$ {
root /webpath;
fastcgi_pass 127.0.0.1:9000;
…
...
}apache
这个location指令把以php为文件后缀的请求,交给127.0.0.1:9000处理。我想你看到这个应该猜到了,这是一个C/S架构东西。 而这里的IP地址和端口(127.0.0.1:9000)就是fastcgi进程监听的IP地址和端口。fastcgi的配置IP和端口从何而来呢?在php-fpm.conf中能够看到。
listen = 127.0.0.1:9000 #这个表示php的fastcgi进程监听的ip地址以及端口
pm.start_servers = 2vim
php-fpm做为fastcgi的进程管理器,能够有效控制内存和进程,而且平滑重载php配置。php5.3之后,php-fpm被集成到php的core中,默认安装,无须配置。后端
fastcgi进程管理器php-fpm自身初始化,启动主进程php-fpm和启动start_servers个fastcgi子进程。主进程php-fpm主要是管理fastcgi子进程,监听9000端口,fastcgi子进程等待请求。当客户端请求到达nginx时,nginx经过location指令,将全部以php为后缀的文件都交给 127.0.0.1:9000 来处理。php-fpm选择并链接到一个fastcgi子进程,并将环境变量和标准输入发送到fastcgi子进程。fastcgi子进程完成处理后将标准输出和错误信息返回。当fastcgi子进程关闭链接时,请求便告处理完成,等待下次处理。
(3)fastcgi与cgi
I、cgi在2000年或更早的时候用得比较多, 之前web服务器通常只处理静态的请求,若是碰到一个动态请求怎么办呢?web服务器会根据此次请求的内容,而后会fork一个新进程来运行外部c程序(或perl脚本...), 这个进程会把处理完的数据返回给web服务器,最后web服务器把内容发送给用户,刚才fork的进程也随之退出。 若是下次用户还请求改动态脚本,那么web服务器又再次fork一个新进程,周而复始的进行。
后来出现了一种更高级的方式是, web服务器能够内置perl解释器或php解释器。 也就是说这些解释器作成模块的方式,web服务器会在启动的时候就启动这些解释器。 当有新的动态请求进来时,web服务器就是本身解析这些perl或php脚本,免得从新fork一个进程,效率提升了。
II、fastcgi的方式是,web服务器收到一个请求时,他不会从新fork一个进程(由于这个进程在web服务器启动时就开启了,并且不会退出),web服务器直接把内容传递给这个进程(进程间通讯,但fastcgi使用了别的方式,tcp方式通讯),这个进程收到请求后进行处理,把结果返回给web服务器,最后本身接着等待下一个请求的到来,而不是退出。
III、举个例子: 服务端如今有个10万个字单词, 客户每次会发来一个字符串,问以这个字符串为前缀的单词有多少个。 那么能够写一个程序,这个程序会建一棵trie树,而后每次用户请求过来时能够直接到这个trie去查找。 可是若是以cgi的方式的话,此次请求结束后这课trie也就没了,等下次再启动该进程时,又要新建一棵trie树,这样的效率就过低下了。 而用fastcgi的方式的话,这课trie树在进程启动时创建,之后就能够直接在trie树上查询指定的前缀了。
4、用户对动态php网页的访问过程
(1)用户浏览器发起对网页的访问:http://www.66rpg.com/index.php
(2)用户和nginx服务器进行三次握手,进行tcp链接(忽略包括nginx访问控制策略、防火墙等)
(3)第一步:用户将http请求发送给nginx服务器
(4)第二步:nginx会根据用户访问的URL和后缀对请求进行判断,例如用户访问的index.php则会根据配置文件中的location进行匹配。nginx根据用户请求的资源匹配到具体的location后会执行location对应的动做。
fastcgi_params #表示nginx会调用fastcgi这个接口。
fastcgi_intercept_errors on; #表示开启fastcgi的中断和错误信息记录。
fastcgi_pass 127.0.0.1::9000; #表示nginx经过fastcgi_pass将用户请求的资源发给127.0.0.1:9000进行解析,这里的nginx和php在同一台服务器上,因此127.0.0.1:9000表示本地的php脚本解析服务器。
(5)第三步:经过第二步能够看出,用户请求的是动态内容,nginx会将请求交给fastcgi客户端,经过fastcgi_pass将用户的请求发送给php-fpm。若是用户访问的是静态资源,nginx直接将用户请求的静态资源返回给用户
(6)第四步:fastcgi_pass将动态资源交给php-fpm以后,php-fpm会将资源转给php脚本解析服务器的wrapper
(7)第五步:wrapper收到php-fpm转过了的请求后,wrapper会生成一个新的线程调用php动态程序解析服务器。若是用户请求的是须要读取Mysql数据库等,会出发读库操做;若是用户请求的是图片,附件等,php会触发一次查询后端存储服务器的操做。
(8)第六步:php将查询到的结果返回给nginx
(9)第七步:nginx构造一个响应报文将结果返回给用户。
5、配置说明,调优
压测:
合理的并发,且保证qps在必定范围没有明显降低。
I、# vim /usr/local/php/etc/php-fpm.conf
pm.max_children = 800
pm.start_servers = 400
pm.min_spare_servers = 200
pm.max_spare_servers = 500
pm.max_requests = 2048
(1)php-fpm有一个参数 max_requests,该参数指明了,每一个children最多处理多少个请求后便会被关闭,默认的设置是500。由于php是把请求轮询给每一个children,在大流量下,每一个childre到达max_requests所用的时间都差很少,这样就形成全部的children基本上在同一时间被关闭,这样会致使此时nginx发给php的请求没法获得相应,会出现短期的502.解决方法:php-fpm有一个参数 max_requests,该参数指明了,每一个children最多处理多少个请求后便会被关闭,默认的设置是500。
(2)php-fpm 进程池优化方法
php-fpm进程池开启进程有两种方式,一种是static,直接开启指定数量的php-fpm进程,再也不增长或者减小;
另外一种则是dynamic,开始时开启必定数量的php-fpm进程,当请求量变大时,动态的增长php-fpm进程数到上限,当空闲时自动释放空闲的进程数到一个下限。
这两种不一样的执行方式,能够根据服务器的实际需求来进行调整。
要用到的一些参数,分别是pm、pm.max_children、pm.start_servers、pm.min_spare_servers和pm.max_spare_servers。
pm表示使用那种方式,有两个值能够选择,就是static(静态)或者dynamic(动态)。
下面4个参数的意思分别为:
pm.max_children:静态方式下开启的php-fpm进程数量,在动态方式下他限定php-fpm的最大进程数(这里要注意pm.max_spare_servers的值只能小于等于pm.max_children)
pm.start_servers:动态方式下的起始php-fpm进程数量。
pm.min_spare_servers:动态方式空闲状态下的最小php-fpm进程数量。
pm.max_spare_servers:动态方式空闲状态下的最大php-fpm进程数量。
若是dm设置为static,那么其实只有pm.max_children这个参数生效。系统会开启参数设置数量的php-fpm进程。
若是dm设置为dynamic,4个参数都生效。系统会在php-fpm运行开始时启动pm.start_servers个php-fpm进程,而后根据系统的需求动态在pm.min_spare_servers和pm.max_spare_servers之间调整php-fpm进程数。
PS.pm.min_spare_servers、pm.max_spare_servers这2个参数一开始我觉得是指空闲进程,可是后来服务器给我报了一个错误:pm.start_servers(70) must not be less than pm.min_spare_servers(15) and not greater than pm.max_spare_servers(60)要求pm.start_servers的值在pm.min_spare_servers和pm.max_spare_servers之间,通过测试,得出上述结论。