从输入网址到呈现——详解一次HTTP请求1

自从误打误撞的从C++转到了基于PHP的Web开发方向,由于个人的懒惰和现实情况,仅疲奔拘泥于纯后端接口的开发中。既未曾站在一定的高度纵览整个过程,比如详解一次HTTP请求的具体响应过程,也未曾从后端接口开发中横向地磨练出设计模式的苗头,实乃失败。

今日暂得闲,在进行了一上午的基础资料搜索和整理后,幸运的发现了牛人整理的一篇文章:http://www.tuicool.com/articles/BZRJn2y,生动形象的对渣渣的我进行了基础扫盲行动。故而今日就“巨人的肩膀上”,采用“总——分——总”的形式以个人的理解对HTTP请求的具体过程做一次梳理,一个“有心无力的考究癖者”。

详解一次HTTP请求の服务器端

我们的故事也从服务器端开始讲起吧,基础知识点,比如Host, Server, Linux, Nginx/Apache/IIS等概念性的东西就不赘述了。很久很久以前,机房一台的普通服务器开机了,它启动了操作系统,随着操作系统的就绪,服务器启动了http服务进程,这个http服务的守护进程,可能是apache, 也可能是ngnix,不管怎样,这个http服务进程开始定位到服务器上的www文件夹,一般位于/var/www,然后启动了一些附属模块,例如php,或者,使用fastcgi方式连接到php的fpm管理进程。。。。。。好,暂停存档。

断点1:CGI、Fastcgi与php-fpm

对于我这种小白而言,一定会问:“什么是cgi,什么是fastcgi,php-fpm又是什么鬼?”所幸,对小白我而言,大牛是如此之多,贴篇觉得讲得条理蛮不错的文章:http://www.cnblogs.com/wanghetao/p/3934350.html, 来,我们这就科普一下:

同样在很久很久以前,那时Web服务器简单的响应浏览器发来的HTTP请求,并将存储在服务器上的HTML文件返回给浏览器,也就是静态HTML。但随着动态技术的出现,php,asp等脚本文件应运而生,遗憾的是,服务器并不能直接运行php、asp这样的文件,既然如此,那就只能外包给别人,但是要与外包方做个约定,这个协议就是common gateway interface,简称cgi。这个协议可以用vb,c, php, python等来实现,所以cgi只是个接口协议。CGI就是规定了要传哪些数据、以什么样的格式传递给后方处理这个请求的协议,比如要传送的数据中:url得有吧,查询字符串也要有吧,post的数据也要有,HTTP HEADER不能少吧。

Web服务器根据CGI程序的类型(c,vb,php)决定向CGI程序的传送方式,一般来讲是通过标准输入/输出和环境变量与CGI程序间传送数据。Web服务器和CGI接口又设置了一些环境变量,来向CGI程序传递一些重要的参数,比如以下常用的CGI环境变量:

常用CGI环境变量

Sample CGI

是不是文字多得有点烦,来,我们写个小程序,lighttpd+CGI:lighttpd配置cgi,打开cgi.conf,cgi.assign = (".cgi" => "") 设置 cgi 模块的扩展名和解释器。就本语句而言,表示cgi模块的扩展名是“.cgi”且该 cgi 模块不需要特别的解释器来执行。因为用c来写的是可执行文件。

        生成可执行文件放到服务器配置程序的目录下: gcc test.c -o test.cgi

然后访问:http://localhost/test.cgi?a=b&c=d,结果为:

看到这个cgi程序的执行过程,对于我这种“半路出家”到WEB的应用程序开发的人,不由得要一激灵了,这程序执行的访问方式不是妥妥的普通PHP的url接口吗,我原始的理解:“CGI是个协议,是个flag,WEB服务器根据CGI程序类型向PHP/JAVA等解释器传送数据。。。。。。”,但以上面的情况来看,CGI程序本身就可以妥妥的处理客户端请求了呀,说好的协议呢,说好的只是个定规矩的人呢,是在下武断了。。。。。。

然而,历史的事实真相是:在早期的WEB开发中的确都是使用CGI来处理客户端请求的,那时候还没有能够做到HTML代码和后台逻辑代码的分离,专为WEB开发而设计的语言如PHP的出现(君生我未生~~),所以CGI程序返回的结果通常都会包含一些HTML代码,浏览器接收到整个结果然后进行渲染。后来,。。。我总算学会了如何去爱。。。停,后来有了PHP,JSP这种可以将前后端进行分离的WEB开发语言,PHP代码只负责处理后台逻辑,将大量的HTML代码放在静态HTML文件中,浏览器最后渲染的结果是服务器返回的HTML代码加JS代码加CSS代码以及PHP模板输出的综合结果

那么,我们现在知道了CGI程序只是早期运行在http网络服务器上用来处理客户请求的程序。那么fastcgi又是个什么东东呢?

CGI的工作原理:每当客户请求CGI的时候,web服务器就请求操作系统生成一个新的CGI解释器进程(如php-cgi.exe),CGI的一个进程处理完请求后退出,下一个请求来时再创建进程。但当访问量增大,并发存在,这种方式就不再适用,于是有了FASTCGI。

fastcgi的工作流程是这样的:

1. Web Server启动时载入fastcgi进程管理器(IIS ISAPI或Apache Module);

2. fastcgi进程管理器自身初始化,启动多个cgi解释器进程(比如多个php-cgi),并等待Web Server的连接; 

