FastCGI原理

  FastCGI是一个运用于Http Server和动态脚本语言间通信的接口,多数流行的Http Server都支持FastCGI,包括Apache、Nginx和lighttpd等。同时,FastCGI也被许多脚本语言支持,其中就有PHP。 FastCGI接口方式采用C/S结构,可以将HttP服务器和脚本解析服务器分开,同时在脚本解析服务器上启动一个或者多个脚本解析守护进程。当HttP服务器每次遇到动态程序时,可以将其直接交付给FastCGI进程来执行,然后将得到的结果返回给客户端。这种方式可以让HttP服务器专一地处理静态请求或者将动态脚本服务器的结果返回给客户端,这在很大程度上提高了整个应用系统的性能。

  Nginx+php-fpm实现原理

  Nginx本身不会对PHP进行解析,终端对PHP页面的请求将会被Nginx交给FastCGI进程监听的IP地址及端口,由php-fpm作为动态解析服务器处理,最后将处理结果再返回给nginx。其实,Nginx就是一个反向代理服务器。Nginx通过反向代理功能将动态请求转向后端php-fpm,从而实现对PHP的解析支持,这就是Nginx实现PHP动态解析的原理。

  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速度上有提升。

  那nginx是怎么调用php的呢?先看下面的nginx中关于php的配置

location ~ \.php$ {
root /webpath;
fastcgi_pass 127.0.0.1:9000;
...
...
}

  这个location指令把以php为文件后缀的请求,交给127.0.0.1:9000处理。我想你看到这个应该猜到了,这是一个C/S架构东西。 而这里的IP地址和端口(127.0.0.1:9000)就是fastcgi进程监听的IP地址和端口。fastcgi是一个可伸缩地、高速地在http server和动态脚本语言间通信的接口。多数流行的http server都支持fastcgi,包括apache、nginx和lighttpd等。同时,fastcgi也被许多脚本语言支持,其中就有php。

那这个fastcgi的配置IP和端口从何而来呢?在php-fpm.conf中可以看到如下:

listen = 127.0.0.1:9000  #这个表示php的fastcgi进程监听的ip地址以及端口
pm.start_servers = 2

  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子进程关闭连接时,请求便告处理完成,等待下次处理。

nginx和php之间是怎样通信的呢?的更多相关文章

  1. nginx和PHP之间的通信

    如果程序员a和B在windows上开发代码,它们可以被分离到不同的服务器,因为nginx和PHP之间的通信是基于TCP fastcgi协议的我们可以在程序员的windows pc上安装nginx,使用 ...

  2. 父窗口,子窗口之间的JS"通信"方法

    今天需要在iframe内做一个弹窗,但使用弹窗组件的为子窗口,所以弹窗只在子窗口中显示掩膜层和定位,这样不符合需求. 后来晓勇哥指点,了解到一个以前一直没关注到的东西,每个窗口的全局变量,其实都存在对 ...

  3. RPC 编程 使用 RPC 编程是在客户机和服务器实体之间进行可靠通信的最强大、最高效的方法之一。它为在分布式计算环境中运行的几乎所有应用程序提供基础。

    RPC 编程 使用 RPC 编程是在客户机和服务器实体之间进行可靠通信的最强大.最高效的方法之一.它为在分布式计算环境中运行的几乎所有应用程序提供基础.本文介绍 RPC 客户机和服务器之间基本的事件流 ...

  4. 安卓中不同APP之间的消息通信

    昨天在腾讯实习生招聘初试面试时面试官问道我关于两个APP之间相互通信的方式,当时自己回道到了contentProvider与BroadcastReceiver.但他接着问还有没有其它的方式,我跟他说可 ...

  5. Java与C之间的socket通信

    最近正在开发一个基于指纹的音乐检索应用,算法部分已经完成,所以尝试做一个Android App.Android与服务器通信通常采用HTTP通信方式和Socket通信方式.由于对web服务器编程了解较少 ...

  6. Handler主线程子线程之间的互相通信

    Handler主线程子线程之间的互相通信 package com.wyl.dansnote; import android.app.Activity; import android.os.Bundle ...

  7. 用vlan实现同一网段的的各部门之间有的可以通信有的不可以通信

    日前老师上课演示一个项目:实现公司同一网段的各个部门之间有的可以通信有的无法通信.我们用的是思科测试软件模拟操作,个人觉得很好用.       在刚开始做这个项目的时候我以为端口是对应的,如图,交换机 ...

  8. Android设备之间通过Wifi通信

    之前写过PC与Android之间通过WIFI通信(通过Socket,可以在博客里面搜索),PC作为主机,Android作为客户机,现在手头有一台仪器通过wifi传输数据,如果仪器作为主机发射WIFI热 ...

  9. 使用thrift实现了Javaserver和nodejsclient之间的跨平台通信

    1. 简介 thrift是一个软件框架,用来进行可扩展且跨语言的服务的开发.它结合了功能强大的软件堆栈和代码生成引擎.以构建在 C++, Java, Python, PHP, Ruby, Erlang ...

随机推荐

  1. LeetCode-Add and Search Word

    Design a data structure that supports the following two operations: void addWord(word) bool search(w ...

  2. spring-boot集成swagger

    1.引入swagger需要的java类库 <dependency> <groupId>io.springfox</groupId> <artifactId&g ...

  3. chrome不支持字体12px

    如果网页字体小于12px的话,人眼看着会不太舒服,所以chrome的最小字体为12px. 如果想要缩小字体,可以尝试用CSS3中的 transform: scale(相应的缩小倍数)来实现. 不过不推 ...

  4. Python--比较两个字典部分value是否相等

    # 比较两个字典部分是否相等def compare_two_dict(dict1, dict2, key_list): flag = True keys1 = dict1.keys() keys2 = ...

  5. java面试基础题------》Java 中的final关键字有哪些用法

    (1)修饰类:表示该类不能被继承: (2)修饰方法:表示方法不能被重写: (3)修饰变量:表示变量只能一次赋值以后值不能被修改(常量).

  6. Win10图标显示不正常解决办法

    当缓存文件出现问题时,就会引发系统图标显示不正常: 1.由于图标缓存文件是隐藏文件,我们需要在资源管理器中将设置改为“显示所有文件”. 2.同时按下快捷键 Win+R,在打开的运行窗口中输入 %loc ...

  7. Python 线程(threading)

    Python 的thread模块是比较底层的模块,Python的threading模块是对thread做了一些包装,可以更加方便的 被使用; 1. 使用threading 模块 # 示例一: 单线程执 ...

  8. Git Extension工具安装及使用

    以下界面所示的三个工具,如果没安装过,则勾上让其安装.MsysGit为Git的Windows版本,必须要安装:Kdiff为对比/合并工具,可选安装,可以换为使用其它的相关工具:最后一个Windows ...

  9. 教你编译PHP7 (nginx+mysql+php7)

    # 安装编译工具: yum install gcc automake autoconf libtool gcc-c++ # 安装基础库 yum install gd zlib zlib-devel o ...

  10. PAT 1084 Broken Keyboard[比较]

    1084 Broken Keyboard (20 分) On a broken keyboard, some of the keys are worn out. So when you type so ...