这是从 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