简单阐述 nginx + php 是如何工作的
这里要提到几个东西, cgi, php-fpm, fastcgi, phpcgi , 网上有很多种解释,大部分都正确,但解释得不算太清晰,有时候多一个字或者少一个字会产生一些误解,经过不断的去求证,大致也了解了一些关于php网站是如何呈现在用户面前的,当然说得有 big 一点的话也就是 php 的运行机制流程是怎样的。
小故事
专业性的名词暂且不讲,先来形象的讲一个故事:
因为房价一直涨,老王被气死了,当老王醒来发现自己竟然穿越到了古猿时代。
肚子饿得很,但是自己是个现代人不会打猎啊,怎么办呢,只能要求古猿帮帮忙了。
但是古猿听不懂他说的话,幸好跟随老王穿越过来的还有许多许多现代物品,其中就包括了非常多的纸和笔了,老王就画了根黄瓜,递给了古猿,古猿看不懂啊,因为这种形状的东西太多了,你到底是要干什么呢,老王马上知道古猿的疑虑了,马上提笔挥墨,画了个自己肚子饿要吃的动作,古猿明白了,从外面采集了些黄瓜回来给了老王,一天就结束了。
第二天老王又饿了,他想吃肉了,并且发现这群猿对自己简直言听计从啊,前提是沟通得了。
于是老王又画了一块肉,画了一个吃的动作,古猿告诉他,肉他弄不到,但是有的猿能弄到,这种猿叫食肉猿。
就把食肉猿叫了过来,老王把纸交给了食肉猿,于是食肉猿开始收拾装备,老王以为他马上就能吃到肉了,但是万万没想到,食肉猿居然跳起了舞,后来了解到食肉猿要打猎必须先跳一段舞拜一下老天,求老天给予指引告诉他哪些地方可以有收获。
经过一番折腾后,老王终于又吃到了肉了,第二天就这样结束了。
第三天老王的饭量变大了,需要不停的吃上几块肉才觉得爽,虽然吃是吃饱了,但是他有一点不爽,那就是每叫一个食肉猿,总会跳一段舞,导致吃完了一块肉,得等会才能吃上另外一块肉。
后来想到了一个好办法,如果让他们只跳一次舞,就能一直去打猎,因为这些舞都跳得一模一样,太浪费时间了。
但是要怎么做到呢?后来找到一个聪明点的猿,幸福生活即将要开始。
来到了第四天,老王一起床叫了一些食肉猿来到自己面前,说你们以后归聪明猿管了,他昨天晚上已经帮你们跳好舞蹈了,以后他让你们打猎你们就去打猎带来肉给我就可以了,众猿纷纷点头。
老王开始验证自己的这套机制,首先跟聪明猿画了画,有肉和吃的动作,果然很快食肉猿带来了一块肉并没有跳舞,然后跟聪明猿要了4块肉,马上又吃完了4块肉。
最后和聪明猿说要100块肉,快过年了得腌点肉过冬了,但是很奇怪的是,前99块肉很快就拿到手上了,但是最后一块肉却迟了一点。
找聪明猿问了问情况,聪明猿比划着跟老王解释,原来他上次只叫了99个食人猿说归聪明猿管,当他要100块肉时,99个食人猿已经全部出动找肉了,当99个食人猿带着肉回来时,聪明猿记着还有一块没送过来,于是又叫了一个食人猿再次出发,所以最后一块肉才晚了一点,如果想要1次收获100块肉的话呢,可以再交给聪明猿一个食人猿就可以解决了。
老王以后的需求可能越来越变态,但是在这古猿时代,总会有一些聪明猿来想方设法的讨这位从未来来的客人欢喜,因为满足了老王,会有越来越多的猿变成聪明猿,会让这个古猿时代变得越来越繁荣。
故事背后的故事
好了,再开始讲讲以上的小故事和今天的标题是什么联系吧,我喜欢把这叫做php是如何工作的,有些叫做php的进程管理,有人叫做php的工作机制,当然后两种说法更专业,但我有些不喜欢。
cgi代表着一种协议
服务器发送什么样的数据给php解析,解析结果以什么样的方式返回给服务器,我觉得这是一种很好的解释办法,更好的解释办法就是干脆说他是一个接口吧,规定接受什么数据返回什么数据。
每一次接受请求都需要解析一遍php.ini和初始化执行环境。代表着老王第一次吃肉。
fastcgi,也是一种协议
它比cgi更快,原因是在服务器启动时,就会启动一个master,然后解析一遍php.ini和初始化环境,然后再启动多个worker等待请求,请求多时,会按照预先的配置再多几个worker,请求少时,关闭一些worker,由worker调动phpcgi。master是聪明猿
phpcgi是php语言的解释器。食肉猿
而phpfpm,实现了fastcgi这个协议。
古猿是谁呢,古猿是用户请求的静态数据。
为什么要画吃的动作呢,因为这是协议,规定了你返回什么数据,画肉为我需求什么数据。
纸代表了Nginx,而不是老王。
所以,用户在浏览器上请求一次,通过http请求到我们的服务器,nginx有个fastcgi模块,nginx通过fastcgi协议将数据传递给phpfpm,由fpm选择一个worker来调用phpcgi解释请求,解释完毕后以fastcgi协议为基础将数据返回给Nginx,nginx通过Http协议返回给用户。
若解释牵强或本人理解有误,望告知。