启动流程
// 启动服务
php think swoole start
think - 入口
- 引入自动加载
- 应用初始化
- 实例化
App
,并获取Console
组件- 实例化
Console
,调用$this->app->initialize();
初始化注册了指令,注册了think\swoole\service
- 获取默认输入定义
- 加载指令
- 执行启动器(回调预处理)
- 实例化
- 调用
Console->run
- 获取命令
php think swoole start
- 进入命令处理
think\swoole\command\Server
- 进入命令处理
- 获取命令
- 实例化
注册服务
App->initialize()
-
RegisterService->init()
注册系统服务vendor/services.php
-
think\swoole\Service->register()
创建Swoole
服务器并绑定
在
App->initialize
初始化时注册了Error::class
、RegisterService::class
、BootService::class
,主要是在注册系统服务RegisterService::class
时加载了外部服务
/**
* 应用初始化器
* @var array
*/
protected $initializers = [
Error::class,
RegisterService::class,
BootService::class,
];
/**
* 初始化应用
* @access public
* @return $this
*/
public function initialize()
{
...
// 循环执行应用初始化器的 init 方法
foreach ($this->initializers as $initializer) {
$this->make($initializer)->init($this);
}
...
}
在注册系统服务时
think\initializer\RegisterService
加载了vendor/services.php
服务列表
vendor/services.php
该文件是由composer
钩子生成的
'think\\migration\\Service',
1 => 'think\\swoole\\Service',
2 => 'think\\trace\\Service',
);
// think\swoole\Service
public function register()
{
$this->isWebsocket = $this->app->config->get('swoole.websocket.enable', false);
$this->app->bind(Server::class, function () {
if (is_null(static::$server)) {
$this->createSwooleServer();
}
return static::$server;
});
$this->app->bind("swoole.server", Server::class);
$this->app->bind(PidManager::class, function () {
return new PidManager($this->app->config->get("swoole.server.options.pid_file"));
});
}
配置
[
'host' => env('SWOOLE_HOST', '127.0.0.1'), // 监听地址
'port' => env('SWOOLE_PORT', 80), // 监听端口
'mode' => SWOOLE_PROCESS, // 运行模式 默认为SWOOLE_PROCESS
'sock_type' => SWOOLE_SOCK_TCP, // sock type 默认为SWOOLE_SOCK_TCP
'options' => [
'pid_file' => runtime_path() . 'swoole.pid',
'log_file' => runtime_path() . 'swoole.log',
'daemonize' => false,
// Normally this value should be 1~4 times larger according to your cpu cores.
'reactor_num' => swoole_cpu_num(),
'worker_num' => swoole_cpu_num(),
'task_worker_num' => swoole_cpu_num(),
'task_enable_coroutine' => true,
'task_max_request' => 3000,
'enable_static_handler' => true,
'document_root' => root_path('public'),
'package_max_length' => 20 * 1024 * 1024,
'buffer_output_size' => 10 * 1024 * 1024,
'socket_buffer_size' => 128 * 1024 * 1024,
'max_request' => 3000,
'send_yield' => true,
],
],
'websocket' => [
'enable' => false,
'handler' => Handler::class,
'parser' => Parser::class,
'ping_interval' => 25000,
'ping_timeout' => 60000,
'room' => [
'type' => 'table',
'table' => [
'room_rows' => 4096,
'room_size' => 2048,
'client_rows' => 8192,
'client_size' => 2048,
],
'redis' => [
],
],
'listen' => [],
'subscribe' => [],
],
'rpc' => [
'server' => [
'enable' => false,
'port' => 9000,
'services' => [
],
],
'client' => [
],
],
'hot_update' => [
'enable' => env('APP_DEBUG', false),
'name' => ['*.php'],
'include' => [app_path()],
'exclude' => [],
],
//连接池
'pool' => [
'db' => [
'enable' => true,
'max_active' => 100,
'max_wait_time' => 5,
],
'cache' => [
'enable' => true,
'max_active' => 50,
'max_wait_time' => 5,
],
],
'coroutine' => [
'enable' => true,
'flags' => SWOOLE_HOOK_ALL,
],
'tables' => [],
//每个worker里需要预加载以共用的实例
'concretes' => [],
//重置器
'resetters' => [],
//每次请求前需要清空的实例
'instances' => [],
//每次请求前需要重新执行的服务
'services' => [],
];
Http请求
在InteractsWithHttp->OnRequest
事件中触发
/**
* "onRequest" listener.
*
* @param Request $req
* @param Response $res
*/
public function onRequest($req, $res)
{
$args = func_get_args();
$this->runInSandbox(function (Http $http, Event $event, App $app) use ($args, $req, $res) {
$event->trigger('swoole.request', $args);
$request = $this->prepareRequest($req);
try {
$response = $this->handleRequest($http, $request);
} catch (Throwable $e) {
$response = $this->app
->make(Handle::class)
->render($request, $e);
}
$this->sendResponse($res, $response, $app->cookie);
});
}
/**
* 在沙箱中执行
* @param Closure $callable
* @param null $fd
* @param bool $persistent
*/
protected function runInSandbox(Closure $callable, $fd = null, $persistent = false)
{
/** @var Sandbox $sandbox */
$sandbox = $this->app->make(Sandbox::class);
$sandbox->run($callable, $fd, $persistent);
}
runInSandbox
连接池
在
InteractsWithServer->onWorkerStart()
事件中开启了协程,调用了prepareApplication
,对db
、cache
进行重新绑定,替换为连接池实例
InteractsWithServer->prepareApplication()
,重新绑定了
沙盒
隔离不同协程的上下文