LNMP运维跟踪技巧总结曾几何时,我开始运维公司的LNMP网站。网站错误的方式。好记性不如烂笔头,总结一下吧!开头我会梳理一下我所理解的关于Web请求从发起到响应的每个阶段服务器和浏览器都做了些什么。所有用户响应异常都发生在这个过程中。了解了每个流程的细节,就可以使用不同的方法来定位异常发生的阶段,从而更准确、更快速地定位到错误。下面不断更新自己在被这个网站折磨的过程中遇到的各种错误,给自己做个记录。当然,如果我能帮助到别人,我也很荣幸。Web请求期间到底发生了什么?上图是一个简单的web请求流程。嗯,画的确实有点太简单了。我在上图中隐藏了很多细节。让我一一解释。如果有可能没有涉及到的地方,欢迎补充:第一步,用户在浏览器中输入url比如http:www.baidu.com,chr??om等浏览器需要解析成IPaddress知道去哪里访问哪个服务器。浏览器解析DNS的步骤如下:搜索浏览器自身的dns缓存,缓存时间短,缓存数量有限。搜索操作系统的dns缓存,读取host文件的dns映射(一般情况下,本地开发映射就是修改这个文件,达到拦截浏览器对本地服务器的请求的目的,让本地成功映射serveraddress)首先在本地网卡配置中发起域名解析请求的dnsserver,貌似还有一套运营商处理流程没有进行。下面好像有一些流程,由于这一步基本不执行,一般dns运营商的dnsserver会处理。如果解析失败,以上任一步骤成功都会返回一个成功的ip地址。第二步,浏览器使用随机端口共享ip地址的特定端口(默认80)发起著名的TCP3次握手。一个http请求到达nginx服务的过程大致如下:st=>start:TCP请求en=>end:异常op=>operation:Nginx模块cond1=>condition:进入网卡?cond2=>condition:内核的TCP/IP协议栈?cond3=>condition:Firewall?st->cond1cond1(yes)->cond2cond1(no)->encond2(yes)->cond3cond2(no)->encond3(no)->encond3(yes)->opStep3After握手完成,浏览器和服务器就可以愉快的发送http请求了。nginx上的具体流程如下:st=>start:httprequesten=>end:responseresponseop1=>operation:第二步流程op2=>operation:nginx流程op3=>operation:获取httpop4的头部信息=>操作:匹配server_name,定位站点根目录op5=>操作:进入代码框架的路由op6=>操作:解析出框架php文件的路由解析器op7=>操作:php进入fastcgi进程op8=>operation:fastcgi进程将php填充成一个html文件op9=>operation:将html文件提交给nginx并设置响应信息st->op1->op2->op3->op4->op5->op6->op7->op8->op9->enStep4浏览器根据服务器的响应头和响应体渲染一个可视化页面resopnse响应码描述1xx信息状态描述2xx成功状态码3xx重定向状态码301永久重定向,Location响应头的值仍然是当前的URL,所以是隐藏重定向302临时重定向,显式重定向,Location响应头的值为新的URL304NotModified未修改,比如本地缓存时资源文件与服务器比对,发现没有被修改,服务器返回304状态码,告诉浏览器不需要请求资源,可以直接使用本地资源4xx客户端错误404NotFound请求的URL资源不存在5xx服务器错误500InternalServerError服务器内部错误502BadGatewayfront504GatewayTimeout当代理服务器无法联系后端服务器时出现。这意味着代理可以联系到后端服务器,但后端服务器在指定时间内没有响应代理服务器。以上大致梳理了下LNMP服务器系统下的http请求。只有心中有一个整体流程的概念,才能更好地跟踪实际问题。下面针对以上基本步骤会出现的问题进行定位跟踪。如果第一步和第二步出现问题,可以通过“端口可用性检测”来定位。pingwww.baidu.com检查域名解析器是否异常检查域名解析是否有误,大部分问题出现在这个阶段,这个阶段的问题也是最难定位和解决的。为了更好地处理现阶段的问题,我们需要对下一个Web服务器与一个Web程序之间直接信息通信的模型和过程有更深入的了解。要解释这个问题,首先我们需要了解一下大名鼎鼎的CGI协议、FASTCGI协议和PHP-FPM是什么,以及它们之前的关系。对于一个PHPweb程序,web服务器(如:nginx)需要通过CGI协议与其通信。当网络请求到达网络服务器时,网络服务器将创建一个CGI进程。CGI进程按照固定格式解析web请求,然后写入标准输入(STDIN)和环境变量,然后由PHP启动的CGI解析服务器会从标准输入(STDIN)中读取http请求数据)和环境变量,所以$_SERVER会有数据,然后做相应的逻辑处理,然后将处理结果放入标准输出(STDOUT),CGI进程从STDOUT中读取响应数据,然后传输到浏览器,让服务器完成一个http请求。以上就是CGI的实现过程,但是使用CGI协议的服务器需要在用户每次访问服务器的时候fork/销毁CGI进程,这势必会成为冗余的系统开销,所以FASTCGI就是为了解决这个问题。FastCGI会创建一个常驻master进程和多个worker进程。主进程负责管理和反派工作进程的任务。工作进程负责在里面嵌入一个CGI解析器来解释php代码。PHP-FPM是一个FastCGI进程管理器,它实现了LNMP系统中的FastCGI协议。同样,它也会创建一个常驻master进程和多个worker进程。master进程负责监听端口和接收来自nginx的请求,并将任务分配给worker进程。工作进程负责解释PHP代码。PHP-FPM可以通过配置预先启动一定数量的worker进程,从而在http请求到来时能够更快的做出响应。nginx与PHP-FPM的通信一般是通过其ngx_http_fastcgi_module模块实现的。其中,fastcgi_pass用于设置fastcgi服务器的IP地址;fastcgi_param设置传递给fastcgi服务器的参数。这个模块的配置问题一般都集中在这个区域。相比并发状态出现的问题,一般都集中在fastcgi服务器上。具体表现为fastcgiserver为了应对大量的http请求,必须不断的fork新的worker进程。这时候就要考虑服务器能支持的最大连接数。php-fpm配置中的number和最大打开文件数(可以通过ulimit-n查看)和最小openworker数和最大openworker数。高性能服务器可以朝这个方向调优。这也是我还在摸索的地方,以后一定会写总结的。第四步出现的问题一般这一步出现的问题很少,也很容易定位问题。大部分都是前端渲染的问题,我不是很懂。在完成分界线之前,我总结一下每个阶段可能出现的一些错误,这些错误在客户端是如何出现的,如何定位,如何解决。CSDN传送门
