这是从 fpm 到 swoole http server 非常重要的概念. fpm 是多进程模式, 虽然 $_POST 等变量, 被称之为超全局变量, 但是, 这些变量在不同 fpm 进程间是隔离的. 但是到了 swoole http server 中, 一个 worker 进程, 会异步处理多个请求, 简单理解就是下面的等式:
fpm worker : http request = 1 : 1 swoole worker : http request = 1 : n
所以, 我们就需要一种新的方式, 来进行 request 间的隔离.
在编程语言里, 有一个专业词汇 scope(作用域). 通常会使用 scope/生命周期, 所以我一直强调的生命周期的概念, 真的很重要.
swoole 本身是实现了隔离的:
$http = new swoole_http_server("127.0.0.1", 9501);
$http->on('request', function ($request, $response) {
$response->end("<h1>Hello Swoole. #".rand(1000, 9999)."</h1>");
});
$http->start();
msf 在 Context 上还做了一层封装, 让 Context 看起来 为所欲为:
// 你几乎可以用这种方式, 完成任何需要的逻辑 $this->getContext()->xxxModule->xxxModuleFunction();
细节可以查看 src/Helpers/Context.php 文件
对象池
对象池这个概念, 大家可能比较陌生, 目的是减少对象的频繁创建与销毁, 以此来提升性能, msf 做了很好的封装, 使用很简单:
// getObject() 就可以了 /** @var DemoModel $demoModel */ $demoModel = $this->getObject(DemoModel::class, [1, 2]);
对象池的具体代码在 src/Base/Pool.php 下:
底层使用反射来实现对象的动态创建
public function get($class, ...$args)
{
$poolName = trim($class, '\\');
if (!$poolName) {
return null;
}
$pool = $this->map[$poolName] ?? null;
if ($pool == null) {
$pool = $this->applyNewPool($poolName);
}
if ($pool->count()) {
$obj = $pool->shift();
$obj->__isConstruct = false;
return $obj;
} else {
// 使用反射
$reflector = new \ReflectionClass($poolName);
$obj = $reflector->newInstanceWithoutConstructor();
$obj->__useCount = 0;
$obj->__genTime = time();
$obj->__isConstruct = false;
$obj->__DSLevel = Macro::DS_PUBLIC;
unset($reflector);
return $obj;
}
}
使用 SplStack 来管理对象
private function applyNewPool($poolName)
{
if (array_key_exists($poolName, $this->map)) {
throw new Exception('the name is exists in pool map');
}
$this->map[$poolName] = new \SplStack();
return $this->map[$poolName];
}
// 管理对象
$pool->push($classInstance);
$obj = $pool->shift();
连接池 & 代理
连接池 Pools