3. 当客户端请求到达Web Server时,fastcgi进程管理器选择并连接到一个cgi解释器子进程,Web Server将环境变量和标准输入发送到fastcgi的某个子进程,如php-cgi; 

4. fastcgi进程完成处理后将标准输出和错误信息从同一连接返回Web Server。当Fastcgi子进程关闭连接时,请求便告处理完成。Fastcgi子进程继续等待并处理来自fastcgi进程管理器的下一个连接。对比于cgi模式的的处理后便退出,fastcgi更像是一个常驻型CGI,它可以一直执行,只要激活后,不会每次都要花费时间去fork一次(cgi的fork-and-execute模式)。

直观看来,fastcgi管理器类似一个“进程池”的东西,有多个cgi解释器子进程可供它“调兵遣将”,效率上似乎高于“随来随用随走”的cgi模式\(^o^)/~,但毕竟“兵马有限”,当处于高并发情况下,cgi解释子进程个数多少合适呢?

wuli知乎告知:fastcgi中应设置cgi解释子进程的合理个数,应该对服务器进行压力测试(apache ab),监控内存的使用量和CPU使用量的分布情况,通过top查看RES,计算压力峰值,从而找出合理的进程数,即为最佳模式。

为此,我们知道了“fastcgi进程管理器”的存在意义,那么什么是php-fpm呢?

其实,经常伴随出现的还有一种“spawn-fcgi”的概念,spawn-fcgi是一个通用的fastcgi管理服务器,是lighttpd中的一部分。而php-fpm是针对PHP,fastcgi的一种实现,在CPU和内存方面的控制更胜一筹,而前者容易崩溃,必须用crontab(定时任务)进行监控。

php-fpm它负责管理一个进程池,以处理来自Web服务器的请求,自PHP5.3.3已经集成php-fpm了,不再是第三方的包了。

至此,相信大多数小朋友应该差不多知道CGI、Fastcgi与php-fpm之间的关联了,那么理论联系实际,来个思考题吧。以鄙人本地WAMPSERVER开发环境为例,打开http://localhost/?phpinfo=1可以看到Server API为Apache 2.0 Handle,那么我们如何在本地领略下php-fpm的风采呢?

PHP脚本有三种运行方式:1. mod_php(即HTTPServer的内置模块,例如apache的mod_php5,如上图示),就是以模块加载方式运行,本质上就是将php集成到apache服务器,以同一个进程运行,初学者;2. 以CGI方式运行,已几乎很少使用了;3. 以fast-cgi方式运行;下面,我们就以本地WAMPSERVER开发环境为例,分别尝试下这三种运行方式,顺手贴一个小牛已运行成功的链接:http://www.cnblogs.com/52php/p/5668823.html。

鄙人本地虽尝试了“照葫芦画瓢”,奈何太渣。。。。并未成功:wampserver集成以模块加载方式运行自是不必多说;CGI方式,修改配置问题后,不是乱码就是500。。。;fastcgi非默认自带,需要下载fastcgi模块,下载地址http://httpd.apache.org/mod_fcgid/;解压复制其中的mod_fcgid.so和mod_fcgid.pdb,奈何下载的都是源码,需要makefile编译下,window下。。。太渣,捂脸遁走。。。。。。

在./configure的时候带 –enable-fpm参数即可开启PHP-FPM。使用PHP-FPM来控制PHP-CGI的FastCGI进程,php-fpm有两种执行方式, 与Apache一样,他的进程数也是可以根据设置分为动态和静态的,一种是直接开启指定数量的php-fpm进程,不再增加或者减少;另一种则是开始的时候开启一定数量的php-fpm进程,当请求量变大的时候,动态的增加php-fpm进程数到上限,当空闲的时候自动释放空闲的进程数到一个下限。这两种不同的执行方式,可以根据服务器的实际需求来进行调整。

关于php-fpm的参数配置及具体细节加载有时间再详解,可暂参见文章:http://www.cnblogs.com/argb/p/3604340.html。

题外话,那么对于我们的服务器(比如鄙人的本地开发环境:Nginx+php7+php-fpm),选择哪种执行方式比较好呢?。。。没兴趣的下面这段话可自行跳过。。。

事实上,跟Apache一样,我们运行的PHP程序在执行完成后,或多或少会有内存泄露的问题(话说,可以去了解下PHP这种弱类型语言的内存回收机制)。所以据说一个php-fpm进程初始运行只占用3M左右内存,运行一段时间后就会上升到20-30M,php-fpm以动态方式运行会结束掉多余的进程,可回收释放一些内存,所以推荐在内存较少的服务器或者VPS上使用:pm.max_children=【/20M】,pm.min_spare_servers,则建议根据服 务器的负载情况来设置,比较合适的值在5~10之间; 而对于比较大内存的服务器来说,由于频繁开关php-fpm进程也会有时滞,所以运行方式选择静态效果会更好,pm.max_children=【sizeof(memory)/30M】 数量也可以根据 内存/30M 得到。但这些均为大神们的经验之谈,渣我也是道听途说,可以尝试服务器压力测试及php-fpm的参数设置

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,117评论 4 360
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 66,963评论 1 290
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 107,897评论 0 240
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,805评论 0 203
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,208评论 3 286
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,535评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,797评论 2 311
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,493评论 0 197
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,215评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,477评论 2 244
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,988评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,325评论 2 252
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,971评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,055评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,807评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,544评论 2 271
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,455评论 2 266

推荐阅读更多精彩内容