本文全是个人理解,不一定对
1.web访问站点的流程 http://test.com
我以 laravel 的 nginx 服务器配置为例子,省略掉不必要的参数
server {
#1.首先会走这一步
location / {
try_files $uri $uri/ /index.php?$query_string; #2. http://test.com/index.php
}
#3
location ~ \.php$ {
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass unix:/var/run/php/php7.3-fpm.sock; #4.#nginx fastcgi进程监听的 sock
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
}
nginx 对php的处理,可参考这篇文章 nginx 开启多版本php
使用 sock 和 ip端口处理php都是一样的,参考文章中有个按照端口处理php的流程
www.example.com
|
Nginx
|
路由到www.example.com/index.php
|
加载nginx的fast-cgi模块
|
fast-cgi监听127.0.0.1:9000地址
|
www.example.com/index.php请求到达127.0.0.1:9000
|
php-fpm 监听127.0.0.1:9000
|
php-fpm 接收到请求,启用worker进程处理请求
|
php-fpm 处理完请求,返回给nginx
|
nginx将结果通过http返回给浏览器
2.PHP-FPM处理php的特点
这种方式运行的 fpm 是 Master/Worker 模式,
启动一个 Master 进程监听来自 Nginx 的请求,再 fork 多个 Worker 进程处理请求。
每个 Worker 进程只能处理一个请求,单一进程的生命周期大体如下:
初始化模块。
初始化请求。此处请求是请求 PHP 执行代码的意思,并非 HTTP 的请求。
执行 PHP 脚本。
结束请求。
关闭模块。
多进程模型是依赖进程数来解决并发问题,一个进程只能处理一个连接,
当启动大量进程,进程调度( fork Worker 进),会消耗CPU
3.swoole处理php的特点
Swoole 采用的也是 Master/Worker 模式,不同的是 Master 进程有多个 Reactor 线程,Master 只是一个事件发生器,负责监听 Socket 句柄的事件变化。Worker 以多进程的方式运行,接收来自 Reactor 线程的请求
master进程接收到请求
分配给 Reactor 线程,
线程将请求分配给 worker 进程
Swoole 加速的原理
由 Reactor(epoll 的 IO 复用方式)负责监听 Socket 句柄的事件变化,解决高并发问题。
通过内存常驻的方式节省 PHP 代码初始化的时间,在使用笨重的框架时,用 swoole 加速效果是非常明显的。
我感觉 swoole 速度快
一是处理请求时候,使用了线程去调度进程,避免了进程调度的开销
二是 swoole 启动后,php 代码是直接常驻内存的。注常驻内存可不是已经编译过的。
之前请求,需要从文件中读取php代码,现在这块代码直接在内存里了
但是使用 swoole 的时候要注意,就不能使用累计增加的代码了,比如:
function add(){
static $i;
$i++;
echo $i;
}
这段代码在 swoole 中运行,每次请求,值都会增肌
但是 php-fpm 处理的话,因为是单线程,所以每次都是1
所以单例模式很适合在 swoole 中使用,不管多少次请求,都只会实例化一次,这就减少了代码运行的数据处理
swoole 性能
1.如果只是空载的文件,没有加载mysql 处理,你会发现 swoole 处理速度有很大的提升
2.但是如果使用 mysql ,我在本地测试,发现性能提升很多,但是线上没有明显的提升。这点我很困惑
3.php框架的mysql 实例化,一般应该都使用了单例模式,所以我觉得不需要连接池了。但是我觉得连接与请求查询相比,连接应该也消耗不了多少时间