共计 1795 个字符,预计需要花费 5 分钟才能阅读完成。
php 工作原理
首先先了解下常听说的 cgi,php-cgi,fastcgi,php-fpm 到底是什么关系,帮助了解 php 的工作原理
cgi 协议
cgi 协议用来确定 webserver(例如 nginx),也就是内容分发服务器传递过来什么数据,什么样格式的数据
php-cgi 进程解释器
php-cgi 是 php 的 cgi 协议进程解释器,每次启动时,需要经历加载 php.ini 文件 -> 初始化执行环境 -> 处理请求 -> 返回内容给 webserver->php-cgi 进程退出的流程
fastcgi 协议
fastcgi 协议是对 cgi 协议效率提升的补充,主要是针对每次请求过来时都需要启动一个 cgi 解释器进程的优化,不再需要 cgi 解释器进程每次收到 webserver 请求后都需要重新加载 php.ini 文件和初始化执行环境
php-fpm 进程管理器
php-fpm 是对 fastcgi 协议的实现,是进程管理器,启动时包括 master 和 worker 进程俩部分,master 进程监听端口,接收来自 webserver 请求,worker 进程一般具有多个,每个 worker 进程都有一个 cgi 进程解释器,用来执行 php 代码
php 启动和工作原理
启动 phpfpm 时,会启动 master 进程,加载 php.ini 文件,初始化执行环境,并启动多个 worker 进程。每次请求来时会将请求传递给 worker 进程进行处理
php 平滑重启原理
每次修改完 php.ini 配置并重启后,会启动新的 worker 进程加载新的配置,而之前已经存在的进程会在工作完成之后销毁,因此实现平滑重启
nginx 工作原理
如果想弄明白 nginx 和 php 配合的原理,还需要先了解 nginx 的配置文件中的 server 部分
server {
listen 80; #监听 80 端口,接收 http 请求
server_name www.example.com; #一般存放网址,表示配置的哪个项目
root /home/wwwroot/zensmall/public/; # 存放代码的根目录地址或代码启动入口
index index.php index.html; #网站默认首页
#当请求网站的 url 进行 location 的前缀匹配且最长匹配字符串是该配置项时,按顺序检查文件是否存在,并返回第一个找到的文件
location / {
#try_files,按顺序检查文件是否存在,返回第一个找到的文件
#$uri 代表不带请求参数的当前地址
#$query_string 代表请求携带的参数
try_files $uri $uri/ /index.php?$query_string; #按顺序检查 $uri 文件,$uri 地址是否存在,如果存在,返回第一个找到的文件;如果都不存在,发起访问 /index.php?$query_string 的内部请求,该请求会重新匹配到下面的 location 请求
}
#当请求网站的 php 文件的时候,反向代理到 php-fpm 去处理
location ~ \.php$ {
include fastcgi_params; #引入 fastcgi 的配置文件
fastcgi_pass 127.0.0.1:9000; #设置 php fastcgi 进程监听的 IP 地址和端口
fastcgi_index index.php; #设置首页文件
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; #设置脚本文件请求的路径
}
}
上面 server 配置的整体含义是:每次 nginx 监听到 80 端口的 url 请求,会对 url 进行 location 匹配。如果匹配到 / 规则时,会进行内部请求重定向,发起 /index.php?$query_string 的内部请求,而对应的 location 配置规则会将请求发送给监听 9000 端口的 php-fpm 的 master 进程
总结
下面总结下最简单的用户请求流程:
用户访问域名 -> 域名进行 DNS 解析 -> 请求到对应 IP 服务器和端口 ->nginx 监听到对应端口的请求 ->nginx 对 url 进行 location 匹配 -> 执行匹配 location 下的规则 ->nginx 转发请求给 php->php-fpm 的 master 进程监听到 nginx 请求 ->master 进程将请求分配给其中一个闲置的 worker 进程 ->worker 进程执行请求 ->worker 进程返回执行结果给 nginx->nginx 返回结果给用户